2009-01-02 11 views
14

Estoy usando cmake para construir mi proyecto. Para UNIX, me gustaría escribir make desde el directorio raíz de mi proyecto y invocar cmake para crear los Makefiles correctos (si aún no existen) y luego crear mi proyecto. Me gustaría que los archivos "internos" cmake (archivos de objeto, archivos Makefiles internos cmake, etc.) estén ocultos (por ejemplo, ponerlos en un directorio .build) para que no ocupen mi directorio de proyectos.¿Llamar a cmake desde make para crear Makefiles?

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, escriba make y esto ocurra) para cada subproyecto ejecute cmake (como se indica anteriormente) y cree solo ese subproyecto (con dependencias, para que la biblioteca se genere a 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 un poco bien el proyecto principal, aunque se siente un poco hackish. No puedo crear objetivos específicos utilizándolo, porque mi Makefile simplemente llama al make en el directorio de compilación de cmake.

Tenga en cuenta que debido a que la biblioteca es la única dependencia (y probablemente no es necesario compilar manualmente, y porque soy floja) 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 [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} ..) 

Si ayuda, aquí es mi estructura del proyecto (si esto es "equivocado" por favor, dime - 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 no ha cogido todavía , Básicamente busco 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!

Respuesta

8

Si cmake está generando los archivos make, sólo tiene que incluir el makefile generado en el makefile maestro, por ejemplo

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

La incluía archivos se generan a continuación, hacer que se reinicie con los nuevos archivos incluidos. Los archivos incluidos deben detallar los objetivos, etc.

Debe poder cambiar la ubicación de los archivos usados ​​utilizando la directiva vpath, consulte p. Ej. la Gnu make manual,

vpath %.o project/.build 

demás la forma tediosa es reescribir las reglas tomando nota del directorio necesario.

Ed: Quizás 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 $ (HAZ) -f $ (GUI-MAKE) todas las obras de comando en la línea de comandos, y nos hemos escondido 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.

Propagación de archivos de objetos a través debe implicar algo así como

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

aunque probablemente obtendrá errores tratando de hacer que los objetos de prueba

+0

Wow! ¡Ni siquiera pensé en eso! Sin embargo, hay un problema: el Makefile incluido ($ GENERATED) espera un pwd/$ CUR_DIR diferente del dir del proyecto (cree que está en project/.build). Cualquier forma de arreglar esto? – strager

+0

No creo que pueda cambiar el directorio de trabajo entre reglas, sin embargo, he agregado una nota en vpath, que debería permitirle encontrar sus archivos de objetos, etc. en el lugar correcto. – cramsin

+0

Recibo el siguiente error, sin vpath: make [1]: CMakeFiles/Makefile2: No existe dicho archivo o directorio. Es causado por la invocación de Makefile generada por cmake: $ (MAKE) -f CMakeFiles/Makefile2 all. CMakeFiles es un subdirectorio en mi directorio de compilación. [continued ...] – strager