Как мне настроить эту структуру папок в CMake? - PullRequest
2 голосов
/ 27 мая 2020

Я пытаюсь переключиться с проекта Xcode на проект на основе CMake. (Xcode автоматизировал все настройки проекта). У меня есть эта настройка проекта:

game/ (Includes the core utils used by the client and the server. Has libraries -llua, -lbullet, etc.)
| util.cpp
| CMakeLists.txt
game-client/ (The client. Has libraries -lglfw)
| window.cpp
| CMakeLists.txt
game-server/ (The server)
| server.cpp
| CMakeLists.txt
game-test/ (Tests source files in the game/ directory)
| util-tester.cpp

game-client / и game-server / оба зависят от игры /. Однако, когда я пытаюсь добавить add_subdirectory(../tdgame) в файл game-client / CMakeLists.txt, он сообщает мне:

"game/" is not a subdirectory of "game-client/".  When specifying an
out-of-tree source a binary directory must be explicitly specified.

Итак, как мне это настроить? Я никогда раньше не использовал CMake.

Ответы [ 2 ]

2 голосов
/ 27 мая 2020

Вот как я бы установил такой проект:

./CMakeLists.txt:

cmake_minimum_required(VERSION 3.0.2)
project(my_game)

add_subdirectory(game)
add_subdirectory(game-client)
add_subdirectory(game-server)

Обратите внимание, что очень важно, чтобы подкаталоги добавлялись в обратном порядке зависимости. Например, game-server зависит от game, поэтому его следует добавить после него.

./game/CMakeLists.txt:

find_package(Lua REQUIRED)

add_library(game utils.cpp)
target_include_directories(game PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${LUA_INCLUDE_DIR})
target_link_libraries(game PUBLIC ${LUA_LIBRARIES})

Здесь решающее значение имеют target_include_directories и target_link_libraries. Когда вы используете режим PUBLIC, вы сообщаете cmake, что каждая цель, которая зависит от вашей библиотеки, должна также иметь эти каталоги, добавленные в путь поиска препроцессора, и если это исполняемый файл, он также должен быть связан с вашими зависимостями.

./game-client/CMakeLists.txt:

add_executable(game-server main.cpp)
target_link_libraries(game-server PUBLIC game)

Вам также необходимо сообщить cmake, что ваш исполняемый файл зависит от вашей библиотеки.

Вот пример (исходный код примера находится в /tmp/so/game)

$ make VERBOSE=1 | grep main.cpp
[...]
cd /tmp/a/game-client && /usr/bin/c++   -I/tmp/so/game -I/usr/include/lua5.3   -o CMakeFiles/game-client.dir/main.cpp.o -c /tmp/so/game-client/main.cpp
/usr/bin/c++    -rdynamic CMakeFiles/game-client.dir/main.cpp.o  -o game-client ../game/libgame.a -llua5.3 -lm
1 голос
/ 27 мая 2020

Если вы запускаете CMake из проекта game-client, каталог game будет вне исходного дерева проекта game-client. Итак, как объясняется в сообщении об ошибке, вы должны предоставить CMake двоичный каталог для использования сгенерированных файлов сборки, связанных с game:

add_subdirectory(../tdgame ${CMAKE_BINARY_DIR}/game)

Возможно, лучшим подходом было бы построить все эти проекты внутри тот же экземпляр CMake. Просто добавьте файл CMakeLists.txt верхнего уровня (как родственник папки game), который вызывает add_subdirectory() для каждого из подпроектов:

cmake_minimum_required(VERSION 3.16)

project(MyGameProj)

add_subdirectory(game)
add_subdirectory(game-client)
add_subdirectory(game-server)
# Uncomment this if your 'game-test' directory also contains a CMakeLists.txt file.
#add_subdirectory(game-test)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...