2012-06-06 3 views
21

CMake documentation явно заявляет, что file(GLOB ...) не является Рекомендуется собирать исходные файлы для сборки, но не упоминает, что такое рекомендуемый метод на самом деле.Как собрать исходные файлы с CMake без globbing?

Задание каждого исходного файла вручную звучит немного слишком вручную для меня. Итак, какой правильный способ собирать исходные файлы, если не file(GLOB ...)?

+0

Вы можете использовать Глоб из CMake в сценарии и есть, что добавить выливать имена файлов. – Damian

ответ

17

Руководство действительно рекомендуемый метод. Рекомендуя отказаться от использования GLOB, документация просто предупреждает систему сборки, которая зависит от присутствующих файлов. Например, вы хотите добавить тестовый исполняемый файл, поэтому вы создаете mytest.cpp. К сожалению. Теперь ваша компиляция библиотеки ломается. Документация AUX_SOURCE_DIRECTORY (аналогичные цели, как подстановка для исходных файлов) дает следующее предупреждение:

Заманчиво использовать эту команду, чтобы избежать написания списка источника файлов для библиотеки или исполняемого файла цели. Хотя это, похоже, работает, не существует способа для CMake для создания системы сборки, которая знает, когда был добавлен новый исходный файл . Обычно сгенерированная система сборки знает, когда ей нужно перезапустить CMake, потому что файл CMakeLists.txt имеет значение , чтобы добавить новый источник. Когда источник просто добавлен в каталог , не изменяя этот файл, нужно было бы вручную перезапустить CMake для создания системы сборки, включающей новый файл.

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

Кроме того, не забудьте перечислить файлы вручную, не обязательно включать в себя ввод всех имен файлов. Вы можете сделать, например, ls *.cpp >> CMakeLists.txt, а затем использовать свой редактор, чтобы переместить список файлов в нужное место в файле.

+0

Вид зависит от IDE tbh. В Qt Creator он всегда перезапускает CMake, поэтому использование GLOB не является проблемой. – Lap

+2

'printf 'add_library (xxx $ (ls * .cpp))" >> CMakeLists.txt' тоже должно быть хорошо! – Alex

+0

Я не думаю, что ваше усложнение является допустимым, потому что тест обычно находится в тестовой папке и не должен загромождать исходное дерево. – Arne

12

Я использую Глоб именно для этого и каждый раз, когда я добавить файл бегаю

touch ../src/CMakeLists.txt 

Следующая make команда будет повторно сканировать каталоги.

«CMake не может создать систему сборки, которая знает, когда был добавлен новый исходный файл« Действительно? Хорошо, так сказать!

Это не 100% автоматический, а проклятый взгляд легче, чем добавление файлов вручную.

1

Я использую cog, модуль python. Вот пример для сбора .cpp файла:

The CMakeLists.txt:

set(SRC_FILES "") 

# [[[cog 
# import cog, glob 
# for src in glob.glob('*.cpp'): 
#  if "skeleton" in src: continue 
#  cog.outl("SET(SRC_FILES ${SRC_FILES} %s)" % src) 
# ]]] 
# [[[end]]] 

add_library(mylib STATIC ${SRC_FILES}) 

И затем запустите:

python -m cogapp -r CMakeLists.txt 

CMakeLists.txt файл будет обновлен на месте.

Для установки винчестера и другого использования, пожалуйста, прочтите the article from the author.

0

Я использую обычный CMakeLists.txt и скрипт python для его обновления. Я запускаю скрипт python вручную после добавления файлов.

import os 
import re  

def relFiles(base, sub): 
    fullSub = os.path.join(base,sub) 
    abs = [os.path.join(dp, f) for dp, dn, fn in os.walk(fullSub) for f in fn] 
    return [os.path.relpath(f, base) for f in abs] 

def updateAddLibrary(cmakelistsDir, subs): 
    cmakelists = os.path.join(cmakelistsDir, "CMakeLists.txt") 
    listings = [relFiles(cmakelistsDir, sub) for sub in subs] 
    files = [f for listing in listings for f in listing] #flatten 
    with open(cmakelists, 'r') as file: 
     text = file.read() 
    sources = "".join([" %s\n" % f.replace('\\', '/') for f in files]) 
    text = re.sub(r"add_library\s*\(\s*([^\s\)]+).*?\)", 
      r"add_library(\1\n%s)" % sources, 
      text, 1, re.DOTALL) 
    with open(cmakelists, "w") as file: 
     file.write(text) 

dir = os.path.dirname(os.path.abspath(__file__)) 
updateAddLibrary(dir, ['inc','src']) 

Пример перед:

... 
add_library(MyLib 
    inc/a.h 
) 
... 

после:

... 
add_library(MyLib 
    inc/a.h 
    inc/sub/b.h 
    src/a.cpp 
)   
... 
Смежные вопросы