2016-12-25 107 views
0

我有一个这样的项目结构,我希望使用CMake构建。CMake add_subdirectory不调用子CMakeLists.txt

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/的内容)和项目将产生一个可执行出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}) 

什么不工作:

当我执行cmake .sudo makeroot/目录我期望父母和孩子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 

什么是工作:

我继续在root/

  • 导航这样做

    1. 执行cmake .crystal文件夹,并手动调用Makefile由sudo make
    2. 来到root/再次和sudo make

    调用外部的Makefile,这完美工作

    问:

    为什么孩子CMake的,因为我在什么不工作部分中提到的是没有得到调用???

  • +1

    一般建议:不要用CMake做_in-source_构建(即'cmake .')。在项目目录树之外创建一个单独的构建目录(例如,作为“root /”的同级)。 –

    回答

    2

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

    +0

    这解决了我的问题。所以,'lib'前缀和'.a'扩展名不是显式需要的。但是我想知道为什么删除'link_directories'调用不影响任何东西。 'g ++'的'-L'开关不是必需的吗? –

    +1

    @AyanDas CMakes指出并补充了所需的一切。作为一个经验法则,将库的完整路径传递到'target_link_libraries'并且不要完全使用'link_directories'。 – arrowd