【问题标题】:Linking several programs with CMake使用 CMake 链接多个程序
【发布时间】:2016-02-22 12:55:49
【问题描述】:

我有三个程序以串行代码计算数量 S,并使用 MPI 和 OpenMP 并行计算。所有程序都需要相同的头文件 utils.h。不知何故,在运行 cmake .. 之后,我需要运行两次 make 才能正确编译程序,因为第一次运行会导致链接错误(标准库似乎没有链接)。任何想法为什么会这样?

cmake_minimum_required(VERSION 2.6)
project(compute_S)

find_package(MPI)
enable_language(C)

include_directories(${MPI_INCLUDE_PATH})

set(CMAKE_C_FLAGS "-std=c99")
add_executable(compute_S compute_S.c utils.h)

set(CMAKE_C_FLAGS "-std=c99")
add_executable(compute_S_MPI compute_S_MPI.c utils.h)

set(CMAKE_C_FLAGS "-std=c99 -fopenmp")
add_executable(compute_S_OpenMP compute_S_OpenMP.c utils.h)

target_link_libraries(compute_S ${catkin_LIBRARIES})
target_link_libraries(compute_S_MPI ${MPI_C_LIBRARIES})
target_link_libraries(compute_S_OpenMP ${catkin_LIBRARIES})

您可以通过运行以下命令重现错误

mkdir test 
cd test 
git clone https://github.com/Zetison/exerciseSet4 
cd exerciseSet4 
cmake . 
make

【问题讨论】:

标签: c linker cmake


【解决方案1】:

我尝试了https://cmake.org/pipermail/cmake/2011-June/045037.html 的示例,它显示了如何链接 MPI。模块 FindMPI.cmake 创建以下变量:

  • MPI_INCLUDE_PATH : 包含搜索路径
  • MPI_LIBRARIES:小米库的名字。
  • MPI_COMPILE_FLAGSMPI_LINK_FLAGS:要编译和链接的标志。

同样,FindOpenMP.cmake 模块创建变量OpenMP_C_FLAGSOpenMP_Fortran_FLAGSOpenMP_CXX_FLAGS,它们对应于MPI_LINK_FLAGS。确实可以恢复到-fopenmp

您可以通过输入cmake . 然后输入make 来尝试以下CMakeLists.txt 吗?

cmake_minimum_required(VERSION 2.6)
project(compute_S)

find_package(MPI REQUIRED)
find_package(OpenMP REQUIRED)
enable_language(C)

include_directories(${MPI_INCLUDE_PATH})

set(CMAKE_C_FLAGS "-std=c99")
add_executable(compute_S compute_S.c utils.h)

set(CMAKE_C_FLAGS "-std=c99")
add_executable(compute_S_MPI compute_S_MPI.c utils.h)
# https://cmake.org/pipermail/cmake/2011-June/045037.html
target_link_libraries(compute_S_MPI ${MPI_LIBRARIES})

if(MPI_COMPILE_FLAGS)
  set_target_properties(compute_S_MPI PROPERTIES
    COMPILE_FLAGS "${MPI_COMPILE_FLAGS}")
endif()

if(MPI_LINK_FLAGS)
  set_target_properties(compute_S_MPI PROPERTIES
    LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()

set(CMAKE_C_FLAGS "-std=c99")
add_executable(compute_S_OpenMP compute_S_OpenMP.c utils.h)

# https://cmake.org/cmake/help/v3.0/module/FindOpenMP.html
#message(${OpenMP_C_FLAGS})
if(OpenMP_C_FLAGS)
  set_target_properties(compute_S_OpenMP PROPERTIES
    LINK_FLAGS "${OpenMP_C_FLAGS}")
endif()

target_link_libraries(compute_S ${catkin_LIBRARIES})
target_link_libraries(compute_S_MPI ${MPI_C_LIBRARIES})
target_link_libraries(compute_S_OpenMP ${catkin_LIBRARIES})

【讨论】:

  • 出现同样的错误。我已经更新了描述,以便可以重现错误。
  • @user2978680 我设法用修改后的 CMakeLists.txt 编译了你的程序。我收到了警告,因为函数 fabs()utils.h 中被调用。您可以尝试在 CMakeLists.txt 中的 utils.htarget_link_libraries(compute_S ${catkin_LIBRARIES} m) target_link_libraries(compute_S_MPI ${MPI_C_LIBRARIES} m) target_link_libraries(compute_S_OpenMP ${catkin_LIBRARIES} m) 中添加 #include <math.h> 吗?因此,数学库将被包含并链接。在再次运行 cmake 之前删除 CMakeCache.txt。如果它不能解决你的问题,我不能移动这块石头,我会删除我的答案!
  • 此外,如果在 CMakeLists.txt 的开头没有添加find_package(catkin REQUIRED),则不会设置变量${catkin_LIBRARIES}。您可以添加message(${catkin_LIBRARIES}) 以检查变量是否已设置。
  • 多么尴尬,我一定是在某些时候删除了数学库的包含。感谢帮助!! :)
  • @user2978680:不客气!不要觉得尴尬!
猜你喜欢
  • 2013-02-18
  • 2021-12-05
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多