Compiling DCMTK on x86_64

Compilation and installation of DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
jap1968
Posts: 3
Joined: Thu, 2005-07-07, 10:28
Location: Miranda de Ebro (Burgos) - Spain
Contact:

Compiling DCMTK on x86_64

#1 Post by jap1968 »

Hi there,

I am having problems when trying to compile DCMTK on a new machine. I have compiled previously on several other machines with no (or almost no) problems, but this time, there are a lot of new things, and I am unable to solve the problem.

My environment:

OS: Linux Fedora Core 4 - x86_64
gcc version 4.0.0 20050519 (Red Hat 4.0.0-8 )
Linux kernel verion: 2.6.11-1.1369_FC4
Hardware platform: AMD Opteron 250 (HP Proliant DL385)

I download, untar and do the simplest compile (.configure, make, ...) without additional parameters.

When the system starts compiling, I obtain the following error:

Code: Select all

c++     -DHAVE_CONFIG_H  -DNDEBUG  -c -I. -I. -I../include -I../../config/include   \
         -O -I/usr/include/libxml2 -D_REENTRANT -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_BSD_COMPAT -D_OSF_SOURCE -D_POSIX_C_SOURCE=199506L -Wall  ofthread.cc
ofthread.cc: In member function ‘int OFThread::start()’:
ofthread.cc:148: error: invalid cast from type ‘pthread_t’ to type ‘long unsigned int’
ofthread.cc: In member function ‘int OFThread::join()’:
ofthread.cc:167: error: invalid cast from type ‘long unsigned int’ to type ‘pthread_t’
ofthread.cc: In member function ‘bool OFThread::equal(long unsigned int)’:
ofthread.cc:191: error: invalid cast from type ‘long unsigned int’ to type ‘pthread_t’
ofthread.cc:191: error: invalid cast from type ‘long unsigned int’ to type ‘pthread_t’
ofthread.cc: In static member function ‘static long unsigned int OFThread::self()’:
ofthread.cc:217: error: invalid cast from type ‘pthread_t’ to type ‘long unsigned int’
ofthread.cc: In member function ‘bool OFThread::equal(long unsigned int)’:
ofthread.cc:197: warning: control reaches end of non-void function
make[2]: *** [ofthread.o] Error 1
make[2]: Leaving directory `/usr/local/src/dcmtk-3.5.3/ofstd/libsrc'
make[1]: *** [libsrc-all] Error 2
make[1]: Leaving directory `/usr/local/src/dcmtk-3.5.3/ofstd'
make: *** [ofstd-all] Error 2
Has anyone compiled DCMTK on a similar environment?

Thanks in advance,

José Antonio Pérez

jap1968
Posts: 3
Joined: Thu, 2005-07-07, 10:28
Location: Miranda de Ebro (Burgos) - Spain
Contact:

Found a temporal solution

#2 Post by jap1968 »

The origin of the problem seems to be a 64bit size of pointer on x86_64 architecture.

The error is due to a macro related to type casting: OFreinterpret_cast(...)

This macro is defined in 'ofstd/include/ofcast.h'

And in particular those lines (lines 51 to 55)

Code: Select all

#ifdef HAVE_REINTERPRET_CAST
#define OFreinterpret_cast(x,y) (reinterpret_cast< x >(y))
#else
#define OFreinterpret_cast(x,y) ((x)(y))
#endif
The solution I have adopted is replacing line 52 for that of line 54, so:

Code: Select all

- #define OFreinterpret_cast(x,y) (reinterpret_cast< x >(y))
+ #define OFreinterpret_cast(x,y) ((x)(y))
The same effect would be obtained undefining HAVE_REINTERPRET_CAST

The DCMTK toolkit compiles and works (at least just a few things that I have just tried), but it is not an elegant solution.

I am not very familiar with make/automake/config and so on, but the correct solution would be detecting the 64 bit platforms and change the way of doing type castings.

Does anyone know how to make such thing in a proper way?

Regards,

José Antonio Pérez

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#3 Post by Jörg Riesmeier »

The above mentioned error seems to be related to the definition of "pthread_t" on your system. Since we changed this code after the release of DCMTK 3.5.3 it is possible that the current development version already works for you. Excerpt from the CVS log of "ofthread.cc":
Updated code to correctly handle pthread_t both as an integral integer type (e.g. Linux, Solaris) and as a pointer type (e.g. BSD, OSF/1).
We could make the current version available to you if you are interested. Just send an email to dicom/at/offis/dot/de.

If this version also does not work we would need your help to fix this problem (e.g. by determining how "pthread_t" is defined on your system).

jsalk
DCMTK Tester
Posts: 13
Joined: Thu, 2004-11-25, 15:59

#4 Post by jsalk »

Hi Joerg, José, all.

I have the vague feeling that this is an issue with the compiler version.

I've just switched from gcc/g++ 3.3.6 to 4.0.0 on Debian Sid (i386)
and got the very same error when trying to rebuild dcmtk with 4.0.0.
It builds right out of the box on the same system with version 3.3.6.
Replacing reinterpret_cast < > ( ) by a C-style cast works for me as
well but this does not seem to be a very clean solution.

pthread_t is still defined as unsigned long int on Linux.

Best regards - Juergen

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#5 Post by Jörg Riesmeier »

I just checked it with the current development version of DCMTK and gcc 4.0 (Debian i386):

Code: Select all

ofthread.cc: In static member function 'static long unsigned int OFThread::self()':
ofthread.cc:231: error: invalid cast from type 'pthread_t' to type 'long unsigned int'
make[2]: *** [ofthread.o] Error 1

jsalk
DCMTK Tester
Posts: 13
Joined: Thu, 2004-11-25, 15:59

#6 Post by jsalk »

Hi Jörg,

with gcc 4.0 you seem to *have* to use `static_cast' to convert between types
that are actually already both integral like unsigned long and pthread_t on Linux.
`reinterpret_cast' doesn't seem to work any more for this kind of conversion
with gcc 4.0. :-/

Best regards - Jürgen

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#7 Post by Jörg Riesmeier »

Jürgen,

Thank you for the tip. It seems that in the current development version we still need to change at least one type cast from "reinterpret" to "static". Unfortunately, I do not have access to my Debian machine (with gcc 4.0) right now so I'll test it later.
Last edited by Jörg Riesmeier on Fri, 2005-07-08, 10:56, edited 1 time in total.

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1444
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

#8 Post by Marco Eichelberg »

If there is a reinterpret_cast in the code, this means that there has been at least one platform on which a static_cast was not sufficient and lead to compile errors. I assume this affects the platforms on which pthread_t is not an integer but a pointer, such as some of the BSDs and OSF/1. For any change of cast type, test compiles have to be done on all platforms supported by DCMTK. Ugly but necessary.

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#9 Post by Jörg Riesmeier »

This is certainly true but, fortunately, there is already a HAVE_POINTER_TYPE_PTHREAD_T macro/define which could probably be used for this purpose. We'll see ...

jap1968
Posts: 3
Joined: Thu, 2005-07-07, 10:28
Location: Miranda de Ebro (Burgos) - Spain
Contact:

HAVE_POINTER_TYPE_PTHREAD_T

#10 Post by jap1968 »

Hi again,

I have just compiled the cvs version (20050707) with this modification, according to Jörg proposal.

It compiles ok with gcc4. There are something wrong in the makefile and the compilation process gets caught on a infinite loop (but this is a different problem).

ofthread.cc, lines 226 to 239:

Code: Select all

unsigned long OFThread::self()
{
#ifdef WINDOWS_INTERFACE
  return OFstatic_cast(unsigned long, GetCurrentThreadId());
#elif defined(POSIX_INTERFACE) && defined(HAVE_POINTER_TYPE_PTHREAD_T)
  return OFreinterpret_cast(unsigned long, pthread_self());
#elif defined(POSIX_INTERFACE) && !defined(HAVE_POINTER_TYPE_PTHREAD_T)
  return OFstatic_cast(unsigned long, pthread_self());
#elif defined(SOLARIS_INTERFACE)
  return OFstatic_cast(unsigned long, thr_self());
#else
  return 0;
#endif
}
Regards,

José Antonio

hardwick
Posts: 3
Joined: Fri, 2005-07-22, 16:05

#11 Post by hardwick »

I needed GCC 4, but don't want to make the leap from 3.5.3 to the development version. I've made a patch from the current cvs against 3.5.3 that seems to work under 32 bit and 64 bit GCC 4 (tested on FC4).

Code: Select all

--- dcmtk-3.5.3/ofstd/libsrc/ofthread.cc        2004-04-22 04:45:32.000000000 -0600
+++ dcmtk-3.5.3-new/ofstd/libsrc/ofthread.cc    2005-07-27 09:39:16.000000000 -0600
@@ -143,10 +143,16 @@
     return 0;
   }
 #elif defined(POSIX_INTERFACE)
+#ifdef HAVE_POINTER_TYPE_PTHREAD_T
   pthread_t tid=0;
   int result = pthread_create(&tid, NULL, thread_stub, OFstatic_cast(void *, this));
   if (0 == result) theThread = OFreinterpret_cast(unsigned long, tid); else theThread = 0;
   return result;
+#else
+  pthread_t tid=0;
+  int result = pthread_create(&tid, NULL, thread_stub, OFstatic_cast(void *, this));
+  if (0 == result) theThread = OFstatic_cast(unsigned long, tid); else theThread = 0;
+#endif
 #elif defined(SOLARIS_INTERFACE)
   thread_t tid=0;
   int result = thr_create(NULL, 0, thread_stub, OFstatic_cast(void *, this), 0, &tid);
@@ -163,8 +169,13 @@
   if (WaitForSingleObject((HANDLE)theThreadHandle, INFINITE) == WAIT_OBJECT_0) return 0;
   else return (int)GetLastError();
 #elif defined(POSIX_INTERFACE)
+#ifdef HAVE_POINTER_TYPE_PTHREAD_T
   void *retcode=NULL;
   return pthread_join(OFreinterpret_cast(pthread_t, theThread), &retcode);
+#else
+  void *retcode=NULL;
+  return pthread_join(OFstatic_cast(pthread_t, theThread), &retcode);
+#endif
 #elif defined(SOLARIS_INTERFACE)
   void *retcode=NULL;
   // reinterpret_cast does not work for gcc 3.x
@@ -188,7 +199,11 @@
 #ifdef WINDOWS_INTERFACE
   if (theThread == tID) return OFTrue; else return OFFalse;
 #elif defined(POSIX_INTERFACE)
+#ifdef HAVE_POINTER_TYPE_PTHREAD_T
   if (pthread_equal(OFreinterpret_cast(pthread_t, theThread), OFreinterpret_cast(pthread_t, tID))) return OFTrue; else return OFFalse;
+#else
+  if (pthread_equal(OFstatic_cast(pthread_t, theThread), OFstatic_cast(pthread_t, tID))) return OFTrue; else return OFFalse;
+#endif
 #elif defined(SOLARIS_INTERFACE)
   if (OFstatic_cast(thread_t, theThread) == OFstatic_cast(thread_t, tID)) return OFTrue; else return OFFalse;
 #else
@@ -214,12 +229,16 @@
 #ifdef WINDOWS_INTERFACE
   return OFstatic_cast(unsigned long, GetCurrentThreadId());
 #elif defined(POSIX_INTERFACE)
+#ifdef HAVE_POINTER_TYPE_PTHREAD_T
   return OFreinterpret_cast(unsigned long, pthread_self());
+#else
+  return OFstatic_cast(unsigned long, pthread_self());
+#endif
 #elif defined(SOLARIS_INTERFACE)
   return OFstatic_cast(unsigned long, thr_self());
 #else
   return 0;
-#endif
+#endif
 }

 #if defined(WINDOWS_INTERFACE) || defined(POSIX_INTERFACE) || defined(SOLARIS_INTERFACE)

jsalk
DCMTK Tester
Posts: 13
Joined: Thu, 2004-11-25, 15:59

#12 Post by jsalk »

hardwick wrote:I needed GCC 4, but don't want to make the leap from 3.5.3 to the development version. I've made a patch from the current cvs against 3.5.3 that seems to work under 32 bit and 64 bit GCC 4 (tested on FC4).

Code: Select all

--- dcmtk-3.5.3/ofstd/libsrc/ofthread.cc        2004-04-22 04:45:32.000000000 -0600
+++ dcmtk-3.5.3-new/ofstd/libsrc/ofthread.cc    2005-07-27 09:39:16.000000000 -0600
@@ -143,10 +143,16 @@
     return 0;
   }
 #elif defined(POSIX_INTERFACE)
+#ifdef HAVE_POINTER_TYPE_PTHREAD_T
 ...
+#else
 ...
+#endif
...
 
Just a marginal note:

AFAIK, there is no HAVE_POINTER_TYPE_PTHREAD_T macro definition
in 3.5.3 at all (unless you have patched some of the build scripts as
well). So your fix will probably fail on any system with a pointer type
pthread_t definition.

Best regards - Juergen

Post Reply

Who is online

Users browsing this forum: Baidu [Spider] and 1 guest