【问题标题】:CMake add_subdirectory not invoking the child CMakeLists.txtCMake add_subdirectory 不调用子 CMakeLists.txt
【发布时间】:2016-12-25 07:42:06
【问题描述】:

我有一个像这样的项目结构,我希望使用 CMake 构建它。

root\
|
|--crystal\
|        |
|        |--include\ Math.h, Window.h
|        |--src\ Math.cpp, Window.cpp
|        |--lib\
|        |--CMakeLists.txt // the CHILD cmake
|
|--game\ main.cpp
|--CMakeLists.txt // the PARENT cmake

水晶子项目应该在lib/文件夹中生成一个静态库(libcrystal.a)(使用include/src/的内容)和root 项目将从game/main.cpp 链接libcrystal.a 静态库生成一个可执行文件。

父CMAKE如下:

cmake_minimum_required(VERSION 2.8.1)
project(thegame)

set(CRYSTAL_LIB_DIR lib)
set(CRYSTAL_LIB_NAME crystal)

add_subdirectory(${CRYSTAL_LIB_NAME})

set(LINK_DIR ${CRYSTAL_LIB_NAME}/${CRYSTAL_LIB_DIR})

set(SRCS game/main.cpp)
link_directories(${LINK_DIR})
include_directories(${CRYSTAL_LIB_NAME}/include)

add_executable(thegame ${SRCS})
target_link_libraries(thegame lib${CRYSTAL_LIB_NAME}.a)

子CMAKE如下:

cmake_minimum_required(VERSION 2.8.1)

project(crystal)

include_directories( include )
file(GLOB_RECURSE SRC "src/*.cpp")

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CRYSTAL_LIB_DIR})
add_library(${CRYSTAL_LIB_NAME} STATIC ${SRC})

什么不起作用:

当我在 root/ 目录中执行 cmake .sudo make 时,我希望父 cmake 和子 cmake 都按顺序运行。但似乎子 cmake 没有被调用,因此没有生成 .a 文件。它显示了一些错误,例如:

Scanning dependencies of target thegame
[ 20%] Building CXX object CMakeFiles/thegame.dir/game/main.cpp.o
[ 40%] Linking CXX executable thegame
/usr/bin/ld: cannot find -lcrystal
collect2: error: ld returned 1 exit status
CMakeFiles/thegame.dir/build.make:94: recipe for target 'thegame' failed
make[2]: *** [thegame] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/thegame.dir/all' failed
make[1]: *** [CMakeFiles/thegame.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

什么是有效的:

我继续做了这个

  1. root/ 中执行cmake .
  2. 导航到crystal文件夹并通过sudo make手动调用Makefile
  3. 再次来到root/并通过sudo make调用外部Makefile

而且这完美运行

问题:

为什么没有像我在 什么不起作用 部分中提到的那样调用子 CMake ???

【问题讨论】:

  • 一般建议:不要使用 CMake 进行 in-source 构建(即cmake .)。在项目目录树之外创建一个单独的构建目录(例如,作为root/ 的兄弟)。

标签: c++ makefile build cmake


【解决方案1】:

在根 CMakeLists.txt 中使用 target_link_libraries(thegame ${CRYSTAL_LIB_NAME}) 并删除 link_directories 调用。 CMake 将识别您正在链接到 crystal 目标并相应地设置 makefile 依赖项和编译器标志。

【讨论】:

  • 这解决了我的问题。因此,lib 前缀和.a 扩展不是明确需要的。但是我想知道为什么删除 link_directories 电话不会影响任何事情。 g++-L开关不是必须的吗?
  • @AyanDas CMakes 解决了这个问题并添加了所需的一切。根据经验,只需将库的完整路径传递到target_link_libraries,不要完全使用link_directories
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 2018-09-20
相关资源
最近更新 更多