Created
February 20, 2025 20:41
-
-
Save Ryex/4d808c1917affbc3ff00a873ea7ad010 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.15) | |
if (NOT(CMAKE_SCRIPT_MODE_FILE AND NOT CMAKE_PARENT_LIST_FILE)) | |
message(FATAL_ERROR "UpdateSources.cmake must be run in script mode") | |
return() | |
endif() | |
set(_script_file "${CMAKE_CURRENT_LIST_FILE}") | |
get_filename_component(_root "${_script_file}" ABSOLUTE) # _root/cmake/UpdateSources.cmake | |
get_filename_component(_root "${_root}" DIRECTORY) # _root/cmake/ | |
get_filename_component(_root "${_root}" DIRECTORY) # _root/ | |
set(IGNORE_PATHS | |
libraries | |
program_info | |
) | |
list(TRANSFORM IGNORE_PATHS PREPEND "${_root}/") | |
message(STATUS "IGNORING: ${IGNORE_PATHS}") | |
function(UpdateGlobSources _path _additional_paths_var) | |
set(_file "${_path}/CMakeLists.txt") | |
message("READING: ${_file}") | |
file(READ "${_file}" _content) | |
if(NOT EXISTS "${_file}") | |
return() | |
endif() | |
set(_line "") | |
set(_output "") | |
set(_in_sources FALSE) | |
set(_have_sources FALSE) | |
set(_sources "") | |
set(_found "") | |
set(_updating "") | |
set(_addtional_paths "") | |
string(LENGTH "${_content}" _content_len) | |
foreach(index RANGE 0 ${_content_len}) | |
string(SUBSTRING "${_content}" ${index} 1 current_char) | |
string(CONCAT _line "${_line}" "${current_char}") | |
# message("char: ${index} : ${current_char} | line: ${_line}") | |
if("${current_char}" STREQUAL "\n") | |
# new line | |
set(_do_output TRUE) | |
string(STRIP "${_line}" _line_strip) | |
# message("STRIP: \"${_line_strip}\"") | |
if( | |
(NOT _in_sources) | |
AND ("${_line_strip}" MATCHES [[^#[ \t]*UPDATE SOURCES (GLOB(_RECURSE)?)[ \t]*(.*)$]]) | |
) | |
set(_recurse FALSE) | |
set(_file_cmd "${CMAKE_MATCH_1}") | |
set(_globs "${CMAKE_MATCH_3}") | |
separate_arguments(_globs UNIX_COMMAND "${_globs}") | |
list(TRANSFORM _globs PREPEND "${_path}/" ) | |
message("GLOB_CMD: ${_file_cmd} ${_globs}") | |
file(${_file_cmd} _sources RELATIVE "${_path}/" ${_globs}) | |
set(_have_sources TRUE) | |
set(_found "") | |
message("SOURCES: ${_sources}") | |
elseif( | |
_have_sources | |
AND ("${_line_strip}" MATCHES [[^[Ss][Ee][Tt]\(([A-Za-z0-9_-]+)[ \t]*$]]) | |
) | |
set(_in_sources TRUE) | |
message(STATUS "UPDATING: ${CMAKE_MATCH_1}") | |
set(_updating "${CMAKE_MATCH_1}") | |
set(_found "") | |
elseif( | |
_have_sources | |
AND ("${_line_strip}" MATCHES [[^[Ss][Ee][Tt]\(([A-Za-z0-9_-]+)[ \t]*(.*)\)$]]) | |
) | |
set(_do_output FALSE) | |
message(STATUS "UPDATING: ${CMAKE_MATCH_1}") | |
set(_updating "${CMAKE_MATCH_1}") | |
set(_line_sources "${CMAKE_MATCH_2}") | |
separate_arguments(_line_sources UNIX_COMMAND "${_line_sources}") | |
set(_found "") | |
set(_output_sources "") | |
foreach(_line_source IN LISTS _line_sources) | |
if("${_line_source}" IN_LIST _sources) | |
list(APPEND _found "${_line_source}") | |
string(CONCAT _output_sources "${_output_sources}" " ${_line_source}\n") | |
endif() | |
endforeach() | |
foreach(_source IN LISTS _sources) | |
if(NOT "${_source}" IN_LIST _found) | |
string(CONCAT _output_sources "${_output_sources}" " ${_source}\n") | |
endif() | |
endforeach() | |
string(CONCAT _output "${_output}" "set(${_updating}\n${_output_sources})") | |
elseif( | |
_in_sources | |
AND ("${_line_strip}" MATCHES [[^\)[ \t]*$]]) | |
) | |
set(_in_sources FALSE) | |
set(_updating "") | |
foreach(_source IN LISTS _sources) | |
if(NOT "${_source}" IN_LIST _found) | |
string(CONCAT _output "${_output}" " ${_source}\n") | |
endif() | |
endforeach() | |
elseif( | |
_in_sources | |
AND (NOT "${_line_strip}" MATCHES [[^#]]) | |
AND (NOT "${_line_strip}" STREQUAL "") | |
) | |
if("${_line_strip}" IN_LIST _sources) | |
set(_do_output TRUE) | |
list(APPEND _found "${_line_strip}") | |
else() | |
set(_do_output FALSE) | |
endif() | |
elseif( | |
_have_sources | |
AND (NOT _in_sources) | |
) | |
set(_sources "") | |
set(_have_sources FALSE) | |
elseif( | |
(NOT _in_sources) | |
AND ("${_line_strip}" MATCHES [[^[Aa][Dd][Dd]_[Ss][Uu][Bb][Dd][Ii][Rr][Ee][Cc][Tt][Oo][Rr][Yy]\((.*)( EXCLUDE_FROM_ALL)?\)$]]) | |
) | |
list(APPEND _addtional_paths "${_path}/${CMAKE_MATCH_1}") | |
endif() | |
if(_do_output) | |
string(CONCAT _output "${_output}" "${_line}") | |
endif() | |
set(_line "") | |
endif() | |
endforeach() | |
set(${_additional_paths_var} ${_addtional_paths} PARENT_SCOPE) | |
if(NOT "${_output}" STREQUAL "${_content}") | |
message(STATUS "UPDATE: ${_file} has changed") | |
file(WRITE "${_file}" "${_output}") | |
endif() | |
endfunction(UpdateGlobSources) | |
list(APPEND _path_stack "${_root}") | |
while(_path_stack) | |
list(POP_FRONT _path_stack _cur_path) | |
message(STATUS "PROCESSING: ${_cur_path}") | |
UpdateGlobSources("${_cur_path}" _next_paths) | |
foreach(_path ${_next_paths}) | |
get_filename_component(_parent "${_path}" DIRECTORY) # _root/ | |
get_filename_component(_parent_parent "${_parent}" DIRECTORY) # _root/ | |
if( | |
(NOT "${_path}" IN_LIST IGNORE_PATHS) | |
AND (NOT "${_parent}" IN_LIST IGNORE_PATHS) | |
AND (NOT "${_parent_parent}" IN_LIST IGNORE_PATHS) | |
) | |
list(APPEND _path_stack "${_path}") | |
endif() | |
endforeach() | |
endwhile() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment