使用CMake

时间:2017-09-22 02:18:34

标签: c++ cmake centos7 hdf5

快问:如何编写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/ 所以,我认为,

  • 包含文件从1.10.1
  • 引用
  • 链接时从1.8.12引用库
  • 兼容性问题上升(即这些API未在HDF5 1.8.12中定义),导致链接错误
    (我查找了HDF5 C ++ API参考,看起来是真的)

所以,我应该如何编写/修复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

2 个答案:

答案 0 :(得分:1)

使用find_package表示您的代码将使用include_directoriestarget_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安装。

  1. 创建一个新的构建目录以删除任何缓存的设置

  2. 定义HDF5_ROOT

    export HDF5_ROOT=/usr/local
    
  3. (或export HDF5_ROOT=/usr/local/hdf5-1.10.1如果HDF5在子目录中。)

    1. 再次运行cmake
    2. 进行新构建或删除缓存设置非常重要,否则将无法获取设置。

      如果这不起作用,我建议删除/usr安装HDF。