Вызвать cmake из make для создания Makefile?

Я использую cmake для создания моего проекта. Для UNIX я хотел бы набрать make из корневого каталога проекта и вызвать cmake для создания правильных Make файлов (если они еще не существуют), а затем построить мой проект. Я бы хотел, чтобы внутренние файлы cmake (объектные файлы, cmake внутренние Make файлы и т.д.) Были скрыты (например, помещены в каталог .build), поэтому он не загромождает мою директорию проекта.

В моем проекте есть несколько подпроектов (в частности, библиотека, исполняемый файл пользователя и исполняемый файл unit test). Я бы хотел, чтобы Makefiles (т.е. я набираю make и это происходит) для каждого подпроекта для выполнения cmake (как указано выше) и строит только этот подпроект (с зависимостями, поэтому библиотека будет построена из исполняемых файлов) Makefiles, если необходимо). Результирующая двоичная (.so библиотека или исполняемый файл) должна находиться в каталоге подпроектов.

Я сделал Makefile, который делает бит проекта немного хорошо, хотя он чувствует себя несколько хакерским. Я не могу использовать конкретные цели, потому что мой Makefile просто вызывает make в каталоге cmake build.

Обратите внимание, что поскольку библиотека является единственной зависимостью (и, вероятно, ее не нужно создавать вручную, а потому, что я ленив), я опустил ее в своем Makefile.

BUILD_DIR   :=  .build

.PHONY: all clean project-gui ${BUILD_DIR}/Makefile

all:    project-gui project-test

clean:
    @([ -d ${BUILD_DIR} ] && make -C ${BUILD_DIR} clean && rm -r ${BUILD_DIR}) || echo Nothing to clean

project-gui:  ${BUILD_DIR}/Makefile
    @make -C ${BUILD_DIR} project-gui
    @cp ${BUILD_DIR}/project-gui/project-gui [email protected]

project-test:  ${BUILD_DIR}/Makefile
    @make -C ${BUILD_DIR} project-test
    @cp ${BUILD_DIR}/project-test/project-test [email protected]

${BUILD_DIR}/Makefile:
    @[ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}
    @[ -f ${BUILD_DIR}/Makefile ] || (cd ${BUILD_DIR} && cmake ${CMAKE_OPTS} ..)

Если это помогает, здесь моя структура проекта (если это "неправильно", пожалуйста, скажите мне - я все еще изучаю cmake):

project/
project/CMakeLists.txt
project/common.cmake
project/Makefile -- see Makefile above for this; should be replaced with something better, building libproject, project-gui, and project-test

project/libproject/
project/libproject/CMakeLists.txt
project/libproject/libproject.so -- after build
project/libproject/Makefile -- doesn't exist yet; should build libproject only
project/libproject/source/
project/libproject/include/

project/project-gui/
project/project-gui/CMakeLists.txt
project/project-gui/Makefile -- doesn't exist yet; should build libproject then project-gui
project/project-gui/source/
project/project-gui/include/

project/project-test/
project/project-test/CMakeLists.txt
project/project-test/Makefile -- doesn't exist yet; should build libproject then project-test
project/project-test/source/
project/project-test/include/

Если вы еще не поймали, я в основном ищу способ создания проекта и подпроектов, как будто cmake не было: как будто мой проект состоял только из Make файлов. Это можно сделать? Является ли решение элегантным или грязным? Должен ли я пытаться сделать что-то еще вместо этого?

Спасибо!

Ответы

Ответ 1

Если cmake генерирует make файлы, вы можете просто включить сгенерированный make файл в мастер файл make, например

# makefile
all:                # Default
include $GENERATED
$GENERATED:$CMAKEFILE
   #  Generate the makefile here`

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

Вы должны иметь возможность изменять местоположение используемых файлов с помощью директивы vpath, см., например, Gnu сделайте руководство,

vpath %.o project/.build

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

Ed: Возможно, нам не следует использовать плоский make файл.

Попробуйте что-то вроде:

# makefile
all: gui test
clean:
    $(MAKE) -f $(GUI-MAKE) clean
    $(MAKE) -f $(TEST-MAKE) clean

gui:$(GUI-MAKE)
    $(MAKE) -f $(GUI-MAKE) all
$(GUI-MAKE):$(GUI-CMAKE)
    # Generate

# Same for test

Это должно работать, если команда команды $(MAKE) -f $(GUI-MAKE) работает в командной строке, и мы скрыли cmake в генерирующей цели. Вам также придется копировать любые другие цели в мастер файл, а также следить за запуском параллельно.

Распространение объектных файлов через должно включать что-то вроде

%.o:$(GUI-MAKE)
    $(MAKE) -f $(GUI-MAKE) [email protected]

хотя вы, вероятно, получите ошибки, пытающиеся создать тестовые объекты