c++ - 如何使用CMake交叉编译C++ DCMTK项目(从Ubuntu到Windows)

标签 c++ cmake compiler-errors cross-compiling dcmtk

我正在尝试交叉编译我发现的最简单的DCMTK示例,并且可以将其构建。
我正在运行Ubuntu 18.04.4 LTS以使用x86_64-w64-mingw32进行交叉编译。

我也检查了这些答案和示例,但它们对我没有用:

  • CMake: Cross-compiling linux-to-windows with MinGW does not find some system headers
  • https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/cross_compiling/Mingw

  • 这是项目的唯一文件(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;
    }
    

    这是我的CMake.txt配置文件:
    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)
    

    我正在使用此工具链文件:
    ### 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)
    

    当我使用CMake配置时,得到以下信息:
    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
    

    但是,当我尝试构建代码时,这是我得到的:
    /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
    

    但是,该库存在:
    (base) yo@MiPC:/usr/local/include/dcmtk/config$ ls /usr/local/include/dcmtk/config/os*
    /usr/local/include/dcmtk/config/osconfig.h
    

    那么,我在做什么错呢?我应该怎么做才能使其正常工作?

    我尝试了@squareskittles的答案,尝试构建时得到了这个:
    (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
    

    最佳答案

    您的CMake正在添加dcmtk包含目录,如下所示:

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

    结果如下:
    /usr/local/include/dcmtk/include
    

    然后,您的main.cpp文件包括dcmtk/config/osconfig.h,该文件(结合了两个路径)表明标题位于此处:
    /usr/local/include/dcmtk/include/dcmtk/config/osconfig.h
    

    这似乎不正确。尝试在CMake文件中仅包括/usr/local/include:
    INCLUDE_DIRECTORIES(/usr/local/include)
    

    作为附带说明,CMake为DCMTK提供了Find Module,因此它将尝试查找库并为您设置一些变量。您可以尝试类似的方法,但是根据您的CMake版本,结果可能会有所不同:
    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})
    

    如果此操作成功找到DCMTK,则DCMTK_INCLUDE_DIRS可能会包含,包括DCMTK所需的所有包含目录,而不仅仅是您手动添加的包含目录。这可能有助于解决您看到的编译器错误。

    关于c++ - 如何使用CMake交叉编译C++ DCMTK项目(从Ubuntu到Windows),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61084555/

    相关文章:

    c++ - 如果名称包含 "update",Windows 会强制文件进行 UAC 提升?

    c++ - 在 Windows 上编译 libssh2

    java - Java 10 上的 Swing 问题

    c++ - 不确定如何将 opencv 库添加到 CMakeLists.txt

    c - Ubuntu,如何在 C 中链接 .exp 文件?

    asp.net 代码隐藏看不到 aspx 页面中声明的对象并导致生成错误

    c++ - 在 C++ 中避免整数溢出的模数函数

    c++ - MSVC 中的分解

    c++ - C++ 和 eigen3 的编译器错误

    c++ - 如何在 CLion 中设置基本的 openMP 项目