################################################ # Dynamically add files from src(_msw/_nix/_mac) # to the project # # Written by Steven 'KaReL' Van Ingelgem # # License: BSD License ################################################ # # # Notice: # ------- # This should be included before the call of: # 'ADD_EXECUTABLE' # # # Purpose: # -------- # The purpose of this script is to recursively add sources # from the src-directories and retain their relative # directory structure inside the IDE of your choice (the # ones I tested are XCode & VS). # # The sources should be put in the following directories: # /src/ # /src_mac/ # /src_msw/ # /src_nix/ # # Before the call to ADD_EXECUTABLE/LIBRARY you should call # "GET_ALL_SOURCE_FILES(target_var from_dir)" # --> For example: GET_ALL_SOURCE_FILES(all_sources # ${CMAKE_CURRENT_SOURCE_DIR}) # # After this you can just include the sources into # ADD_EXECUTABLE/LIBRARY as ${target_var} # --> For example: ADD_EXECUTABLE(project ${all_sources}) # # After the call to ADD_EXECUTABLE/LIBRARY you should call # "GENERATE_SOURCE_GROUPS(source_var from_dir)" # --> For example: GENERATE_SOURCE_GROUPS(all_sources # ${CMAKE_CURRENT_SOURCE_DIR}) # --> NOTICE!! the source_var should be the same as the # target_var used in the call to GET_ALL_SOURCE_FILES # --> NOTICE!! the from_dir should be the same as the # from_dir used in the call to GET_ALL_SOURCE_FILES # # Extension: # ---------- # You can override which extensions it will enlist as 'sources' # by including this file and SET'ting (= overriding) the # variable DYNAMIC_ADD_SOURCE_FILE_LIST. # ################################################# # Version History ################################################# # # 1.0.0: # Initial release to the public # # # # # # # # # # # SET(DYNAMIC_ADD_SOURCE_FILE_LIST "*.cpp;*.hpp;*.c;*.h;*.cc;*.hh;*.c++;*.h++;*.cxx;*.hxx") # Help macro to get all sourcefiles from a specific directory structure MACRO(DYNAMIC_ADD_GET_ALL_SOURCE_FILES_HELP INTO_VAR FROM_DIR SUB_DIR) IF(EXISTS "${FROM_DIR}/${SUB_DIR}") # Loop over all possible sources FOREACH(${INTO_VAR}_loopvar ${DYNAMIC_ADD_SOURCE_FILE_LIST}) # Clean our working variable SET(${INTO_VAR}_workvar) # Recursive find all files FILE(GLOB_RECURSE ${INTO_VAR}_workvar "${FROM_DIR}/${SUB_DIR}" ${SUB_DIR}/${${INTO_VAR}_loopvar}) # Add them to the global list FOREACH(${INTO_VAR}_workvar_loop ${${INTO_VAR}_workvar}) LIST(APPEND ${INTO_VAR} "${${INTO_VAR}_workvar_loop}") ENDFOREACH(${INTO_VAR}_workvar_loop) ENDFOREACH(${INTO_VAR}_loopvar) ENDIF(EXISTS "${FROM_DIR}/${SUB_DIR}") ENDMACRO(DYNAMIC_ADD_GET_ALL_SOURCE_FILES_HELP) MACRO(GET_ALL_SOURCE_FILES INTO_VAR FROM_DIR) # Init variable to nothing SET(${INTO_VAR}) DYNAMIC_ADD_GET_ALL_SOURCE_FILES_HELP(${INTO_VAR} "${FROM_DIR}" "src") # And a list of all additional sources in the platform dependent directories (src_msw/mac/nix) IF(WIN32) DYNAMIC_ADD_GET_ALL_SOURCE_FILES_HELP(${INTO_VAR} "${FROM_DIR}" "src_msw") ELSEIF(APPLE) DYNAMIC_ADD_GET_ALL_SOURCE_FILES_HELP(${INTO_VAR} "${FROM_DIR}" "src_mac") ELSE(WIN32) # UNIX-like DYNAMIC_ADD_GET_ALL_SOURCE_FILES_HELP(${INTO_VAR} "${FROM_DIR}" "src_nix") ENDIF(WIN32) # Sort it (it looks more nice) LIST(SORT "${INTO_VAR}") ENDMACRO(GET_ALL_SOURCE_FILES) MACRO(DYNAMIC_ADD_GET_DIRECTORY target_var input) # Init SET(${target_var}) # Change all Windows-directory terminators to '/' STRING(REPLACE "\\" "/" ${target_var}_input "${input}") # Get the length of the input string STRING(LENGTH "${${target_var}_input}" ${target_var}_length) # -1 because we're 0-based :( MATH(EXPR ${target_var}_length "${${target_var}_length}-1") # Init work variable SET(${target_var}_current_variable) SET(${target_var}_building_list) # Loop over every character in the input-string FOREACH(${target_var}_current_position RANGE 0 ${${target_var}_length}) # Clean the target variable SET(${target_var}_current_char) # Get the character at the current position STRING(SUBSTRING "${${target_var}_input}" ${${target_var}_current_position} 1 ${target_var}_current_char) # If it's a directory terminator IF( "${${target_var}_current_char}" STREQUAL "/" ) # If it's empty, we have '//' which is translated to '/' (ie: don't add it!) IF ( NOT "${${target_var}_current_variable}" STREQUAL "" ) # Add it to the output variable LIST(APPEND ${target_var}_building_list "${${target_var}_current_variable}") ENDIF( NOT "${${target_var}_current_variable}" STREQUAL "" ) # And clean it SET(${target_var}_current_variable) ELSE( "${${target_var}_current_char}" STREQUAL "/" ) # Add the character we're working on to the working variable SET(${target_var}_current_variable "${${target_var}_current_variable}${${target_var}_current_char}") ENDIF( "${${target_var}_current_char}" STREQUAL "/" ) ENDFOREACH(${target_var}_current_position) # Right here we build a list (${target_var}_building_list) with all the paths, # but not the last part (ie: the filename) # Loop our resulted list of directories and build the output variable from it FOREACH(${target_var}_building_list_loopvar ${${target_var}_building_list}) # Don't add terminators in the first position IF("${${target_var}}" STREQUAL "") SET(${target_var} "${${target_var}_building_list_loopvar}") ELSE("${${target_var}}" STREQUAL "") SET(${target_var} "${${target_var}}\\\\${${target_var}_building_list_loopvar}") ENDIF("${${target_var}}" STREQUAL "") ENDFOREACH(${target_var}_building_list_loopvar) ENDMACRO(DYNAMIC_ADD_GET_DIRECTORY) MACRO(DYNAMIC_ADD_STRIP_FROM_FRONT output_var searchfor input_var) # Init output_var SET(${output_var} ${input_var}) # Get the lengths STRING(LENGTH "${searchfor}" ${output_var}_search_length) STRING(LENGTH "${input_var}" ${output_var}_in_length) # If len(inputvar) >= len(searchfor) IF(${${output_var}_in_length} GREATER ${${output_var}_search_length} OR ${${output_var}_in_length} EQUAL ${${output_var}_search_length}) # Get the first len(searchfor) characters from the input variable STRING(SUBSTRING "${input_var}" 0 ${${output_var}_search_length} ${output_var}_first_characters) IF("${${output_var}_first_characters}" STREQUAL "${searchfor}") # Get the amount of characters which has to be left MATH(EXPR ${output_var}_in_length "${${output_var}_in_length}-${${output_var}_search_length}") # Get the new output variable STRING(SUBSTRING "${input_var}" ${${output_var}_search_length} ${${output_var}_in_length} ${output_var}) ENDIF("${${output_var}_first_characters}" STREQUAL "${searchfor}") ENDIF(${${output_var}_in_length} GREATER ${${output_var}_search_length} OR ${${output_var}_in_length} EQUAL ${${output_var}_search_length}) ENDMACRO(DYNAMIC_ADD_STRIP_FROM_FRONT) MACRO(GENERATE_SOURCE_GROUPS SOURCE_VARIABLE FROM_DIR) # Change all Windows -> Unix terminators STRING(REPLACE "\\" "/" ${SOURCE_VARIABLE}_working_dir "${FROM_DIR}") # Loop over every source file FOREACH(${SOURCE_VARIABLE}_current_source_file ${${SOURCE_VARIABLE}}) # Get the path from the current sourcefile GET_FILENAME_COMPONENT(${SOURCE_VARIABLE}_current_file_path "${${SOURCE_VARIABLE}_current_source_file}" PATH) # Add this directory as an include INCLUDE_DIRECTORIES( ${${SOURCE_VARIABLE}_current_file_path} ) # Change all Windows -> Unix terminators STRING(REPLACE "\\" "/" ${SOURCE_VARIABLE}_currently_working_on_source_file "${${SOURCE_VARIABLE}_current_source_file}") # Remove the 'FROM_DIR' so we only keep the relative path STRING(REPLACE "${${SOURCE_VARIABLE}_working_dir}" "" ${SOURCE_VARIABLE}_currently_working_on_source_file "${${SOURCE_VARIABLE}_currently_working_on_source_file}") # Remove the directories from the front DYNAMIC_ADD_STRIP_FROM_FRONT(${SOURCE_VARIABLE}_currently_working_on_source_file "/src/" "${${SOURCE_VARIABLE}_currently_working_on_source_file}") DYNAMIC_ADD_STRIP_FROM_FRONT(${SOURCE_VARIABLE}_currently_working_on_source_file "/src_msw/" "${${SOURCE_VARIABLE}_currently_working_on_source_file}") DYNAMIC_ADD_STRIP_FROM_FRONT(${SOURCE_VARIABLE}_currently_working_on_source_file "/src_mac/" "${${SOURCE_VARIABLE}_currently_working_on_source_file}") DYNAMIC_ADD_STRIP_FROM_FRONT(${SOURCE_VARIABLE}_currently_working_on_source_file "/src_nix/" "${${SOURCE_VARIABLE}_currently_working_on_source_file}") # Get the directory for the SOURCE_GROUP DYNAMIC_ADD_GET_DIRECTORY(${SOURCE_VARIABLE}_relative_source_dir "${${SOURCE_VARIABLE}_currently_working_on_source_file}") SOURCE_GROUP("${${SOURCE_VARIABLE}_relative_source_dir}" FILES ${${SOURCE_VARIABLE}_current_source_file}) ENDFOREACH(${SOURCE_VARIABLE}_current_source_file) ENDMACRO(GENERATE_SOURCE_GROUPS) ################################################ # Dynamically add files from src(_msw/_nix/_mac) # to the project # # Written by Steven 'KaReL' Van Ingelgem # ################################################