Почему-то меня совершенно сбивает с толку принцип работы CMake. Каждый раз, когда мне кажется, что я все ближе понимаю, как должен быть написан CMake, он исчезает в следующем примере, который я читал. Все, что я хочу знать, это то, как мне структурировать свой проект, чтобы мой CMake требовал минимального обслуживания в будущем. Например, я не хочу обновлять свой CMakeList.txt, когда я добавляю новую папку в свое дерево src, которая работает точно так же, как все другие папки src.
Так я представляю себе структуру своего проекта, но, пожалуйста, это только пример. Если рекомендуемый способ отличается, сообщите мне, как это сделать.
myProject
src/
module1/
module1.h
module1.cpp
module2/
[...]
main.cpp
test/
test1.cpp
resources/
file.png
bin
[execute cmake ..]
Кстати, важно, чтобы моя программа знала, где находятся ресурсы. Я хотел бы знать рекомендуемый способ управления ресурсами. Я не хочу получать доступ к своим ресурсам с помощью "../resources/file.png"
источник
For example I don't want to update my CMakeList.txt when I am adding a new folder in my src tree
вы можете привести пример IDE, которая автоматически собирает исходники?Ответы:
после некоторого исследования у меня теперь есть собственная версия самого простого, но полного примера cmake. Вот он, и он пытается охватить большинство основ, включая ресурсы и упаковку.
одна вещь, которую он выполняет нестандартно, - это обработка ресурсов. По умолчанию cmake хочет поместить их в / usr / share /, / usr / local / share / и что-то подобное в Windows. Я хотел иметь простой zip / tar.gz, который можно было распаковать где угодно и запустить. Поэтому ресурсы загружаются относительно исполняемого файла.
Основное правило для понимания команд cmake - это следующий синтаксис:
<function-name>(<arg1> [<arg2> ...])
без запятой и точки с запятой. Каждый аргумент представляет собой строку.foobar(3.0)
иfoobar("3.0")
то же самое. вы можете установить списки / переменные с помощьюset(args arg1 arg2)
. С этим набором переменныхfoobar(${args})
иfoobar(arg1 arg2)
фактически то же самое. Несуществующая переменная эквивалентна пустому списку. Список внутри представляет собой просто строку с точкой с запятой для разделения элементов. Таким образом, список с одним элементом по определению является именно этим элементом, без упаковки. Переменные глобальные. Встроенные функции предлагают некоторую форму именованных аргументов , поскольку они ожидают некоторых идентификаторов, таких какPUBLIC
илиDESTINATION
в их списке аргументов, чтобы сгруппировать аргументы. Но это не языковая функция, эти идентификаторы также являются просто строками и анализируются реализацией функции.вы можете клонировать все с github
источник
set(sources src/main.cpp)
.CMakeLists.txt
, то обычный make (или ниндзя) вызовет повторный вызов cmake, поэтому вы не сможете его забыть. Это также немного удобнее для команды, потому что тогда члены команды также не могут забыть выполнить cmake. Но я думаю, что make-файл не нужно трогать только потому, что кто-то добавил файл. Напишите это один раз, и никто больше не должен думать об этом.Самый простой, но полный пример можно найти в учебнике CMake :
Для примера вашего проекта у вас может быть:
Чтобы ответить на ваш дополнительный вопрос, можно снова обратиться к руководству: создать настраиваемый файл заголовка, который вы включите в свой код. Для этого сделайте напильник
configuration.h.in
со следующим содержанием:Тогда в вашем
CMakeLists.txt
добавлении:Наконец, если вам нужен путь в коде, вы можете:
источник
string resourcePath = string(RESOURCE_PATH) + "file.png"
IMHO - плохая идея жестко указывать абсолютный путь к исходному каталогу. Что делать, если вам нужно установить свой проект?Здесь я пишу самый простой, но полный пример файла CMakeLists.txt.
Исходный код
После этого я предложил документ для подробностей.
Если у вас есть вопросы, вы можете связаться со мной, и я хотел бы это объяснить.
источник