快问:如何编写CMakeLists.txt以避免下面描述的HDF5链接问题?
我正在使用HDF5库(1.10.1)制作一个C ++项目
我通过源代码文件tarball和CMake安装了
(安装在/usr/local/
)
我也使用CMake为我的项目配置构建环境
(CMake 3.8.1,CentOS 7上的g ++ 5.3.1)
最近,由于链接错误,我的应用程序无法编译
(附上的错误日志)
在我的一位同事更新了服务器和一些软件包时,还发现了HDF5 1.8.12
这些库文件位于/usr/lib64/
所以,我认为,
所以,我应该如何编写/修复CMakeLists.txt以避免此类链接错误?
即在这种情况下如何正确链接HDF5 1.10.1?
编辑:在CMakeLists.txt周围添加了更多详细信息
以下是我项目的CMakeLists.txt的一些细节:
cmake_minimum_required(VERSION 3.8.1)
# Reference: https://github.com/dmonopoly/gtest-cmake-example/blob/master/CMakeLists.txt
project (adl-boilerplate)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.64.0 COMPONENTS program_options)
option(ENABLE_HDF5 "Enable HDF5 support" ON)
if(ENABLE_HDF5)
set(HDF5_ROOT /usr/local/hdf5/)
find_package(HDF5 "1.10.1" REQUIRED)
if(HDF5_FOUND)
include_directories(${HDF5_INCLUDE_DIR})
set(_hdf5_libs hdf5 hdf5_cpp hdf5_hl hdf5_hl_cpp)
message(STATUS "HDF5 root: ${HDF5_ROOT}")
message(STATUS "HDF5 version: ${HDF5_VERSION}")
message(STATUS "HDF5 include dir: ${HDF5_INCLUDE_DIRS}")
message(STATUS "HDF5 CXX lib: ${HDF5_LIBRARIES}")
message(STATUS "CMake library path: " ${CMAKE_LIBRARY_PATH})
else()
# Download HDF5 library and define hdf5_local
# ...
endif()
endif()
# Get includes/srcs
file(GLOB_RECURSE adl-boilerplate_SOURCES "src/*.cpp")
file(GLOB_RECURSE adl-boilerplate_HEADERS "src/*.h")
set(adl-boilerplate_INCLUDE_DIRS "include")
include_directories(${adl-boilerplate_INCLUDE_DIRS})
if(ENABLE_HDF5)
add_executable(
runner
${adl-boilerplate_SOURCES}
)
target_link_libraries(
runner
${_hdf5_libs}
)
endif()
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(runner ${Boost_LIBRARIES})
endif()
以及执行make
[100%] Linking CXX executable runner
CMakeFiles/runner.dir/src/GociHdf5Handler.cpp.o: In function
'CGociHdf5Handler::OpenRrs(CGociHdf5Handler::AvailableRrs)':
GociHdf5Handler.cpp:(.text+0x166b): undefined reference to
`H5::H5Location::openDataSet(std::string const&) const'
GociHdf5Handler.cpp:(.text+0x18ad): undefined reference to
`H5::H5Object::attrExists(std::string const&) const'
GociHdf5Handler.cpp:(.text+0x18e1): undefined reference to
`H5::H5Object::openAttribute(std::string const&) const'
CMakeFiles/runner.dir/src/GociHdf5Handler.cpp.o: In function
`CGociHdf5Handler::OpenFlags()':
GociHdf5Handler.cpp:(.text+0x1c72): undefined reference to
`H5::H5Location::openDataSet(std::string const&) const'
CMakeFiles/runner.dir/src/GociHdf5Handler.cpp.o: In function
`CGociHdf5Handler::WriteOutput(std::unique_ptr<float [],
std::default_delete<float []> >, std::string)':
GociHdf5Handler.cpp:(.text+0x20af): undefined reference to
`H5::H5Location::createGroup(char const*, unsigned long) const'
GociHdf5Handler.cpp:(.text+0x20cc): undefined reference to
`H5::H5Location::createGroup(char const*, unsigned long) const'
GociHdf5Handler.cpp:(.text+0x20e9): undefined reference to
`H5::H5Location::createGroup(char const*, unsigned long) const'
GociHdf5Handler.cpp:(.text+0x2109): undefined reference to
`H5::H5Location::createGroup(char const*, unsigned long) const'
GociHdf5Handler.cpp:(.text+0x2179): undefined reference to
`H5::H5Location::createDataSet(std::string const&, H5::DataType const&,
H5::DataSpace const&, H5::DSetCreatPropList const&) const'
GociHdf5Handler.cpp:(.text+0x2229): undefined reference to
`H5::H5Object::createAttribute(std::string const&, H5::DataType const&,
H5::DataSpace const&, H5::PropList const&) const'
collect2: error: ld returned 1 exit status
make[2]: *** [runner] 오류 1
make[1]: *** [CMakeFiles/runner.dir/all] 오류 2
make: *** [all] 오류 2
答案 0 :(得分:1)
使用find_package
表示您的代码将使用include_directories
和target_link_libraries
中 中定义的变量。
根据FindHDF5 docs,您的案例的正确用法是:
# Explicitely list required HDF5 components
find_package(HDF5 COMPONENTS CXX HL)
include_directories(${HDF5_INCLUDE_DIRS})
target_link_libraries(
runner
${HDF5_LIBRARIES} # This should list all libraries.
)
答案 1 :(得分:0)
cmake&#34; finder&#34;对于HDF5,可以受环境变量HDF5_ROOT
的影响,以确定在多次安装的情况下要使用的HDF5安装。
创建一个新的构建目录以删除任何缓存的设置
定义HDF5_ROOT
export HDF5_ROOT=/usr/local
(或export HDF5_ROOT=/usr/local/hdf5-1.10.1
如果HDF5在子目录中。)
进行新构建或删除缓存设置非常重要,否则将无法获取设置。
如果这不起作用,我建议删除/usr
安装HDF。