Warning, /sdk/kshim/cmake/cmakerc/CMakeRC.cmake is written in an unsupported language. File is not indexed.
0001 # This block is executed when generating an intermediate resource file, not when 0002 # running in CMake configure mode 0003 if(_CMRC_GENERATE_MODE) 0004 # Read in the digits 0005 file(READ "${INPUT_FILE}" bytes HEX) 0006 # Format each pair into a character literal. Heuristics seem to favor doing 0007 # the conversion in groups of five for fastest conversion 0008 string(REGEX REPLACE "(..)(..)(..)(..)(..)" "'\\\\x\\1','\\\\x\\2','\\\\x\\3','\\\\x\\4','\\\\x\\5'," chars "${bytes}") 0009 # Since we did this in groups, we have some leftovers to clean up 0010 string(LENGTH "${bytes}" n_bytes2) 0011 math(EXPR n_bytes "${n_bytes2} / 2") 0012 math(EXPR remainder "${n_bytes} % 5") # <-- '5' is the grouping count from above 0013 set(cleanup_re "$") 0014 set(cleanup_sub ) 0015 while(remainder) 0016 set(cleanup_re "(..)${cleanup_re}") 0017 set(cleanup_sub "'\\\\x\\${remainder}',${cleanup_sub}") 0018 math(EXPR remainder "${remainder} - 1") 0019 endwhile() 0020 if(NOT cleanup_re STREQUAL "$") 0021 string(REGEX REPLACE "${cleanup_re}" "${cleanup_sub}" chars "${chars}") 0022 endif() 0023 string(CONFIGURE [[ 0024 namespace { const char file_array[] = { @chars@ 0 }; } 0025 namespace cmrc { namespace @NAMESPACE@ { namespace res_chars { 0026 extern const char* const @SYMBOL@_begin = file_array; 0027 extern const char* const @SYMBOL@_end = file_array + @n_bytes@; 0028 }}} 0029 ]] code) 0030 file(WRITE "${OUTPUT_FILE}" "${code}") 0031 # Exit from the script. Nothing else needs to be processed 0032 return() 0033 endif() 0034 0035 set(_version 2.0.0) 0036 0037 cmake_minimum_required(VERSION 3.12) 0038 include(CMakeParseArguments) 0039 0040 if(COMMAND cmrc_add_resource_library) 0041 if(NOT DEFINED _CMRC_VERSION OR NOT (_version STREQUAL _CMRC_VERSION)) 0042 message(WARNING "More than one CMakeRC version has been included in this project.") 0043 endif() 0044 # CMakeRC has already been included! Don't do anything 0045 return() 0046 endif() 0047 0048 set(_CMRC_VERSION "${_version}" CACHE INTERNAL "CMakeRC version. Used for checking for conflicts") 0049 0050 set(_CMRC_SCRIPT "${CMAKE_CURRENT_LIST_FILE}" CACHE INTERNAL "Path to CMakeRC script") 0051 0052 function(_cmrc_normalize_path var) 0053 set(path "${${var}}") 0054 file(TO_CMAKE_PATH "${path}" path) 0055 while(path MATCHES "//") 0056 string(REPLACE "//" "/" path "${path}") 0057 endwhile() 0058 string(REGEX REPLACE "/+$" "" path "${path}") 0059 set("${var}" "${path}" PARENT_SCOPE) 0060 endfunction() 0061 0062 get_filename_component(_inc_dir "${CMAKE_BINARY_DIR}/_cmrc/include" ABSOLUTE) 0063 set(CMRC_INCLUDE_DIR "${_inc_dir}" CACHE INTERNAL "Directory for CMakeRC include files") 0064 # Let's generate the primary include file 0065 file(MAKE_DIRECTORY "${CMRC_INCLUDE_DIR}/cmrc") 0066 set(hpp_content [==[ 0067 #ifndef CMRC_CMRC_HPP_INCLUDED 0068 #define CMRC_CMRC_HPP_INCLUDED 0069 0070 #include <cassert> 0071 #include <functional> 0072 #include <iterator> 0073 #include <list> 0074 #include <map> 0075 #include <mutex> 0076 #include <string> 0077 #include <system_error> 0078 #include <type_traits> 0079 0080 #if !(defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) || defined(CMRC_NO_EXCEPTIONS)) 0081 #define CMRC_NO_EXCEPTIONS 1 0082 #endif 0083 0084 namespace cmrc { namespace detail { struct dummy; } } 0085 0086 #define CMRC_DECLARE(libid) \ 0087 namespace cmrc { namespace detail { \ 0088 struct dummy; \ 0089 static_assert(std::is_same<dummy, ::cmrc::detail::dummy>::value, "CMRC_DECLARE() must only appear at the global namespace"); \ 0090 } } \ 0091 namespace cmrc { namespace libid { \ 0092 cmrc::embedded_filesystem get_filesystem(); \ 0093 } } static_assert(true, "") 0094 0095 namespace cmrc { 0096 0097 class file { 0098 const char* _begin = nullptr; 0099 const char* _end = nullptr; 0100 0101 public: 0102 using iterator = const char*; 0103 using const_iterator = iterator; 0104 iterator begin() const noexcept { return _begin; } 0105 iterator cbegin() const noexcept { return _begin; } 0106 iterator end() const noexcept { return _end; } 0107 iterator cend() const noexcept { return _end; } 0108 std::size_t size() const { return static_cast<std::size_t>(std::distance(begin(), end())); } 0109 0110 file() = default; 0111 file(iterator beg, iterator end) noexcept : _begin(beg), _end(end) {} 0112 }; 0113 0114 class directory_entry; 0115 0116 namespace detail { 0117 0118 class directory; 0119 class file_data; 0120 0121 class file_or_directory { 0122 union _data_t { 0123 class file_data* file_data; 0124 class directory* directory; 0125 } _data; 0126 bool _is_file = true; 0127 0128 public: 0129 explicit file_or_directory(file_data& f) { 0130 _data.file_data = &f; 0131 } 0132 explicit file_or_directory(directory& d) { 0133 _data.directory = &d; 0134 _is_file = false; 0135 } 0136 bool is_file() const noexcept { 0137 return _is_file; 0138 } 0139 bool is_directory() const noexcept { 0140 return !is_file(); 0141 } 0142 const directory& as_directory() const noexcept { 0143 assert(!is_file()); 0144 return *_data.directory; 0145 } 0146 const file_data& as_file() const noexcept { 0147 assert(is_file()); 0148 return *_data.file_data; 0149 } 0150 }; 0151 0152 class file_data { 0153 public: 0154 const char* begin_ptr; 0155 const char* end_ptr; 0156 file_data(const file_data&) = delete; 0157 file_data(const char* b, const char* e) : begin_ptr(b), end_ptr(e) {} 0158 }; 0159 0160 inline std::pair<std::string, std::string> split_path(const std::string& path) { 0161 auto first_sep = path.find("/"); 0162 if (first_sep == path.npos) { 0163 return std::make_pair(path, ""); 0164 } else { 0165 return std::make_pair(path.substr(0, first_sep), path.substr(first_sep + 1)); 0166 } 0167 } 0168 0169 struct created_subdirectory { 0170 class directory& directory; 0171 class file_or_directory& index_entry; 0172 }; 0173 0174 class directory { 0175 std::list<file_data> _files; 0176 std::list<directory> _dirs; 0177 std::map<std::string, file_or_directory> _index; 0178 0179 using base_iterator = std::map<std::string, file_or_directory>::const_iterator; 0180 0181 public: 0182 0183 directory() = default; 0184 directory(const directory&) = delete; 0185 0186 created_subdirectory add_subdir(std::string name) & { 0187 _dirs.emplace_back(); 0188 auto& back = _dirs.back(); 0189 auto& fod = _index.emplace(name, file_or_directory{back}).first->second; 0190 return created_subdirectory{back, fod}; 0191 } 0192 0193 file_or_directory* add_file(std::string name, const char* begin, const char* end) & { 0194 assert(_index.find(name) == _index.end()); 0195 _files.emplace_back(begin, end); 0196 return &_index.emplace(name, file_or_directory{_files.back()}).first->second; 0197 } 0198 0199 const file_or_directory* get(const std::string& path) const { 0200 auto pair = split_path(path); 0201 auto child = _index.find(pair.first); 0202 if (child == _index.end()) { 0203 return nullptr; 0204 } 0205 auto& entry = child->second; 0206 if (pair.second.empty()) { 0207 // We're at the end of the path 0208 return &entry; 0209 } 0210 0211 if (entry.is_file()) { 0212 // We can't traverse into a file. Stop. 0213 return nullptr; 0214 } 0215 // Keep going down 0216 return entry.as_directory().get(pair.second); 0217 } 0218 0219 class iterator { 0220 base_iterator _base_iter; 0221 base_iterator _end_iter; 0222 public: 0223 using value_type = directory_entry; 0224 using difference_type = std::ptrdiff_t; 0225 using pointer = const value_type*; 0226 using reference = const value_type&; 0227 using iterator_category = std::input_iterator_tag; 0228 0229 iterator() = default; 0230 explicit iterator(base_iterator iter, base_iterator end) : _base_iter(iter), _end_iter(end) {} 0231 0232 iterator begin() const noexcept { 0233 return *this; 0234 } 0235 0236 iterator end() const noexcept { 0237 return iterator(_end_iter, _end_iter); 0238 } 0239 0240 inline value_type operator*() const noexcept; 0241 0242 bool operator==(const iterator& rhs) const noexcept { 0243 return _base_iter == rhs._base_iter; 0244 } 0245 0246 bool operator!=(const iterator& rhs) const noexcept { 0247 return !(*this == rhs); 0248 } 0249 0250 iterator& operator++() noexcept { 0251 ++_base_iter; 0252 return *this; 0253 } 0254 0255 iterator operator++(int) noexcept { 0256 auto cp = *this; 0257 ++_base_iter; 0258 return cp; 0259 } 0260 }; 0261 0262 using const_iterator = iterator; 0263 0264 iterator begin() const noexcept { 0265 return iterator(_index.begin(), _index.end()); 0266 } 0267 0268 iterator end() const noexcept { 0269 return iterator(); 0270 } 0271 }; 0272 0273 inline std::string normalize_path(std::string path) { 0274 while (path.find("/") == 0) { 0275 path.erase(path.begin()); 0276 } 0277 while (!path.empty() && (path.rfind("/") == path.size() - 1)) { 0278 path.pop_back(); 0279 } 0280 auto off = path.npos; 0281 while ((off = path.find("//")) != path.npos) { 0282 path.erase(path.begin() + static_cast<std::string::difference_type>(off)); 0283 } 0284 return path; 0285 } 0286 0287 using index_type = std::map<std::string, const cmrc::detail::file_or_directory*>; 0288 0289 } // detail 0290 0291 class directory_entry { 0292 std::string _fname; 0293 const detail::file_or_directory* _item; 0294 0295 public: 0296 directory_entry() = delete; 0297 explicit directory_entry(std::string filename, const detail::file_or_directory& item) 0298 : _fname(filename) 0299 , _item(&item) 0300 {} 0301 0302 const std::string& filename() const & { 0303 return _fname; 0304 } 0305 std::string filename() const && { 0306 return std::move(_fname); 0307 } 0308 0309 bool is_file() const { 0310 return _item->is_file(); 0311 } 0312 0313 bool is_directory() const { 0314 return _item->is_directory(); 0315 } 0316 }; 0317 0318 directory_entry detail::directory::iterator::operator*() const noexcept { 0319 assert(begin() != end()); 0320 return directory_entry(_base_iter->first, _base_iter->second); 0321 } 0322 0323 using directory_iterator = detail::directory::iterator; 0324 0325 class embedded_filesystem { 0326 // Never-null: 0327 const cmrc::detail::index_type* _index; 0328 const detail::file_or_directory* _get(std::string path) const { 0329 path = detail::normalize_path(path); 0330 auto found = _index->find(path); 0331 if (found == _index->end()) { 0332 return nullptr; 0333 } else { 0334 return found->second; 0335 } 0336 } 0337 0338 public: 0339 explicit embedded_filesystem(const detail::index_type& index) 0340 : _index(&index) 0341 {} 0342 0343 file open(const std::string& path) const { 0344 auto entry_ptr = _get(path); 0345 if (!entry_ptr || !entry_ptr->is_file()) { 0346 #ifdef CMRC_NO_EXCEPTIONS 0347 fprintf(stderr, "Error no such file or directory: %s\n", path.c_str()); 0348 abort(); 0349 #else 0350 throw std::system_error(make_error_code(std::errc::no_such_file_or_directory), path); 0351 #endif 0352 } 0353 auto& dat = entry_ptr->as_file(); 0354 return file{dat.begin_ptr, dat.end_ptr}; 0355 } 0356 0357 bool is_file(const std::string& path) const noexcept { 0358 auto entry_ptr = _get(path); 0359 return entry_ptr && entry_ptr->is_file(); 0360 } 0361 0362 bool is_directory(const std::string& path) const noexcept { 0363 auto entry_ptr = _get(path); 0364 return entry_ptr && entry_ptr->is_directory(); 0365 } 0366 0367 bool exists(const std::string& path) const noexcept { 0368 return !!_get(path); 0369 } 0370 0371 directory_iterator iterate_directory(const std::string& path) const { 0372 auto entry_ptr = _get(path); 0373 if (!entry_ptr) { 0374 #ifdef CMRC_NO_EXCEPTIONS 0375 fprintf(stderr, "Error no such file or directory: %s\n", path.c_str()); 0376 abort(); 0377 #else 0378 throw std::system_error(make_error_code(std::errc::no_such_file_or_directory), path); 0379 #endif 0380 } 0381 if (!entry_ptr->is_directory()) { 0382 #ifdef CMRC_NO_EXCEPTIONS 0383 fprintf(stderr, "Error not a directory: %s\n", path.c_str()); 0384 abort(); 0385 #else 0386 throw std::system_error(make_error_code(std::errc::not_a_directory), path); 0387 #endif 0388 } 0389 return entry_ptr->as_directory().begin(); 0390 } 0391 }; 0392 0393 } 0394 0395 #endif // CMRC_CMRC_HPP_INCLUDED 0396 ]==]) 0397 0398 set(cmrc_hpp "${CMRC_INCLUDE_DIR}/cmrc/cmrc.hpp" CACHE INTERNAL "") 0399 set(_generate 1) 0400 if(EXISTS "${cmrc_hpp}") 0401 file(READ "${cmrc_hpp}" _current) 0402 if(_current STREQUAL hpp_content) 0403 set(_generate 0) 0404 endif() 0405 endif() 0406 file(GENERATE OUTPUT "${cmrc_hpp}" CONTENT "${hpp_content}" CONDITION ${_generate}) 0407 0408 add_library(cmrc-base INTERFACE) 0409 target_include_directories(cmrc-base INTERFACE $<BUILD_INTERFACE:${CMRC_INCLUDE_DIR}>) 0410 # Signal a basic C++11 feature to require C++11. 0411 target_compile_features(cmrc-base INTERFACE cxx_nullptr) 0412 set_property(TARGET cmrc-base PROPERTY INTERFACE_CXX_EXTENSIONS OFF) 0413 add_library(cmrc::base ALIAS cmrc-base) 0414 0415 function(cmrc_add_resource_library name) 0416 set(args ALIAS NAMESPACE TYPE) 0417 cmake_parse_arguments(ARG "" "${args}" "" "${ARGN}") 0418 # Generate the identifier for the resource library's namespace 0419 set(ns_re "[a-zA-Z_][a-zA-Z0-9_]*") 0420 if(NOT DEFINED ARG_NAMESPACE) 0421 # Check that the library name is also a valid namespace 0422 if(NOT name MATCHES "${ns_re}") 0423 message(SEND_ERROR "Library name is not a valid namespace. Specify the NAMESPACE argument") 0424 endif() 0425 set(ARG_NAMESPACE "${name}") 0426 else() 0427 if(NOT ARG_NAMESPACE MATCHES "${ns_re}") 0428 message(SEND_ERROR "NAMESPACE for ${name} is not a valid C++ namespace identifier (${ARG_NAMESPACE})") 0429 endif() 0430 endif() 0431 set(libname "${name}") 0432 # Check that type is either "STATIC" or "OBJECT", or default to "STATIC" if 0433 # not set 0434 if(NOT DEFINED ARG_TYPE) 0435 set(ARG_TYPE STATIC) 0436 elseif(NOT "${ARG_TYPE}" MATCHES "^(STATIC|OBJECT)$") 0437 message(SEND_ERROR "${ARG_TYPE} is not a valid TYPE (STATIC and OBJECT are acceptable)") 0438 set(ARG_TYPE STATIC) 0439 endif() 0440 # Generate a library with the compiled in character arrays. 0441 string(CONFIGURE [=[ 0442 #include <cmrc/cmrc.hpp> 0443 #include <map> 0444 #include <utility> 0445 0446 namespace cmrc { 0447 namespace @ARG_NAMESPACE@ { 0448 0449 namespace res_chars { 0450 // These are the files which are available in this resource library 0451 $<JOIN:$<TARGET_PROPERTY:@libname@,CMRC_EXTERN_DECLS>, 0452 > 0453 } 0454 0455 namespace { 0456 0457 const cmrc::detail::index_type& 0458 get_root_index() { 0459 static cmrc::detail::directory root_directory_; 0460 static cmrc::detail::file_or_directory root_directory_fod{root_directory_}; 0461 static cmrc::detail::index_type root_index; 0462 root_index.emplace("", &root_directory_fod); 0463 struct dir_inl { 0464 class cmrc::detail::directory& directory; 0465 }; 0466 dir_inl root_directory_dir{root_directory_}; 0467 (void)root_directory_dir; 0468 $<JOIN:$<TARGET_PROPERTY:@libname@,CMRC_MAKE_DIRS>, 0469 > 0470 $<JOIN:$<TARGET_PROPERTY:@libname@,CMRC_MAKE_FILES>, 0471 > 0472 return root_index; 0473 } 0474 0475 } 0476 0477 cmrc::embedded_filesystem get_filesystem() { 0478 static auto& index = get_root_index(); 0479 return cmrc::embedded_filesystem{index}; 0480 } 0481 0482 } // @ARG_NAMESPACE@ 0483 } // cmrc 0484 ]=] cpp_content @ONLY) 0485 get_filename_component(libdir "${CMAKE_CURRENT_BINARY_DIR}/__cmrc_${name}" ABSOLUTE) 0486 get_filename_component(lib_tmp_cpp "${libdir}/lib_.cpp" ABSOLUTE) 0487 string(REPLACE "\n " "\n" cpp_content "${cpp_content}") 0488 file(GENERATE OUTPUT "${lib_tmp_cpp}" CONTENT "${cpp_content}") 0489 get_filename_component(libcpp "${libdir}/lib.cpp" ABSOLUTE) 0490 add_custom_command(OUTPUT "${libcpp}" 0491 DEPENDS "${lib_tmp_cpp}" "${cmrc_hpp}" 0492 COMMAND ${CMAKE_COMMAND} -E copy_if_different "${lib_tmp_cpp}" "${libcpp}" 0493 COMMENT "Generating ${name} resource loader" 0494 ) 0495 # Generate the actual static library. Each source file is just a single file 0496 # with a character array compiled in containing the contents of the 0497 # corresponding resource file. 0498 add_library(${name} ${ARG_TYPE} ${libcpp}) 0499 set_property(TARGET ${name} PROPERTY CMRC_LIBDIR "${libdir}") 0500 set_property(TARGET ${name} PROPERTY CMRC_NAMESPACE "${ARG_NAMESPACE}") 0501 target_link_libraries(${name} PUBLIC cmrc::base) 0502 set_property(TARGET ${name} PROPERTY CMRC_IS_RESOURCE_LIBRARY TRUE) 0503 if(ARG_ALIAS) 0504 add_library("${ARG_ALIAS}" ALIAS ${name}) 0505 endif() 0506 cmrc_add_resources(${name} ${ARG_UNPARSED_ARGUMENTS}) 0507 endfunction() 0508 0509 function(_cmrc_register_dirs name dirpath) 0510 if(dirpath STREQUAL "") 0511 return() 0512 endif() 0513 # Skip this dir if we have already registered it 0514 get_target_property(registered "${name}" _CMRC_REGISTERED_DIRS) 0515 if(dirpath IN_LIST registered) 0516 return() 0517 endif() 0518 # Register the parent directory first 0519 get_filename_component(parent "${dirpath}" DIRECTORY) 0520 if(NOT parent STREQUAL "") 0521 _cmrc_register_dirs("${name}" "${parent}") 0522 endif() 0523 # Now generate the registration 0524 set_property(TARGET "${name}" APPEND PROPERTY _CMRC_REGISTERED_DIRS "${dirpath}") 0525 _cm_encode_fpath(sym "${dirpath}") 0526 if(parent STREQUAL "") 0527 set(parent_sym root_directory) 0528 else() 0529 _cm_encode_fpath(parent_sym "${parent}") 0530 endif() 0531 get_filename_component(leaf "${dirpath}" NAME) 0532 set_property( 0533 TARGET "${name}" 0534 APPEND PROPERTY CMRC_MAKE_DIRS 0535 "static auto ${sym}_dir = ${parent_sym}_dir.directory.add_subdir(\"${leaf}\")\;" 0536 "root_index.emplace(\"${dirpath}\", &${sym}_dir.index_entry)\;" 0537 ) 0538 endfunction() 0539 0540 function(cmrc_add_resources name) 0541 get_target_property(is_reslib ${name} CMRC_IS_RESOURCE_LIBRARY) 0542 if(NOT TARGET ${name} OR NOT is_reslib) 0543 message(SEND_ERROR "cmrc_add_resources called on target '${name}' which is not an existing resource library") 0544 return() 0545 endif() 0546 0547 set(options) 0548 set(args WHENCE PREFIX) 0549 set(list_args) 0550 cmake_parse_arguments(ARG "${options}" "${args}" "${list_args}" "${ARGN}") 0551 0552 if(NOT ARG_WHENCE) 0553 set(ARG_WHENCE ${CMAKE_CURRENT_SOURCE_DIR}) 0554 endif() 0555 _cmrc_normalize_path(ARG_WHENCE) 0556 get_filename_component(ARG_WHENCE "${ARG_WHENCE}" ABSOLUTE) 0557 0558 # Generate the identifier for the resource library's namespace 0559 get_target_property(lib_ns "${name}" CMRC_NAMESPACE) 0560 0561 get_target_property(libdir ${name} CMRC_LIBDIR) 0562 get_target_property(target_dir ${name} SOURCE_DIR) 0563 file(RELATIVE_PATH reldir "${target_dir}" "${CMAKE_CURRENT_SOURCE_DIR}") 0564 if(reldir MATCHES "^\\.\\.") 0565 message(SEND_ERROR "Cannot call cmrc_add_resources in a parent directory from the resource library target") 0566 return() 0567 endif() 0568 0569 foreach(input IN LISTS ARG_UNPARSED_ARGUMENTS) 0570 _cmrc_normalize_path(input) 0571 get_filename_component(abs_in "${input}" ABSOLUTE) 0572 # Generate a filename based on the input filename that we can put in 0573 # the intermediate directory. 0574 file(RELATIVE_PATH relpath "${ARG_WHENCE}" "${abs_in}") 0575 if(relpath MATCHES "^\\.\\.") 0576 # For now we just error on files that exist outside of the soure dir. 0577 message(SEND_ERROR "Cannot add file '${input}': File must be in a subdirectory of ${ARG_WHENCE}") 0578 continue() 0579 endif() 0580 if(DEFINED ARG_PREFIX) 0581 _cmrc_normalize_path(ARG_PREFIX) 0582 endif() 0583 if(ARG_PREFIX AND NOT ARG_PREFIX MATCHES "/$") 0584 set(ARG_PREFIX "${ARG_PREFIX}/") 0585 endif() 0586 get_filename_component(dirpath "${ARG_PREFIX}${relpath}" DIRECTORY) 0587 _cmrc_register_dirs("${name}" "${dirpath}") 0588 get_filename_component(abs_out "${libdir}/intermediate/${ARG_PREFIX}${relpath}.cpp" ABSOLUTE) 0589 # Generate a symbol name relpath the file's character array 0590 _cm_encode_fpath(sym "${relpath}") 0591 # Get the symbol name for the parent directory 0592 if(dirpath STREQUAL "") 0593 set(parent_sym root_directory) 0594 else() 0595 _cm_encode_fpath(parent_sym "${dirpath}") 0596 endif() 0597 # Generate the rule for the intermediate source file 0598 _cmrc_generate_intermediate_cpp(${lib_ns} ${sym} "${abs_out}" "${abs_in}") 0599 target_sources(${name} PRIVATE "${abs_out}") 0600 set_property(TARGET ${name} APPEND PROPERTY CMRC_EXTERN_DECLS 0601 "// Pointers to ${input}" 0602 "extern const char* const ${sym}_begin\;" 0603 "extern const char* const ${sym}_end\;" 0604 ) 0605 get_filename_component(leaf "${relpath}" NAME) 0606 set_property( 0607 TARGET ${name} 0608 APPEND PROPERTY CMRC_MAKE_FILES 0609 "root_index.emplace(" 0610 " \"${ARG_PREFIX}${relpath}\"," 0611 " ${parent_sym}_dir.directory.add_file(" 0612 " \"${leaf}\"," 0613 " res_chars::${sym}_begin," 0614 " res_chars::${sym}_end" 0615 " )" 0616 ")\;" 0617 ) 0618 endforeach() 0619 endfunction() 0620 0621 function(_cmrc_generate_intermediate_cpp lib_ns symbol outfile infile) 0622 add_custom_command( 0623 # This is the file we will generate 0624 OUTPUT "${outfile}" 0625 # These are the primary files that affect the output 0626 DEPENDS "${infile}" "${_CMRC_SCRIPT}" 0627 COMMAND 0628 "${CMAKE_COMMAND}" 0629 -D_CMRC_GENERATE_MODE=TRUE 0630 -DNAMESPACE=${lib_ns} 0631 -DSYMBOL=${symbol} 0632 "-DINPUT_FILE=${infile}" 0633 "-DOUTPUT_FILE=${outfile}" 0634 -P "${_CMRC_SCRIPT}" 0635 COMMENT "Generating intermediate file for ${infile}" 0636 ) 0637 endfunction() 0638 0639 function(_cm_encode_fpath var fpath) 0640 string(MAKE_C_IDENTIFIER "${fpath}" ident) 0641 string(MD5 hash "${fpath}") 0642 string(SUBSTRING "${hash}" 0 4 hash) 0643 set(${var} f_${hash}_${ident} PARENT_SCOPE) 0644 endfunction()