CMake实战--add_subdirectory
在上一文 <<CMake实战--链接SFML并使用>>中,我们说了如何用CMake来链接编译一个基于SFML库的工程, 并且在ubuntu系统上创建了一个Demo HelloSFML,其有关源码我们放在了一个单独的文件夹下1.HelloSFML。 但是,当我们想再创建一个Demo RenderWindow, 我们也需要将其放在一个单独的文件夹下, 整个工程目录如下:
|SFML_DEMOS
|--|CMakeLists.txt
|--|1.HelloSFML
|--|--|main.cc
|--|2.RenderWindow
|--|--|main.cc
为了好同时编译两个文件夹下的源码, 我们把CMakeListst.txt放在了与两个Demo文件夹同目录下面。
由于CMakeListst.txt位置发生变化,设置SFML SDK的路径及编译1.HelloSFML的源码路径都要发生改变:
set(SFML_SDK "${CMAKE_CURRENT_SOURCE_DIR}/../../SFML_SDK")
set(SFML_SDK "${CMAKE_CURRENT_SOURCE_DIR}/../../SFML_SDK")
set(SOURCE_FILES main.cc)
set(HelloSFML_SOURCE_FILES 1.HelloSFML/main.cc)
add_executable(HelloSFML ${SOURCE_FILES})
add_executable(HelloSFML ${HelloSFML_SOURCE_FILES})
并且在上面语句的后面,需要添加2.RenderWindow的编译目标:
set(RenderWindow_SOURCE_FILES 2.RenderWindow/main.cc)
add_executable(RenderWindow ${RenderWindow_SOURCE_FILES})
然后,给RenderWindow的目标链接库:
if(SFML_LIBRARIES)
target_link_libraries(HelloSFML ${SFML_LIBRARIES})
target_link_libraries(RenderWindow ${SFML_LIBRARIES})
endif()
以上,是两个目标文件写到一起的情况,虽然方便,但是对于我们管理不同的编译目标,如去掉某个编译目标带来很大的不便。因此,我们需要将不同的编译目标写到不同的CMakeLists.txt文件中,并用一个CMakeLists.txt进行统一管理,这样做与上面做法的区别就像面向过程编程和面向对象编程的区别一样。
重新调整结构目录:
|SFML_DEMOS
|--CMakeLists.txt // Root CMakeLists.txt
|--|1.HelloSFML
|--|--|CMakeLists.txt
|--|--|main.cc
|--|2.RenderWindow
|--|--|CMakeLists.txt
|--|--|main.cc
在SFML_DEMOS跟目录下得CMakeLists.txt是主CMake编译文件, 它负责创建整个工程,编译工程目标,安装编译目标等。
这个工程我们需要编译两个目标,一个是位于1.HelloSFML文件夹下的可执行程序,一个是位于2.RenderWindow文件夹下的可执行程序。
在每个文件夹下都对应了一个CMakeLists.txt.
SFML_DEMOS下的CMakeLists.txt的写法如下:
cmake_minimum_required(VERSION 3.0.2)
project(NV3D_SFML)
set(SFML_SDK "${CMAKE_CURRENT_SOURCE_DIR}/../SFML_SDK")
#find SFML Library
#see https://stackoverflow.com/questions/19302542/finding-a-directory-in-cmake
find_path(SFML_INCLUDE_DIR_SYSTEM_H NAMES System.hpp PATHS /usr/include /usr/local/include ${SFML_SDK}/include/SFML/)
find_library(SFML_SYSTEM_LIBRARY NAMES sfml-system PATHS /usr/lib /usr/local/lib ${SFML_SDK}/lib)
find_library(SFML_WINDOW_LIBRARY NAMES sfml-window PATHS /usr/lib /usr/local/lib ${SFML_SDK}/lib)
find_library(SFML_GRAPHIC_LIBRARY NAMES sfml-graphics PATHS /usr/lib /usr/local/lib ${SFML_SDK}/lib)
set(SFML_LIBRARIES ${SFML_SYSTEM_LIBRARY} ${SFML_WINDOW_LIBRARY} ${SFML_GRAPHIC_LIBRARY})
set(SFML_INCLUDE_DIR ${SFML_INCLUDE_DIR_SYSTEM_H}/../)
if(SFML_INCLUDE_DIR)
include_directories(${SFML_INCLUDE_DIR})
endif()
add_subdirectory(1.HelloSFML)
add_subdirectory(2.RenderWindow)
add_subdirectory(NAME)--添加一个文件夹进行编译,该文件夹下的CMakeLists.txt 负责编译该文件夹下的源码. NAME是想对于调用add_subdirectory的CMakeListst.txt的相对路径.
这样在每个子文件夹下的CMakeLists.txt里, 我们只需要设置源码,添加可执行目标,并链接目标和库即可.如1.HelloSFML下的CMakeLists.txt如下:
set(SOURCE_FILES main.cc)
add_executable(Hello_SFML ${SOURCE_FILES})
if(SFML_LIBRARIES)
target_link_libraries(Hello_SFML ${SFML_LIBRARIES})
endif()