使用CMake编译和链接子项目库

时间:2015-12-01 17:22:15

标签: compilation cmake subproject

我有2个项目(prj1和prj2)。一个(prj2)依赖于另一个(prj1),它是一个静态库。我到了用CMake单独编译它们。

但我需要将一个(prj1)整合到另一个(prj2)。所以我希望CMake在另一个(prj2)之前编译静态库(prj1),然后链接静态库。我试过了,但是id没用。

在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

如何编译prj1" core"的库?在prj2" SDL2"使用CMake,然后将prj1的库与prj2链接(再次使用CMake)?

如果您的解决方案不适用于非GNU / Linux操作系统,则不是一个大问题。注意:我的PC运行在Debian GNU / Linux 8" Jessie"。

问候。

2 个答案:

答案 0 :(得分:3)

我无法访问您的仓库https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/,也许服务器已关闭以进行维护。如果我正确理解您的问题,您可以创建一个类似的结构:

根/

  • CMakeLists.txt // 1
  • 的src /
    • 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)

在subdir src的CMakeLists.txt [2]中,您应该声明主要的可执行文件,并使用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"作为独立的二进制文件,也许你必须重新组织它们。

答案 1 :(得分:0)

两个项目都有一个文件“compilation_config.h”。在编译时,出现了错误,因此编译失败,因为使用的代码是#include "compilation_config.h",这是不明确的。

所以我在两个项目中创建了一个“include / project-name”目录,并且我更改了包含路径:“prj1 / compilation_config.h”或“prj2 / compilation_config.h”。多亏了这一点,不再有任何歧义,所以它现在有效!