使用 CMake 编译和链接子项目库
Compiling and linking subproject library with CMake
我有 2 个项目(prj1 和 prj2)。一个 (prj2) 依赖于另一个 (prj1),它是一个静态库。我来用 CMake 分别编译它们。
但我需要将一个 (prj1) 集成到另一个 (prj2)。所以我希望 CMake 在另一个 (prj2) 之前编译静态库 (prj1),然后 link 静态库。我尝试了一些东西,但 id 没有用。
- prj1 "core" 是 https://gitlab.com/RyDroid/PlanetWars2dRT-core
- prj2 "SDL2" 是 https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/(参见分支添加核心)
在 prj2 中,externals/core 是一个 git 子模块(对于非 git 用户,您可以将此目录视为 prj1 的复制粘贴)。
我在 prj2 "SDL2":
中尝试(没有成功)这个 CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wformat=2 -Wpedantic -D_FORTIFY_SOURCE=2")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# TODO
endif()
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
# if (CMAKE_VERSION VERSION_LESS "3.1")
# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
# CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# set (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
# endif()
# else()
# set(CMAKE_CXX_STANDARD 11)
# endif()
project(PlanetWars2dRT-SDL2)
# Version number
set(VERSION_MAJOR "0")
set(VERSION_MINOR "0")
set(VERSION_MICRO "0")
# Configure a header file to pass some of the CMake settings
# to the source code.
configure_file (
"src/compilation_config.h.in"
"${PROJECT_BINARY_DIR}/compilation_config.h"
)
# Add the binary tree to the search path for include files
# so that we will find compilation_config.h
include_directories("${PROJECT_BINARY_DIR}")
set(LIBRARY_OUTPUT_PATH lib/${CMAKE_BUILD_TYPE})
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
include_directories(src/)
file(
GLOB_RECURSE
source_files
src/*
)
add_executable(planet-wars-2d-rt-sdl2 ${source_files})
#include(ExternalProject)
#ExternalProject_Add(PlanetWars2dRT PREFIX externals/core/)
include_directories(externals/core/src/utils/ externals/core/src/specific/)
add_subdirectory(externals/core/)
#find_package(PlanetWars2dRT-core REQUIRED)
include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
pkg_search_module(SDL2GFX REQUIRED SDL2_gfx)
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
target_link_libraries(
planet-wars-2d-rt-sdl2
planet-wars-2d-rt-core
${SDL2_LIBRARIES} ${SDL2GFX_LIBRARIES}
)
这是prj2树的简化版:
.
├── build (with CMake stuff generated with "cmake ..")
├── CMakeLists.txt
├── externals
│ └── core
│ ├── build (with CMake stuff generated with "cmake ..")
│ ├── CMakeLists.txt
│ ├── makefile
│ └── src
├── makefile
├── README.md
└── src
├── compilation_config.h.in
└── planet-wars-2d-rt-sdl2.cpp
如何使用 CMake 在 prj2 "SDL2" 中编译 prj1 "core" 的库,然后使用 prj2(再次使用 CMake)link prj1 的库?
如果您的解决方案不适用于非 GNU/Linux OS,这不是大问题。注意:我的电脑是 运行 Debian GNU/Linux 8 "Jessie".
此致。
我无法访问您的存储库 https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/,可能服务器正在停机维护。如果我正确理解你的问题,你可以创建这样的结构:
根/
- CMakeLists.txt // 1
- 源/
- CMakeLists.txt // 2
- main.cpp
- SDL2/
- 一些来源
- CMakeLists.txt // 3
- 核心/
- 一些来源
- CMakeLists.txt // 4
在 CMakeLists.txt [1] 中,您应该声明您的项目名称、所需的包、常用标志、包含路径等:
cmake_minimum_required( VERSION 2.x )
project(name)
include_directories(inc inc/core inc/SDL2 inc/SthElse)
add_subdirectory(src)
在 CMakeLists.txt [2] 中,对于 subdir src,您应该声明您的主要可执行文件,并添加带有 prj1 和 prj2 的子目录
add_subdirectory(core)
add_subdirectory(SDL2)
add_executable(main main.cpp)
target_link_libraries(main core SDL2 SomeOtherLib)
最后,在你的 CMakeLists.txt [3] && [4] 你的 lib 目录中你应该声明静态库:
add_library(core STATIC ${YourSourceFiles})
这种方法对我一直有效。如果您曾经将 运行 "core" 和 "SDL2" 编译为独立的二进制文件,也许您需要对它们进行一些重组。
两个项目都有一个文件"compilation_config.h"。编译的时候,取错了编译失败,因为使用的代码是#include "compilation_config.h"
,有歧义。
所以我在两个项目中都创建了一个 "include/project-name" 目录,并更改了包含路径:"prj1/compilation_config.h" 或 "prj2/compilation_config.h"。多亏了它不再有歧义,所以它现在可以工作了!
我有 2 个项目(prj1 和 prj2)。一个 (prj2) 依赖于另一个 (prj1),它是一个静态库。我来用 CMake 分别编译它们。
但我需要将一个 (prj1) 集成到另一个 (prj2)。所以我希望 CMake 在另一个 (prj2) 之前编译静态库 (prj1),然后 link 静态库。我尝试了一些东西,但 id 没有用。
- prj1 "core" 是 https://gitlab.com/RyDroid/PlanetWars2dRT-core
- prj2 "SDL2" 是 https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/(参见分支添加核心)
在 prj2 中,externals/core 是一个 git 子模块(对于非 git 用户,您可以将此目录视为 prj1 的复制粘贴)。 我在 prj2 "SDL2":
中尝试(没有成功)这个 CMakeLists.txtcmake_minimum_required(VERSION 2.8)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wformat=2 -Wpedantic -D_FORTIFY_SOURCE=2")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# TODO
endif()
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
# if (CMAKE_VERSION VERSION_LESS "3.1")
# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
# CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# set (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
# endif()
# else()
# set(CMAKE_CXX_STANDARD 11)
# endif()
project(PlanetWars2dRT-SDL2)
# Version number
set(VERSION_MAJOR "0")
set(VERSION_MINOR "0")
set(VERSION_MICRO "0")
# Configure a header file to pass some of the CMake settings
# to the source code.
configure_file (
"src/compilation_config.h.in"
"${PROJECT_BINARY_DIR}/compilation_config.h"
)
# Add the binary tree to the search path for include files
# so that we will find compilation_config.h
include_directories("${PROJECT_BINARY_DIR}")
set(LIBRARY_OUTPUT_PATH lib/${CMAKE_BUILD_TYPE})
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
include_directories(src/)
file(
GLOB_RECURSE
source_files
src/*
)
add_executable(planet-wars-2d-rt-sdl2 ${source_files})
#include(ExternalProject)
#ExternalProject_Add(PlanetWars2dRT PREFIX externals/core/)
include_directories(externals/core/src/utils/ externals/core/src/specific/)
add_subdirectory(externals/core/)
#find_package(PlanetWars2dRT-core REQUIRED)
include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
pkg_search_module(SDL2GFX REQUIRED SDL2_gfx)
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
target_link_libraries(
planet-wars-2d-rt-sdl2
planet-wars-2d-rt-core
${SDL2_LIBRARIES} ${SDL2GFX_LIBRARIES}
)
这是prj2树的简化版:
.
├── build (with CMake stuff generated with "cmake ..")
├── CMakeLists.txt
├── externals
│ └── core
│ ├── build (with CMake stuff generated with "cmake ..")
│ ├── CMakeLists.txt
│ ├── makefile
│ └── src
├── makefile
├── README.md
└── src
├── compilation_config.h.in
└── planet-wars-2d-rt-sdl2.cpp
如何使用 CMake 在 prj2 "SDL2" 中编译 prj1 "core" 的库,然后使用 prj2(再次使用 CMake)link prj1 的库?
如果您的解决方案不适用于非 GNU/Linux OS,这不是大问题。注意:我的电脑是 运行 Debian GNU/Linux 8 "Jessie".
此致。
我无法访问您的存储库 https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/,可能服务器正在停机维护。如果我正确理解你的问题,你可以创建这样的结构:
根/
- CMakeLists.txt // 1
- 源/
- CMakeLists.txt // 2
- main.cpp
- SDL2/
- 一些来源
- CMakeLists.txt // 3
- 核心/
- 一些来源
- CMakeLists.txt // 4
在 CMakeLists.txt [1] 中,您应该声明您的项目名称、所需的包、常用标志、包含路径等:
cmake_minimum_required( VERSION 2.x )
project(name)
include_directories(inc inc/core inc/SDL2 inc/SthElse)
add_subdirectory(src)
在 CMakeLists.txt [2] 中,对于 subdir src,您应该声明您的主要可执行文件,并添加带有 prj1 和 prj2 的子目录
add_subdirectory(core)
add_subdirectory(SDL2)
add_executable(main main.cpp)
target_link_libraries(main core SDL2 SomeOtherLib)
最后,在你的 CMakeLists.txt [3] && [4] 你的 lib 目录中你应该声明静态库:
add_library(core STATIC ${YourSourceFiles})
这种方法对我一直有效。如果您曾经将 运行 "core" 和 "SDL2" 编译为独立的二进制文件,也许您需要对它们进行一些重组。
两个项目都有一个文件"compilation_config.h"。编译的时候,取错了编译失败,因为使用的代码是#include "compilation_config.h"
,有歧义。
所以我在两个项目中都创建了一个 "include/project-name" 目录,并更改了包含路径:"prj1/compilation_config.h" 或 "prj2/compilation_config.h"。多亏了它不再有歧义,所以它现在可以工作了!