2011-06-16 10 views
8

Quiero agregar un objetivo de prueba que depende de la totalidad del proyecto que se está creando correctamente, sin volver a especificar las dependencias en todas las bibliotecas o ejecutables.CMake add_custom_target dependiendo de todo el proyecto que se está creando

que iba a escribir esto en maquillaje como:

all: foo bar 

foo: ... 
bar: ... 

test: all 
    test.sh 

test.sh utiliza implícitamente foo y bar y quiere que estén al día.

Así es como esperaría especificar esto en cmake.

add_library(foo ...) 
add_executable(bar ...) 

add_custom_target(test test.sh 
       DEPENDS all 
) 

Sin embargo, esto no funciona ya que no hay todos los objetivos.

¿Hay alguna manera de especificar esto? ¿O hay una variable que se expande a todos los objetivos que intento construir?

Respuesta

9

A partir de la versión 2.8 CMake no proporciona una variable que contenga una lista de todos los destinos. Lo mejor que puede hacer es anular los comandos integrados add_library y add_executable con macros personalizadas que llaman a los integrados y realizar un seguimiento de todos los destinos definidos en una variable.

Incluso puede usar los mismos nombres para sus macros personalizadas. De esta forma, no es necesario realizar cambios en todas las llamadas existentes add_library y add_executable. Los originales comandos internos tienen el prefijo con un guión si reemplaza cualquiera de ellos:

set (_allTargets "") 

macro(add_library _target) 
    _add_library (${_target} ${ARGN}) 
    list (APPEND _allTargets ${_target}) 
endmacro() 

macro(add_executable _target) 
    _add_executable (${_target} ${ARGN}) 
    list (APPEND _allTargets ${_target}) 
endmacro() 

add_library(liba STATIC liba.cpp) 
add_executable(main liba main.cpp) 

add_custom_target(test "${CMAKE_CURRENT_SOURCE_DIR}/test.sh") 

add_dependencies(test ${_allTargets}) 

También tenga en cuenta que no se puede agregar una dependencia de destino para un objetivo personalizado con la opción DEPENDS. DEPENDS solo puede hacer referencia a archivos existentes o archivos generados con add_custom_command(...) en el mismo directorio. Para agregar una dependencia de destino use el comando add_dependencies en su lugar.

0

Es posible utilizar CTest:

include(CTest) 
if (BUILD_TESTING) 
    add_test(MyTestName test.sh param1 param2) 
endif(BUILD_TESTING) 

Cmake generará Makefile con el nuevo objetivo prueba, véase también: Documentation for add_test command.

pero hay que compilar el proyecto, antes de las pruebas que se ejecutan:

make 
make test 

Además, se puede utilizar objetivo Experimental, noche o continua. Estos objetivos compilarán el proyecto y ejecutarán todas las pruebas, pero también intentarán enviar los resultados de la prueba (puede configurarlo con CTestConfig.cmake).

+0

Gracias. Intenté usar CTest y no me gustó porque no agregó la dependencia y se comió la salida. Esto puede ser más apropiado si no tuviera una infraestructura de prueba existente. –

4

No tengo la reputación suficiente para comentar sobre la respuesta Sakra ...

Un problema que veo con esta solución es que si se utiliza cualquier subdirectorio de los cambios que haces a los _allTargets variables en el interior no se propagará el subdirectorio al alcance principal

de excavación más, list(append ...) no se pueden utilizar en este caso:

Al igual que en el comando SET, el comando LIST crea nuevas variables valores en el ámbito actual, incluso si la lista en sí es en realidad se define en un alcance principal Para propagar los resultados de estas operaciones hacia arriba, use SET con PARENT_SCOPE, SET con CACHE INTERNAL, o algún otro medio de propagación de valores.

http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:set:

Si PARENT_SCOPE está presente, la variable se encuentra en el alcance por encima del ámbito actual. Cada nuevo directorio o función crea un nuevo alcance . Este comando establecerá el valor de una variable en el directorio principal o en la función de llamada (lo que sea aplicable al caso en cuestión).

(Nota para mí mismo: una macro no es una función)

no veo una solución general (por ejemplo, independiente del uso de add_subdirectory) cuando se utiliza PARENT_SCOPE. Sin embargo, aquí parece haber una solución usando CACHE INTERNAL.

Citando: http://www.cmake.org/pipermail/cmake/2007-November/018109.html

# A macro for passing lists between different directories 
# through an internal cache variable. 
MACRO (APPEND_INTERNAL_LIST LIST_NAME VALUE) 

    # If the list in not in the cache, create it. 
    IF (${LIST_NAME}) 
     SET (${LIST_NAME} "${${LIST_NAME}};${VALUE}" CACHE INTERNAL "Internal 
variable") 
    ELSE (${LIST_NAME}) 
     SET (${LIST_NAME} "${VALUE}" CACHE INTERNAL "Internal variable") 
    ENDIF (${LIST_NAME}) 

ENDMACRO (APPEND_INTERNAL_LIST) 

# A macro for passing lists between different directories 
# through an internal cache variable. 
# This function empties the variable (usually because of older runs) 
MACRO (INITIALIZE_INTERNAL_LIST LIST_NAME) 
    SET (${LIST_NAME} "" CACHE INTERNAL "Internal variable") 
ENDMACRO (INITIALIZE_INTERNAL_LIST) 
Cuestiones relacionadas