我拼命尝试,作为一个CMake新手得到DCMTK做的东西。我试图编译和运行的示例如下:
#include "dcmtk/config/osconfig.h"
#include "dcmtk/dcmdata/dctk.h"
#include "dcmtk/dcmdata/dcistrmf.h"
int main(int argc, char *argv[])
{
OFCondition status;
/* approach 1 */
DcmMetaInfo metainfo;
status = metainfo.loadFile("test.dcm");
if (status.good())
{
OFString sopClassUID, xferUID;
if (metainfo.findAndGetOFString(DCM_MediaStorageSOPClassUID, sopClassUID).good())
COUT << "SOP Class UID: " << sopClassUID << OFendl;
if (metainfo.findAndGetOFString(DCM_TransferSyntaxUID, xferUID).good())
COUT << "Transfer Syntax UID: " << xferUID << OFendl;
metainfo.print(COUT);
}
/* approach 2 */
DcmFileFormat fileformat;
status = fileformat.loadFile("test.dcm", EXS_Unknown, EGL_noChange, DCM_MaxReadLength, ERM_metaOnly);
if (status.good())
{
OFString sopClassUID, xferUID;
if (fileformat.getMetaInfo()->findAndGetOFString(DCM_MediaStorageSOPClassUID, sopClassUID).good())
COUT << "SOP Class UID: " << sopClassUID << OFendl;
if (fileformat.getMetaInfo()->findAndGetOFString(DCM_TransferSyntaxUID, xferUID).good())
COUT << "Transfer Syntax UID: " << xferUID << OFendl;
fileformat.print(COUT);
}
/* approach 3 */
fileformat.clear();
DcmInputFileStream fileStream("test.dcm");
status = fileStream.status();
if (status.good())
{
/* first, read meta-header */
fileformat.setReadMode(ERM_metaOnly);
fileformat.transferInit();
status = fileformat.read(fileStream);
if (status.good())
{
OFString sopClassUID, xferUID;
if (fileformat.getMetaInfo()->findAndGetOFString(DCM_MediaStorageSOPClassUID, sopClassUID).good())
COUT << "SOP Class UID: " << sopClassUID << OFendl;
if (fileformat.getMetaInfo()->findAndGetOFString(DCM_TransferSyntaxUID, xferUID).good())
COUT << "Transfer Syntax UID: " << xferUID << OFendl;
/* then read dataset if certain criteria are met */
if (sopClassUID == UID_SecondaryCaptureImageStorage)
{
fileformat.setReadMode(ERM_autoDetect);
status = fileformat.read(fileStream);
if (status.good())
{
fileformat.print(COUT);
}
}
}
fileformat.transferEnd();
}
return 0;
}
问题来自该文件的上部。我知道,在特定的文件夹中,此代码将有一个构建错误,因为它不会在项目目录中找到dcmtk
文件夹。我已经在驱动器上的其他地方的不同文件夹中构建并安装了DCMTK。因此我有两个文件夹:dcmtk-3.6.5-build
和dcmtk-3.6.5-install
。我知道我感兴趣的是dcmtk-3.6.5-install/include/
。但是当构建时,我得到以下错误:
====================[ Build | test_dcmtk | Debug ]==============================
/snap/clion/139/bin/cmake/linux/bin/cmake --build /home/project_dir/test_dcmtk/cmake-build-debug --target test_dcmtk -- -j 38
Scanning dependencies of target test_dcmtk
[ 50%] Building CXX object CMakeFiles/test_dcmtk.dir/main.cpp.o
/home/project_dir/test_dcmtk/main.cpp:1:10: fatal error: dcmtk/config/osconfig.h: No such file or directory
1 | #include "dcmtk/config/osconfig.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[3]: *** [CMakeFiles/test_dcmtk.dir/build.make:83: CMakeFiles/test_dcmtk.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:96: CMakeFiles/test_dcmtk.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:103: CMakeFiles/test_dcmtk.dir/rule] Error 2
make: *** [Makefile:138: test_dcmtk] Error 2
根据我的理解,我应该将编译器引导到安装DCMTK的目录。然而,当我这样做时,我得到一个非常类似的错误:
====================[ Build | test_dcmtk | Debug ]==============================
/snap/clion/139/bin/cmake/linux/bin/cmake --build /home/project_dir/test_dcmtk/cmake-build-debug --target test_dcmtk -- -j 38
Scanning dependencies of target test_dcmtk
[ 50%] Building CXX object CMakeFiles/test_dcmtk.dir/main.cpp.o
In file included from /home/project_dir/test_dcmtk/main.cpp:2:
/home/dcmtk-3.6.5-install/include/dcmtk/dcmdata/dctk.h:25:10: fatal error: dcmtk/config/osconfig.h: No such file or directory
25 | #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
| ^~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[3]: *** [CMakeFiles/test_dcmtk.dir/build.make:83: CMakeFiles/test_dcmtk.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:96: CMakeFiles/test_dcmtk.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:103: CMakeFiles/test_dcmtk.dir/rule] Error 2
make: *** [Makefile:138: test_dcmtk] Error 2
两个错误之间的区别在于编译器正在寻找的头文件。在第二种情况下,看起来编译器不知道osconfig.h
在哪里。由于这涉及DCMTK安装的文件,我的理解是它们应该按原样工作,这导致我认为这个问题应该用CMake来解决。然而,我完全不知道如何在我的CMakeLists.txt
中做正确的事情……这里我的意思是说这个文件包含
cmake_minimum_required(VERSION 3.16)
project(test_dcmtk)
set(CMAKE_CXX_STANDARD 20)
add_executable(test_dcmtk main.cpp)
我完全不知道该在这里写什么。有人能帮帮我吗?
提前感谢您!
DCMTK遗憾地没有提供正确导出的CMake目标,因此您将不得不修补它。我通过vcpkg安装了DCMTK,并且能够用这个构建编译您的代码(在用std::cout
替换COUT
并包括iostream
之后):
cmake_minimum_required(VERSION 3.19)
project(test_dcmtk)
set(CMAKE_CXX_STANDARD 20)
find_package(DCMTK REQUIRED)
# Wrap the variables that DCMTK sets with a proper imported target
# These three lines ought not to be needed.
# This is a failure on the part of the DCMTK authors.
add_library(DCMTK::DCMTK INTERFACE IMPORTED)
target_link_libraries(DCMTK::DCMTK INTERFACE ${DCMTK_LIBRARIES})
target_include_directories(DCMTK::DCMTK INTERFACE ${DCMTK_INCLUDE_DIRS})
# Create your executable and link it to the library
add_executable(test_dcmtk main.cpp)
target_link_libraries(test_dcmtk PRIVATE DCMTK::DCMTK)
您应该向DCMTK库作者抱怨他们没有提供正确的导入目标。
是否使用MSVC进行编译?试着用Clang编译。