2010-01-28 14 views
6

En CMake, intento crear un proyecto que incluya bibliotecas para múltiples arquitecturas de procesador diferentes, compiladas por diferentes cadenas de herramientas. Para cada arquitectura, las bibliotecas estáticas se crean en múltiples subdirectorios y luego se recopilan en una biblioteca compartida en el directorio raíz. Hasta ahora, no he podido resolver esto.CMake add_custom_command/_target en diferentes directorios para la compilación cruzada

Lo más cerca que he llegado hasta ahora es utilizar add_custom_command y add_custom_target en los subdirectorios para producir los archivos .a y luego tratar de reunirlas en un .so en el directorio raíz usando add_custom_command y add_custom_target nuevo. Pero si establezco el punto de dependencia .so en la lista de salidas de comando personalizadas, el archivo MAKE dice "No hay regla que hacer ..." porque las salidas de comando personalizadas no se exportan fuera del subdirectorio. Así que intenté hacer que el punto de dependencia .so fuera la lista de objetivos personalizados en el subdirectorio, y se queja de que no puede encontrar un archivo con ese nombre.

Para decirlo en forma de código, esto es lo que tengo en un subdirectorio:

add_custom_command(OUTPUT subout.a COMMAND ${MYAR} ...) 
add_custom_target(subout_target DEPENDS subout.a) 

En el directorio raíz, he intentado esto:

add_custom_command(OUTPUT my.so COMMAND ${MYLD} ... DEPENDS sub/subout.a) 
add_custom_target(dll ALL DEPENDS my.so) 

Y consigo "No hay ninguna regla para hacer el objetivo 'sub/subout.a', que necesita 'my.so'. Detener. " Lo cual tiene sentido porque los destinos add_custom_command no se exportan desde un directorio.

Y he intentado esto:

add_custom_command(OUTPUT my.so COMMAND ${MYLD} ... DEPENDS subout_target) 
add_custom_target(dll ALL DEPENDS my.so) 

Esto realmente hacer que el archivo de sub/subout.a que se genere, pero luego se muere, diciendo "No hay ninguna regla para hacer diana 'subout_target' ..."

Creo que lo que realmente quiero es poder imitar el comportamiento add_library para múltiples arquitecturas diferentes. Pero aparentemente, CMake no quiere que haga eso ... :)

¿Alguna idea?

Respuesta

7

Supongo que necesita usar add_dependencies para definir las dependencias entre los destinos definidos usando add_custom_target. La opción DEPENDS se usa para especificar dependencias de nivel de archivo en reglas personalizadas pero no dependencias de nivel de destino.

Por ejemplo, el comando que genera el archivo .obj como salida utiliza DEPENDS para especificarlo depende del archivo .cpp. Además, un objetivo puede depender de un solo archivo, no solo de otros objetivos. Por lo tanto, para las dependencias de nivel de archivo, use la opción DEPENDS, pero add_dependencies para el nivel de destino.

+1

Eso lo arregló por completo. Muchas gracias. Me has ahorrado mucha frustración. – boiler96

+1

¡Estoy contento y bienvenido! – mloskot

1

Spot On!

add_dependencies me permitió crear la dependencia 'enlace' final entre add_custom_target objetivos creados, y add_custom_target genera los objetivos necesarios para obtener add_custom_command para crear contenido real en el makefile, es decir, Mi add_custom_command no generaría salida a los archivos make a menos que el sALIDA 's de la add_custom_command se especificaron como dependencias en el add_custom_target comando.

luego a que los add_custom_command 's que se ejecutan en el orden correcto, tuve que usar los nombres de destinatarios definidos en el add_custom_target' s como dependencias en las add_dependencies. NOTA: El SALIDA 's especificado en el add_custom_command y add_custom_target comandos tuvieron que ser especificado en los caminos indicados por separado, es decir:

add_custom_command(OUTPUT "out1 out2 out3" ...) # WRONG! 
add_custom_target(CUSTOMTARG1 "out1 out2 out3") # WRONG! 

add_custom_command(OUTPUT "out1" "out2" "out3" ...) # RIGHT! 
add_custom_target(CUSTOMTARG1 "out1" "out2" "out3") # RIGHT! 

Si yo no tenía por sendas separadas citados, el archivo MAKE construyó las salidas todas las veces, independientemente de si existían o no.

+0

probablemente interpretó "out1 out2 out3" como un solo archivo con espacios en el nombre. Como su regla no genera ese archivo, make siempre lo ejecutará. – Penz

Cuestiones relacionadas