Компиляция и компоновка библиотеки подпроектов с CMake
У меня есть 2 проекта (prj1 и prj2). Один (prj2) зависит от другого (prj1), который является статической библиотекой. Я прибываю, чтобы скомпилировать их отдельно с CMake.
Но мне нужно было объединить одно (prj1) с другим (prj2). Поэтому я хотел бы, чтобы CMake скомпилировал статическую библиотеку (prj1) перед другой (prj2) и затем связал статическую библиотеку. Я пробовал вещи, но id не работал.
- prj1 "ядро" - это https://gitlab.com/RyDroid/PlanetWars2dRT-core
- prj2 "SDL2" - это https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/ (см. ветку добавления ядра)
В prj2 externals/core - это подмодуль git (для пользователей, не являющихся git, этот каталог можно увидеть как копирование-вставку 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".
С уважением.
2 ответа
Оба проекта имеют файл "compilation_config.h". Во время компиляции произошла ошибка, поэтому компиляция не удалась, поскольку использованный код #include "compilation_config.h"
это было неоднозначно.
Поэтому я создал каталог "include/project-name" в обоих проектах и изменил путь включения: "prj1/compilation_config.h" или "prj2/compilation_config.h". Благодаря этому больше не было никакой двусмысленности, так что теперь это работает!
Я не могу получить доступ к вашему репо 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)
В 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" в качестве автономных двоичных файлов, возможно, вам придется их немного реорганизовать.