【问题标题】:How to cross compile C++ DCMTK projects with CMake (from Ubuntu to Windows)如何使用 CMake 交叉编译 C++ DCMTK 项目(从 Ubuntu 到 Windows)
【发布时间】:2020-04-07 16:15:24
【问题描述】:

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

我也检查了这些答案和示例,但它们对我不起作用:

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

【问题讨论】:

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


    【解决方案1】:

    您的 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 必需的包含目录,而不仅仅是您手动添加的包含目录。这可能有助于解决您看到的编译器错误。

    【讨论】:

    • 所以,为了确定,您建议这些行:` SET(DCMTK_DIR /usr/local/include/dcmtk) ADD_DEFINITIONS(-D_REENTRANT) INCLUDE_DIRECTORIES(${DCMTK_DIR}/include) LINK_DIRECTORIES (${DCMTK_DIR}/lib) ` 应该变成这样: ` #SET(DCMTK_DIR /usr/local/include/dcmtk) ADD_DEFINITIONS(-D_REENTRANT) INCLUDE_DIRECTORIES(/usr/local/include) #LINK_DIRECTORIES(${DCMTK_DIR}/库)`
    • @adabreug94 是的,你只需要更改INCLUDE_DIRECTORIES(... )命令,其他的可以保持不变。
    • 好的,我马上试试
    • 我在构建时遇到了几个错误。我将编辑我的答案以显示我的输出
    • @adabreug94 我为我的答案添加了另一个解决方案。使用 DCMTK 查找模块可能会提供更好的结果。
    猜你喜欢
    • 2021-05-03
    • 2021-09-14
    • 2016-11-18
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 2017-06-26
    • 2021-12-09
    相关资源
    最近更新 更多