it-swarm.com.ru

Рекурсивный поиск CMake для заголовочных и исходных файлов

Я новичок в CMake и хотел бы спросить, может ли кто-нибудь помочь в следующей проблеме. 

У меня есть исходные и заголовочные файлы C++ в соответствующих папках, и теперь я хочу создать текстовый файл CMake, который их рекурсивно ищет. 

В настоящее время я делаю это следующим образом: 

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(CarDetectorDAISY)

file(GLOB_RECURSE SRCS *.cpp)
file(GLOB_RECURSE HDRS *.h)

ADD_EXECUTABLE(stereo_framework  ${SRCS} ${HDRS})
TARGET_LINK_LIBRARIES(stereo_framework) 

Это создает мой CarDetectorDAISY.sln файл решения, и когда я пытаюсь его построить, он показывает Ошибку, что заголовочные файлы не найдены (нет такого файла или каталога). 

Буду очень признателен, если кто-нибудь сможет мне помочь. Благодарю.

16
Sanchit

Возможно, вам не хватает одного или нескольких include_directories звонков. Добавление заголовков в список файлов в вызове add_executable фактически не добавляет их в путь поиска компилятора - это удобная функция, благодаря которой они добавляются только в структуру папок проекта в IDE.

Итак, в вашем корне, скажем, у вас есть /my_lib/foo.h, и вы хотите включить его в исходный файл как

#include "my_lib/foo.h"

Затем в вашем CMakeLists.txt вам нужно сделать:

include_directories(${CMAKE_SOURCE_DIR})

Если вместо этого вы просто хотите сделать

#include "foo.h"

затем в CMakeLists.txt, сделать

include_directories(${CMAKE_SOURCE_DIR}/my_lib)


Я должен упомянуть, что file(GLOB...) не рекомендуемый способ собрать список источников - вам просто нужно явно добавить каждый файл в CMakeLists.txt. Таким образом, если вы добавите или удалите исходный файл позже, CMakeLists.txt будет изменен, и CMake автоматически перезапустится при следующей попытке сборки. Из документов для file:

Мы не рекомендуем использовать GLOB для сбора списка исходных файлов из вашего исходного дерева. Если файл CMakeLists.txt не изменяется при добавлении или удалении источника, то сгенерированная система сборки не может знать, когда попросить CMake сгенерировать заново.

21
Fraser

Просто для дальнейшего разъяснения одного пункта в ответе Фрейзера:

Заголовки не должны передаваться в ADD_EXECUTABLE.

Причина в том, что предполагаемая команда компиляции в Linux, например, просто:

gcc main.c mylib.c

и не:

gcc main.c mylib.c mylib.h

Затем препроцессор C анализирует mylib.c и видит #include "mylib.h" и использует свой путь поиска для этих файлов.

Вместо этого, используя include_directories, мы изменяем путь поиска препроцессора cpp, что является правильным подходом. В GCC это означает добавление флага -I в командную строку:

gcc -Inew/path/to/search/for/headers main.c mylib.c