build-process - script - descarga cmake
¿Llamar a cmake desde make para crear Makefiles? (1)
Estoy usando cmake
para construir mi proyecto. Para UNIX, me gustaría escribir make
desde el directorio raíz de mi proyecto, e invocar cmake
para crear los Makefiles correctos (si aún no existen) y luego construir mi proyecto. Me gustaría que los cmake
"internos" de cmake
(archivos de objetos, archivos Makefiles internos de cmake
, etc.) estén ocultos (por ejemplo, ponerlos en un directorio .build
) para que no atenten mi directorio de proyectos.
Mi proyecto tiene varios subproyectos (en particular, una biblioteca, un ejecutable de usuario y un ejecutable de prueba de unidad). Me gustaría que Makefiles (es decir, cmake
make
y esto ocurra) para cada subproyecto ejecute cmake
(como el anterior) y cmake
solo ese subproyecto (con dependencias, para que la biblioteca se cmake
partir de los Makefiles de los ejecutables, si es necesario) ) El binario resultante (biblioteca .so o ejecutable) debe estar en el directorio del subproyecto.
Hice un Makefile que hace bastante bien el proyecto principal, aunque se siente un poco hackish. No puedo construir objetivos específicos utilizándolo, porque mi Makefile simplemente llama a make
en el directorio de construcción de cmake
.
Tenga en cuenta que debido a que la biblioteca es una única dependencia (y probablemente no es necesario compilarla manualmente, y porque soy flojo) la omití en mi 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 $@
project-test: ${BUILD_DIR}/Makefile
@make -C ${BUILD_DIR} project-test
@cp ${BUILD_DIR}/project-test/project-test $@
${BUILD_DIR}/Makefile:
@[ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}
@[ -f ${BUILD_DIR}/Makefile ] || (cd ${BUILD_DIR} && cmake ${CMAKE_OPTS} ..)
Si ayuda, aquí está la estructura de mi proyecto (si esto es "incorrecto", por favor dígame, todavía estoy aprendiendo 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/
Si aún no te has dado cuenta, básicamente estoy buscando una manera de construir el proyecto y los subproyectos como si cmake
no estuviera allí: como si mi proyecto consistiera solo en Makefiles. Se puede hacer esto? ¿Es la solución elegante o desordenada? ¿Debería tratar de hacer otra cosa en su lugar?
¡Gracias!
Si cmake está generando los makefiles, puede simplemente incluir el archivo MAKE generado en el MAKEFLE maestro, por ejemplo
# makefile
all: # Default
include $GENERATED
$GENERATED:$CMAKEFILE
# Generate the makefile here`
Los archivos incluidos se generan y make se reinicia con los nuevos archivos incluidos. Los archivos incluidos deben detallar los objetivos, etc.
Debería poder cambiar la ubicación de los archivos usados utilizando la directiva vpath, consulte, por ejemplo, el manual de Gnu make ,
vpath %.o project/.build
de lo contrario, la forma tediosa es volver a escribir las reglas tomando nota del directorio necesario.
Ed: Tal vez no deberíamos usar un archivo MAKE plano.
Pruebe algo como:
# 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
Esto debería funcionar si el comando $ (MAKE) -f $ (GUI-MAKE) all funciona en la línea de comando, y hemos ocultado cmake en el objetivo de generación. Tendría que copiar cualquier otro objetivo al archivo MAKE maestro también, y tener cuidado ejecutando make en paralelo.
La propagación de archivos de objetos a través debe involucrar algo como
%.o:$(GUI-MAKE)
$(MAKE) -f $(GUI-MAKE) $@
aunque probablemente obtendrá errores al intentar hacer objetos de prueba