1

I'am trying to cross-compile the simplest DCMTK example I found and I can get it built. I am running Ubuntu 18.04.4 LTS to cross compile using x86_64-w64-mingw32.

I have checked these answers and examples too, but they didn't work for me:

This is the only file of the project (main.cpp):

#include "dcmtk/config/osconfig.h"
#include "dcmtk/dcmdata/dctk.h"

using namespace std;
int main()
{
    DcmFileFormat fileformat;
    OFCondition status = fileformat.loadFile("sample.dcm");
    if (status.good())
    {
        OFString patientName;
        if (fileformat.getDataset()->findAndGetOFString(DCM_PatientName, patientName).good())
        {
            cout << "Patient's Name: " << patientName << endl;
        } else
            cerr << "Error: cannot access Patient's Name!" << endl;

        OFString patientID;
        if (fileformat.getDataset()->findAndGetOFString(DCM_PatientID, patientID).good())
        {
            cout << "Patient's ID: " << patientID << endl;
        } else
            cerr << "Fatal Error: cannot access Patient's ID!" << endl;

    } else
        cerr << "Error: cannot read DICOM file (" << status.text() << ")" << endl;
    return 0;
}

This is my CMake.txt configuration file:

cmake_minimum_required(VERSION 2.8)
PROJECT(test1DCMTK)

add_executable(${PROJECT_NAME} "main.cpp")

SET(DCMTK_DIR /usr/local/include/dcmtk)

ADD_DEFINITIONS(-D_REENTRANT)

INCLUDE_DIRECTORIES(${DCMTK_DIR}/include)
LINK_DIRECTORIES(${DCMTK_DIR}/lib)

TARGET_LINK_LIBRARIES(test1DCMTK ofstd dcmdata)

And I am using this toolchain file:

### CMAKE cross compile settings for Windows running from Ubuntu 18.04.4 LTS x86_x64 amd64 ###

# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Windows)
SET(TOOLCHAIN_PREFIX x86_64-w64-mingw32)

SET(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc-posix)
SET(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++-posix)
#SET(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)

# which compilers to use for C and C++
#SET(CMAKE_C_COMPILER x86_x64-mingw32-gcc)
#SET(CMAKE_CXX_COMPILER x86_x64-mingw32-g++)
###SET(CMAKE_RC_COMPILER i586-mingw32msvc-windres)

# here is the target environment located
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} /usr/lib/gcc/${TOOLCHAIN_PREFIX}/7.3-posix)

# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

When I configure, with CMake, I get this:

The C compiler identification is GNU 7.3.0
The CXX compiler identification is GNU 7.3.0
Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc-posix
Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc-posix -- works
Detecting C compiler ABI info
Detecting C compiler ABI info - done
Detecting C compile features
Detecting C compile features - done
Check for working CXX compiler: /usr/bin/x86_64-w64-mingw32-g++-posix
Check for working CXX compiler: /usr/bin/x86_64-w64-mingw32-g++-posix -- works
Detecting CXX compiler ABI info
Detecting CXX compiler ABI info - done
Detecting CXX compile features
Detecting CXX compile features - done
Configuring done

But when I try to build the code, this is what I get:

/home/yo/Projects/test1DCMTK/main.cpp:1:10: fatal error: dcmtk/config/osconfig.h: No existe el archivo o el directorio
 #include "dcmtk/config/osconfig.h"
          ^~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
CMakeFiles/test1DCMTK.dir/build.make:63: fallo en las instrucciones para el objetivo 'CMakeFiles/test1DCMTK.dir/main.cpp.obj'
make[2]: *** [CMakeFiles/test1DCMTK.dir/main.cpp.obj] Error 1
CMakeFiles/Makefile2:67: fallo en las instrucciones para el objetivo 'CMakeFiles/test1DCMTK.dir/all'
make[1]: *** [CMakeFiles/test1DCMTK.dir/all] Error 2
Makefile:83: fallo en las instrucciones para el objetivo 'all'
make: *** [all] Error 2

However, the library exists:

(base) yo@MiPC:/usr/local/include/dcmtk/config$ ls /usr/local/include/dcmtk/config/os*
/usr/local/include/dcmtk/config/osconfig.h

So, what am I doing wrong? What should I do to get it working properly?

I tried the answer of @squareskittles, and I got this when tried to build:

(base) yo@MiPC:~/Projects/build-test1DCMTK-win32$ make all
-- Configuring done
-- Generating done
-- Build files have been written to: /home/yo/Projects/build-test1DCMTK-win32
Scanning dependencies of target test1DCMTK
[ 50%] Building CXX object CMakeFiles/test1DCMTK.dir/main.cpp.obj
In file included from /usr/local/include/dcmtk/dcmdata/dcistrma.h:28:0,
                 from /usr/local/include/dcmtk/dcmdata/dctk.h:30,
                 from /home/elekta/Projects/QT/TUTOS-QT/test1DCMTK/main.cpp:2:
/usr/local/include/dcmtk/ofstd/offile.h:74:9: error: ‘fpos64_t’ does not name a type; did you mean ‘fpos_t’?
 typedef fpos64_t offile_fpos_t;
         ^~~~~~~~
         fpos_t
/usr/local/include/dcmtk/ofstd/offile.h:866:15: error: ‘offile_fpos_t’ has not been declared
   int fgetpos(offile_fpos_t *pos)
               ^~~~~~~~~~~~~
/usr/local/include/dcmtk/ofstd/offile.h:886:15: error: ‘offile_fpos_t’ has not been declared
   int fsetpos(offile_fpos_t *pos)
               ^~~~~~~~~~~~~
/usr/local/include/dcmtk/ofstd/offile.h: In member function ‘int OFFile::fseek(offile_off_t, int)’:
/usr/local/include/dcmtk/ofstd/offile.h:757:5: error: ‘offile_fpos_t’ was not declared in this scope
     offile_fpos_t off2 = off;
     ^~~~~~~~~~~~~
/usr/local/include/dcmtk/ofstd/offile.h:757:5: note: suggested alternative: ‘offile_off_t’
     offile_fpos_t off2 = off;
     ^~~~~~~~~~~~~
     offile_off_t
/usr/local/include/dcmtk/ofstd/offile.h:792:9: error: ‘off2’ was not declared in this scope
         off2 += buf.st_size;
         ^~~~
/usr/local/include/dcmtk/ofstd/offile.h:792:9: note: suggested alternative: ‘off’
         off2 += buf.st_size;
         ^~~~
         off
/usr/local/include/dcmtk/ofstd/offile.h:808:29: error: ‘off2’ was not declared in this scope
     result = this->fsetpos(&off2);
                             ^~~~
/usr/local/include/dcmtk/ofstd/offile.h:808:29: note: suggested alternative: ‘off’
     result = this->fsetpos(&off2);
                             ^~~~
                             off
/usr/local/include/dcmtk/ofstd/offile.h: In member function ‘offile_off_t OFFile::ftell()’:
/usr/local/include/dcmtk/ofstd/offile.h:837:5: error: ‘offile_fpos_t’ was not declared in this scope
     offile_fpos_t pos;
     ^~~~~~~~~~~~~
/usr/local/include/dcmtk/ofstd/offile.h:837:5: note: suggested alternative: ‘offile_off_t’
     offile_fpos_t pos;
     ^~~~~~~~~~~~~
     offile_off_t
/usr/local/include/dcmtk/ofstd/offile.h:838:24: error: ‘pos’ was not declared in this scope
     if (this->fgetpos(&pos) != 0)
                        ^~~
/usr/local/include/dcmtk/ofstd/offile.h:838:24: note: suggested alternative: ‘pow’
     if (this->fgetpos(&pos) != 0)
                        ^~~
                        pow
/usr/local/include/dcmtk/ofstd/offile.h:843:12: error: ‘pos’ was not declared in this scope
     return pos;
            ^~~
/usr/local/include/dcmtk/ofstd/offile.h:843:12: note: suggested alternative: ‘pow’
     return pos;
            ^~~
            pow
/usr/local/include/dcmtk/ofstd/offile.h: In member function ‘int OFFile::fgetpos(int*)’:
/usr/local/include/dcmtk/ofstd/offile.h:873:48: error: cannot convert ‘int*’ to ‘fpos_t* {aka long long int*}’ for argument ‘2’ to ‘int fgetpos(FILE*, fpos_t*)’
     result = STDIO_NAMESPACE fgetpos(file_, pos);
                                                ^
/usr/local/include/dcmtk/ofstd/offile.h: In member function ‘int OFFile::fsetpos(int*)’:
/usr/local/include/dcmtk/ofstd/offile.h:893:48: error: cannot convert ‘int*’ to ‘const fpos_t* {aka const long long int*}’ for argument ‘2’ to ‘int fsetpos(FILE*, const fpos_t*)’
     result = STDIO_NAMESPACE fsetpos(file_, pos);
                                                ^
CMakeFiles/test1DCMTK.dir/build.make:63: fallo en las instrucciones para el objetivo 'CMakeFiles/test1DCMTK.dir/main.cpp.obj'
make[2]: *** [CMakeFiles/test1DCMTK.dir/main.cpp.obj] Error 1
CMakeFiles/Makefile2:67: fallo en las instrucciones para el objetivo 'CMakeFiles/test1DCMTK.dir/all'
make[1]: *** [CMakeFiles/test1DCMTK.dir/all] Error 2
Makefile:83: fallo en las instrucciones para el objetivo 'all'
make: *** [all] Error 2
adabreug94
  • 23
  • 5

1 Answers1

1

Your CMake is adding the dcmtk include directories like this:

SET(DCMTK_DIR /usr/local/include/dcmtk)
INCLUDE_DIRECTORIES(${DCMTK_DIR}/include)

which evaluates to this path:

/usr/local/include/dcmtk/include

Your main.cpp file then includes dcmtk/config/osconfig.h, which (combining the two paths) suggests the header is located here:

/usr/local/include/dcmtk/include/dcmtk/config/osconfig.h

This doesn't seem correct. Try including only /usr/local/include in your CMake file instead:

INCLUDE_DIRECTORIES(/usr/local/include)

As a side note, CMake provides a Find Module for the DCMTK, so it will attempt to find the library and set some variable for you. You could try something like this, but depending on your CMake version, you may have varying results:

cmake_minimum_required(VERSION 2.8)
PROJECT(test1DCMTK)

find_package(DCMTK REQUIRED)

add_executable(${PROJECT_NAME} main.cpp)

SET(DCMTK_DIR /usr/local/include/dcmtk)

ADD_DEFINITIONS(-D_REENTRANT)

# Use the INCLUDE_DIRS variable populated by the DCMTK find module.
INCLUDE_DIRECTORIES(${DCMTK_INCLUDE_DIRS})

# Use the LIBRARIES variable populated by the DCMTK find module.
TARGET_LINK_LIBRARIES(test1DCMTK ofstd ${DCMTK_LIBRARIES})

If this successfully finds DCMTK, the DCMTK_INCLUDE_DIRS will likely contain all necessary include directories for DCMTK, not only the include directory you have added manually. This may help resolve the compiler errors you are seeing.

Kevin
  • 16,549
  • 8
  • 60
  • 74
  • So, only to be sure, you are suggesting that these lines: ` SET(DCMTK_DIR /usr/local/include/dcmtk) ADD_DEFINITIONS(-D_REENTRANT) INCLUDE_DIRECTORIES(${DCMTK_DIR}/include) LINK_DIRECTORIES(${DCMTK_DIR}/lib) ` Should become in this: ` #SET(DCMTK_DIR /usr/local/include/dcmtk) ADD_DEFINITIONS(-D_REENTRANT) INCLUDE_DIRECTORIES(/usr/local/include) #LINK_DIRECTORIES(${DCMTK_DIR}/lib) ` – adabreug94 Apr 07 '20 at 16:31
  • @adabreug94 Yes, you only need to change the `INCLUDE_DIRECTORIES(... )` command, the others can stay the same. – Kevin Apr 07 '20 at 16:36
  • Ok, I will try it rigth now – adabreug94 Apr 07 '20 at 16:38
  • I got several errors when built. I will edit my answer to show my output – adabreug94 Apr 07 '20 at 16:44
  • @adabreug94 I added another solution to my answer. Using the DCMTK find module may provide better results. – Kevin Apr 08 '20 at 12:32
  • I tested your second solutions, it seems to be throwing the same results. Apparently is not a CMake issue anymore. Please note that I edited the answer and added the output of the building process. It founds the included libraries but it's raising errors with some of the types defined by the libraries. – adabreug94 Apr 09 '20 at 02:00