2015-02-10 6 views
8

मैं एक पुस्तकालय गैर स्रोत फ़ाइलों की सामग्री (इस मामले, ओपन शेडर कोड में) से इंजेक्शन कुछ निरंतर डेटा ले जाने की जरूरत है के साथ पुस्तकालय। इस लक्ष्य को हासिल करने के लिए, मैं add_custom_command() उपयोग कर रहा हूँ उत्पन्न करने के लिए फ़ाइलों है कि मैं तो #include मेरी कोड में स्थिरांक स्थैतिक चर प्रारंभ करने में कर सकते हैं शामिल हैं।CMake: हेडर-केवल उत्पन्न फ़ाइलों

यह नियमित पुस्तकालयों (स्थिर या साझा) के साथ पूरी तरह से काम करता है, लेकिन अब मैं अपने पुस्तकालय हेडर केवल करना चाहते हैं। सी की क्षमता ++ स्थिर तरीकों जाने के लिए कि डेटा प्रत्येक अनुवाद इकाई ("जादू स्टैटिक्स") में दोहराया होने का खतरा चलने के बिना स्थिर डेटा लौट यह संभव है।

समस्या यह है कि सीएमके को लगता है कि एक इंटरफेस लाइब्रेरी (जो कि सीएमके फीचर है जिसे मैं हेडर-केवल पुस्तकालय बनाने के लिए उपयोग कर रहा हूं) को भवन की आवश्यकता नहीं है - जो इस मामले में गलत है।

(मुझे एहसास है कि मेरी लाइब्रेरी के लिए केवल वास्तविकता होने के लिए कोई वास्तविक दायित्व नहीं है। इस विशेष मामले में, मुझे यह कारण यह है कि मैं पुस्तकालय चाहता हूं, जो ओपनजीएल कर रहा है, किसी भी से स्वतंत्र रहने के लिए विशिष्ट बाइंडिंग लाइब्रेरी [जैसे कि GLEW या GLee या नवागंतुक glbinding]। मेरी लाइब्रेरी हेडर को केवल रखकर, मैं उस विकल्प को उपयोगकर्ता को छोड़ सकता हूं - उसे केवल #include मेरे पहले बाइंडिंग लाइब्रेरी का शीर्षलेख है।)

किसी CMake हेडर पैदा कस्टम आदेशों को गति प्रदान, नवीनतम पर जब उपभोक्ता प्रोजेक्ट बनाया जा रहा है के लिए एक तरह से देख रहा है?

संपादित करें: मैं बस महसूस किया कि मैं "दोनों दुनिया का सबसे अच्छा" हो सकता है के रूप में यह मेरी लाइब्रेरी स्थिर मेरे सारे कोड हेडर फाइल में लगातार डेटा के लिए छोड़कर रखने, लेकिन अभी भी जारी रखते हुए थे। इस तरह, एक विशिष्ट ओपनजीएल बाइंडिंग लाइब्रेरी चुनने की अभी भी आवश्यकता नहीं होगी। एक के लिए उपयोग की सादगी - - इसलिए मैं अपने सवाल खुला जा रहा हूँ हालांकि, अभी भी हो रही एक पुस्तकालय हेडर केवल होने का लाभ हैं।

संपादित करें # 2: यहाँ मेरी CMakeLists.txt फ़ाइल के प्रासंगिक हिस्सा है (मैं केवल पुस्तकालय निर्भरता छीन - सभी शीर्ष लेख-केवल - अंत से):

set(SHADER_FILES "src/vertex.glsl" "src/fragment.glsl") 

add_library(libGPCGUIGLRenderer INTERFACE) 
target_sources(libGPCGUIGLRenderer INTERFACE ${SHADER_FILES}) 

target_include_directories(libGPCGUIGLRenderer BEFORE 
    INTERFACE 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> 
    $<INSTALL_INTERFACE:include> 
) 

# Embed shader files 

source_group("Shader files" FILES ${SHADER_FILES}) 

set(GENERATED "${CMAKE_CURRENT_BINARY_DIR}/generated") 
target_include_directories(libGPCGUIGLRenderer INTERFACE ${GENERATED}) 

# Find the GPC Bin2C utility 
find_package(GPCBin2C REQUIRED) 

# Add a custom target and a dependency for each shader file  
foreach(shader ${SHADER_FILES}) 
    get_filename_component(name "${shader}" NAME) 
    set(shader_header "${GENERATED}/${name}.h") 
    add_custom_command(
    OUTPUT ${shader_header} 
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${shader} 
    COMMAND GPCBin2C --input=${CMAKE_CURRENT_SOURCE_DIR}/${shader} --output=${shader_header} 
) 
    target_sources(libGPCGUIGLRenderer INTERFACE ${shader_header}) 
endforeach() 

उत्तर

3

आप को CMake 3.1 में target_sources उपयोग कर सकते हैं इंटरफ़ेस फ़ाइलों को संकलित करने के लिए उपभोक्ताओं को बता:

add_library(source_only INTERFACE) 
target_sources(source_only INTERFACE foo.cpp) 

http://www.cmake.org/cmake/help/v3.1/command/target_sources.html

+1

मैं पहले से ही मेरे इंटरफेस लाइब्रेरी में जेनरेट की गई हेडर फ़ाइलों को जोड़ने के लिए 'target_sources()' का उपयोग कर रहा हूं। लेकिन सीएमके उन्हें उत्पन्न नहीं करता है - स्पष्ट रूप से निर्भरता (और इसे हल करने के लिए कस्टम कमांड) उपभोक्ता को पास नहीं किया जा रहा है। – JPNotADragon

1

मैं तुलनीय समस्याओं में भाग गया जब खुशी है कि उपयोग करने के लिए कोशिश कर रहा है: https://github.com/Dav1dde/glad

यह बाध्यकारी बनाने के लिए एक कस्टम सीएमके कमांड का उपयोग करता है, जिसका मतलब है कि जिन परियोजनाओं को आपको खुशी का उपयोग करने वाली परियोजना में शामिल करने की आवश्यकता है, वे मौजूद नहीं हैं, ताकि सीएमके खुश न हों (जो उन फ़ाइलों को बनाएगा) .. ।

मैं अभी तक यह कोशिश करने के लिए नहीं मिला है, लेकिन नीचे दिए गए लिंक का उदाहरण 3 एक अच्छा समाधान हो रहा है और मैं इसे अपने मामले में काम कर सकते हैं का मानना ​​है: https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/

2

के रूप में हेडर के साथ एक स्थिर पुस्तकालय बनाना एकमात्र स्रोत मेरे लिए काम किया। यह निश्चित रूप से केवल एक काम है।

  • केवल हेडर फाइलों के साथ एक स्थिर लाइब्रेरी बनाना एक खाली लाइब्रेरी में परिणाम देता है। मेरा एकमात्र सामग्री के रूप में !<arch> कहता है।
  • सीएमके स्वचालित रूप से निर्भरताओं को उप-निर्देशिकाओं में सही कर देगा।
  • चूंकि सभी स्रोत शीर्षलेख हैं, इसलिए आपको सीएमके को बताना होगा कि कौन सी लिंकर भाषा का उपयोग किया जाना चाहिए।

कोड: इस तरह अन्य निर्देशिकाओं में

set(OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated_include") 
add_custom_command(
    OUTPUT "${OUTDIR}/outfile.h" 
    # Replace the next two lines with a proper generating script. 
    COMMAND mkdir -p ${OUTDIR} 
    COMMAND touch ${OUTDIR}/outfile.h 
) 

# Note, I am only adding header files to the library. 
add_library(generated-headers STATIC 
    "${OUTDIR}/outfile.h" 
) 
set_target_properties(generated-headers 
    PROPERTIES LINKER_LANGUAGE CXX) 
target_include_directories(generated-headers PUBLIC ${OUTDIR}) 

उपयोग:

# In any other directory of the same CMake project: 
add_executable(main main.cpp) 
target_link_libraries(main generated-headers) 

CMake 3.2, 3.8 और 3.9 पर परीक्षण किया गया। निंजा का उपयोग करना और जेनरेटर बनाना।