2015-12-01 2 views
0

У меня есть 2 проекта (prj1 и prj2). Один (prj2) зависит от другого (prj1), который является статической библиотекой. Я прихожу для их компиляции отдельно с CMake.Компиляция и компоновка библиотеки подпроектов с CMake

Но мне нужно было интегрировать один (prj1) в другой (prj2). Поэтому я хотел бы, чтобы CMake собирал статическую библиотеку (prj1) перед другой (prj2), а затем связывал статическую библиотеку. Я пробовал вещи, но id не работал.

В prj2, внешние/ядро ​​представляет собой мерзавец подмодуль (для не пользователей GIT, вы можете увидеть эту директорию как copy-paste prj1). Я пытался (безуспешно) этой CMakeLists.txt в prj2 "SDL2":

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, это не является большой проблемой. Примечание. Мой компьютер работает на Debian GNU/Linux 8 «Jessie».

С уважением.

ответ

0

У обоих проектов есть файл "compilation_config.h". Во время компиляции было сделано неверное, поэтому компиляция не удалась, потому что используемый код был #include "compilation_config.h", который был неоднозначным.

Итак, я создал в обоих проектах директорию include/project-name, и я изменил путь include: «prj1/compilation_config.h» или «prj2/compilation_config.h». Благодаря этому больше не было никакой двусмысленности, поэтому она работает сейчас!

2

Я не могу получить доступ к вашему репо 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] вы должны объявить название своего проекта, необходимый пакет s, общие флаги, включая пути и т. д .:

cmake_minimum_required(VERSION 2.x) 
project(name) 

include_directories(inc inc/core inc/SDL2 inc/SthElse) 

add_subdirectory(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» в качестве автономных двоичных файлов, возможно, вам придется немного их реорганизовать.

+0

У меня нет проблем с доступом к репо. Я обновил свой первый пост с организацией файлов. Он (CMake в prj2) пытается скомпилировать «externals/core/src/specific/planet-wars-2d-rt-text.cpp» (который не является частью библиотеки, поэтому бесполезной для prj2 «SDL2»), но она не работает потому что LIB_PLANET_WARS_2D_RT_CORE_VERSION_MAJOR не найден. Этот макрос определен в «externals/core/build/compilation_config.h» (сгенерированный «externals/core/src/specific/compilation_config.h.in» с CMake). – RyDroid

Смежные вопросы