Как написать CMakeLists.txt для большого проекта с несколькими подкаталогами?

Я работаю над проектом моделирования: беру встроенную кодовую базу C с целевой платформы и пытаюсь смоделировать ее на главном компьютере для отладки или однократного ввода кода.

ОС: Ubuntu Linux 14.04, IDE: CodeLite, Генератор Makefile: Cmake. Я не понимаю, как написать CMakeLists.txt для проекта. Ниже приводится структура кодовой базы (все написано на C):

|ARQSim\  
|-->ARQSim.h  
|-->ARQSim.c  
|-->BaseStationCode\  
|   |->downlink.c  
|   |->neoncopy.c  
|   |->armCore\  
|   |  |->common\  
|   |  |  |->Bsconfig.h  
|   |  |  |->config.h  
|   |  |->MacSource\  
|   |  |  |->lib\  
|   |  |  |  |->arqCommon.h  
|   |  |  |  |->OverTheAir.h  
|   |  |  |->source\  
|   |  |  |  |->beacon.c  
|   |  |  |  |->proxyDhcp.c  
|   |  |  |  |->ARQ\  
|   |  |  |  |  |->arqCommon.c  
|   |  |  |  |  |->arqInterface.c  
|   |  |  |  |  |->fragmentation\  
|   |  |  |  |  |  |->fragBookkeeping.c  
|   |  |  |  |  |  |->fragProcessAck.c  
|   |  |  |  |  |->reassembly\  
|   |  |  |  |  |  |->reasmBookkeeping.c  
|   |  |  |  |  |  |->reasmProcessAck.c

Я совершенно новичок в Cmake. Я прочитал много ресурсов по CMake и потоков здесь, в StackOverflow. Но каждый раз путаюсь. Несколько вопросов у меня:

  1. Мне нужен только один файл CMakeLists.txt в корневом каталоге или для каждого каталога нужен другой файл CMakeLists.txt?
  2. Как рекурсивно добавить исходные файлы в CMakeLists.txt?
  3. Какие основные команды мне нужно добавить в CMakeLists.txt для создания MakeFile?

Приветствуется пример, основанный на структуре кода, упомянутой выше.


person Kazi Hasan    schedule 07.11.2017    source источник
comment
Перечисленная выше структура кажется полным беспорядком. Возможно, вам сначала потребуется разделить его на несколько проектов.   -  person user7860670    schedule 07.11.2017
comment
У вашей цели нет отладчика?   -  person Christian Gibbons    schedule 07.11.2017
comment
@VTT Да, я согласен, структура испорчена, и я еще не разместил здесь все дерево. Хотелось бы, чтобы у меня было время организовать это, но мне нужно начать отладку как можно скорее, поэтому я взял базу встроенного кода как есть. Спасибо   -  person Kazi Hasan    schedule 08.11.2017
comment
@ChristianGibbons: У нас есть отладчик на встроенной платформе. Однако его работа на No-OS-Bare-Metal-while (1) и отладка на платформе безумны. Целевая платформа (OMAP) зависит от непрерывной обратной связи по прерыванию от встроенной FPGA и DSP. Single Stepping останавливает эту обратную связь (прекращается беспроводная модуляция, следовательно, обратная связь от DSP отсутствует). В крайнем случае, который я хочу отладить, необходимо, чтобы беспроводная модуляция всегда была включена. Вот почему мы пытаемся смоделировать сценарий на главном ПК и зайти в него за один раз.   -  person Kazi Hasan    schedule 08.11.2017


Ответы (1)


Мне нужен только один CMakeLists.txt в корневом каталоге или для каждого каталога нужен свой CMakeLists.txt файл?

Обычно по одному на каждом уровне дерева там, где это имеет смысл.

eg:

root/
+--- CMakeLists.txt             // your root CMakeLists
+--- foo/
|    +--- CMakeLists.txt        // foo component's CMakeLists
|    +--- foo.c
|    +--- tests/
|         +--- CMakeLists.txt   // foo test's CMakeLists
|         +--- foo_tests.c
+--- bar/
     +--- CMakeLists.txt        // bar component's CMakeLists
     +--- bar.c
     +--- bar_impl/             // no CMakeLists for this dir, it is part of bar
     |    +--- bar_impl.c
     +--- tests/
          +--- CMakeLists.txt   // bar test's CMakeLists
          +--- bar_tests.c

Корень проекта CMakeLists.txt:

В корне вашего проекта CMakeLists.txt вы указываете минимальные требования cmake, имя проекта и включаете подкаталоги, в которых есть ваши различные компоненты.

root/CMakeLists.txt:

cmake_minimum_required (VERSION 3.5)
project (my_project C)

add_subdirectory(foo)
add_subdirectory(bar)

Компонент CMakeLists.txt:

Затем в каждом подкаталоге компонентов у вас есть еще один CMakeLists.txt файл, в который вы добавляете библиотеки, исполняемые файлы и т. Д.

root/foo/CMakeLists.txt:

add_library(foo foo.c)
target_include_directories(foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

add_subdirectory(tests)

root/foo/tests/CMakeLists.txt:

add_executable(foo_test foo_tests.c)
target_link_libraries(foo_test foo)

Вы следуете этой структуре для бара и т. Д.

root/bar/CMakeLists.txt:

add_library(bar 
    bar.c 
    bar_impl/bar_impl.c)
target_include_directories(bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(bar foo)

add_subdirectory(tests)

root/bar/tests/CMakeLists.txt:

add_executable(bar_test bar_tests.c)
target_link_libraries(bar_test bar)

Создание файлов сборки:

Чтобы начать сборку, вы указываете cmake на свой root/CMakeLists.txt

cd root
mkdir build
cd build
cmake ..

(или используйте диспетчер сборки вашего ide, чтобы сгенерировать его конфигурацию сборки)

дальнейшее чтение

Подробнее о различных функциях, которые я здесь использовал, см. В документации:

Наконец, чтобы ответить на ваш второй вопрос:

Как рекурсивно добавить исходные файлы в CMakeLists.txt?

Это не рекомендуется (дополнительные подробности см. В этом обсуждении).

Лучше явно перечислить каждый файл, который вы хотите включить в свою цель.

Обратите внимание: если у вас есть исходные файлы в нескольких отдельных каталогах, но все они принадлежат одной и той же логической цели, тогда вам не нужен CMakeLists.txt файл для каждого каталога - просто укажите подкаталог в имени файла.

Пример:

foo/
+--- foo.c
+--- bar.c
+--- baz/
     +--- baz.c
     +--- bang.c

Если вам нужна одна цель foo для всех вышеупомянутых файлов, вы должны создать ее следующим образом:

add_library(foo 
   foo.c
   bar.c
   baz/baz.c
   baz/bang.c)

Или, если вы действительно хотите использовать переменную для хранения списка SRCS

set(SRCS 
   foo.c
   bar.c
   baz/baz.c
   baz/bang.c)

add_library(foo ${SRCS})
person Steve Lorimer    schedule 07.11.2017
comment
Спасибо Стиву за подробное разъяснение. Теперь для меня это намного яснее. Теперь мне есть с чего начать, вместе с предоставленной вами документацией, надеюсь, я смогу быстро вникнуть в нее. Очень признателен за ваш отзыв. - person Kazi Hasan; 08.11.2017
comment
@Steve: Могу я узнать, на что указывает эта строка project (my_project C)? - person Akshay Raiyani; 04.04.2019
comment
@AkshayRaiyani это определение project - my_project это название проекта (доступен в переменной ${PROJECT_NAME} и используется некоторыми системами сборки, такими как Visual Studio.) C указывает, что этот проект является проектом на языке C (вы также можете использовать, например, CXX для обозначения проекта на языке C ++). Cmake требует, чтобы верхний уровень CMakeLists.txt проекта включал буквальный вызов этого - person Steve Lorimer; 09.04.2019