2011-06-16 12 views
8

मैं एक परीक्षण लक्ष्य जोड़ना चाहता हूं जो पूरे पुस्तकालयों या निष्पादन योग्यताओं पर निर्भरताओं को फिर से निर्दिष्ट किए बिना पूरी तरह से निर्मित एक परियोजना पर निर्भर है।सीएमके add_custom_target पूरे प्रोजेक्ट के निर्माण के आधार पर

मैं के रूप में कर में यह लिख होगा:

all: foo bar 

foo: ... 
bar: ... 

test: all 
    test.sh 

test.sh परोक्ष foo और बार का उपयोग करता है और तारीख तक होने के लिए उन्हें चाहता है।

इस प्रकार मैं इसे सेमेक में निर्दिष्ट करने की अपेक्षा करता हूं।

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

add_custom_target(test test.sh 
       DEPENDS all 
) 

हालांकि यह काम नहीं करता है क्योंकि कोई लक्ष्य नहीं है।

क्या यह निर्दिष्ट करने का कोई तरीका है? या क्या कोई वैरिएबल है जो उन सभी लक्ष्यों तक फैलता है जिन्हें मैं बनाने की कोशिश कर रहा हूं?

उत्तर

9

संस्करण 2.8 के रूप में सीएमके एक चर प्रदान नहीं करता है जिसमें सभी लक्ष्यों की एक सूची होती है। सबसे अच्छा आप अंतर्निहित कमांड add_library और add_executable को कस्टम मैक्रोज़ के साथ ओवरराइड करना चाहते हैं जो अंतर्निहित कॉल को कॉल करते हैं और एक चर में सभी निर्धारित लक्ष्यों का ट्रैक रखते हैं।

आप अपने कस्टम मैक्रोज़ के लिए भी वही नाम उपयोग कर सकते हैं। इस तरह आपको सभी मौजूदा add_library और add_executable कॉल में परिवर्तन करने की आवश्यकता नहीं है। मूल में निर्मित आदेशों एक अंडरस्कोर लगी होती हैं, तो आप उनमें से किसी को ओवरराइड:

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}) 

भी ध्यान रखें कि आप नहीं DEPENDS विकल्प के साथ एक कस्टम लक्ष्य करने के लिए एक लक्ष्य निर्भरता जोड़ सकते हैं। DEPENDS केवल उसी निर्देशिका में add_custom_command(...) के साथ उत्पन्न मौजूदा फ़ाइलों या फ़ाइलों का संदर्भ दे सकता है। लक्ष्य निर्भरता जोड़ने के लिए add_dependencies कमांड का उपयोग करें।

0

आप CTest उपयोग कर सकते हैं:

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

CMake नया लक्ष्य परीक्षण साथ Makefile उत्पन्न होगा, यह भी देखें: Documentation for add_test command

लेकिन आपके द्वारा चलाए जा परीक्षण से पहले अपनी परियोजना को संकलित करने, की जरूरत है:

make 
make test 

इसके अलावा, आप लक्ष्य प्रायोगिक, रात, या सतत उपयोग कर सकते हैं। ये लक्ष्य परियोजना संकलित करेंगे और सभी परीक्षण चलाएंगे, लेकिन वे परीक्षा परिणाम जमा करने का भी प्रयास करते हैं (आप इसे CTestConfig.cmake से कॉन्फ़िगर कर सकते हैं)।

+0

धन्यवाद। मैंने सीटीएस्ट का उपयोग करने की कोशिश की और इसे पसंद नहीं किया क्योंकि यह निर्भरता को जोड़ता नहीं है और आउटपुट खाता है। यदि मेरे पास मौजूदा परीक्षण आधारभूत संरचना नहीं है तो यह अधिक उपयुक्त हो सकता है। –

4

मैं Sakra जवाब पर टिप्पणी करने के लिए पर्याप्त नहीं प्रतिष्ठा है ...

एक समस्या यह है मुझे लगता है कि समाधान के साथ देख सकते हैं कि अगर आप किसी भी उपनिर्देशिका परिवर्तन का उपयोग आप चर _allTargets करने के लिए क्या है अंदर उपनिर्देशिका प्रचारित नहीं किया जाएगा माता-पिता के दायरे में।

अधिक खुदाई, list(append ...) इस मामले में नहीं किया जा सकता:

सेट कमांड के समान है, सूची आदेश वर्तमान क्षेत्र में नए चर मूल्यों बनाता है, भले ही सूची ही वास्तव में में परिभाषित किया गया है एक माता पिता का दायरा इन संचालन के परिणामों को प्रचारित करने के लिए, PARENT_SCOPE के साथ एसईटी का उपयोग करें, सीएसीई इंटरनल, या मूल्य प्रसार के कुछ अन्य साधनों के साथ सेट करें।

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

तो PARENT_SCOPE मौजूद है, चर वर्तमान क्षेत्र ऊपर दिए गए क्षेत्र में स्थापित किया जाएगा। प्रत्येक नई निर्देशिका या फ़ंक्शन नया स्कोप बनाता है। यह आदेश एक चर के मान को मूल निर्देशिका या कॉलिंग फ़ंक्शन (जो भी मामले पर लागू होता है) में सेट करेगा।

(खुद के लिए ध्यान दें: एक मैक्रो नहीं एक समारोह है)

मैं एक सामान्य समाधान (जैसे add_subdirectory का उपयोग करने से स्वतंत्र) नहीं दिख रहा है जब PARENT_SCOPE का उपयोग कर। हालांकि, यहां कैच इंटरनल का उपयोग करके एक समाधान प्रतीत होता है।

से हवाला देते हुए: 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) 
संबंधित मुद्दे