# Recommendation: Place this file in source control. # Auto-generated by `./dk dksdk.project.new` of dktool. include(FetchContent) function(parse_dktool_command_line) # The first argument is . All dots will be replaced with a # triple underscore as a convenience and to be pretty for the user. if(ARGC EQUAL 0) message(FATAL_ERROR "Missing . Usage: ./dk [args]") endif() set(command ${ARGV0}) string(REPLACE "." "___" expected_function_name ${command}) message(VERBOSE "Searching for ${expected_function_name}") # Set policies (we are in a new EVAL CODE context) # Included scripts do automatic cmake_policy PUSH and POP if(POLICY CMP0011) cmake_policy(SET CMP0011 NEW) endif() # Parse the remainder of the arguments [args] # * Use technique from [Professional CMake: A Practical Guide - Forwarding Command Arguments] # to be able to forward arguments correctly to an inner function (the function). cmake_parse_arguments(PARSE_ARGV 1 FWD "" "" "") set(quotedArgs "") foreach(arg IN LISTS FWD_UNPARSED_ARGUMENTS) string(APPEND quotedArgs " [===[${arg}]===]") endforeach() # Setup the binary directory if(NOT DKTOOL_WORKDIR) message(FATAL_ERROR "Illegal state. Expecting DKTOOL_WORKDIR") endif() set(CMAKE_BINARY_DIR ${DKTOOL_WORKDIR}) set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR}) # Search in all the user scripts set(dot_function_names) file(GLOB_RECURSE command_files LIST_DIRECTORIES FALSE RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/scripts cmake/scripts/*.cmake) foreach(command_file IN LISTS command_files) # Normalize and lowercase cmake_path(NORMAL_PATH command_file) string(TOLOWER "${command_file}" command_file) cmake_path(REMOVE_EXTENSION command_file OUTPUT_VARIABLE command_file_no_ext) # Convert to list string(REPLACE "/" ";" command_stems_no_namespace ${command_file_no_ext}) # Make a pretty description only for validation set(pretty_stems ${command_stems_no_namespace}) list(TRANSFORM pretty_stems PREPEND "'") list(TRANSFORM pretty_stems APPEND "'") string(JOIN ", " pretty_stems_str ${pretty_stems}) string(REGEX REPLACE ",([^,]*)" " and \\1" pretty_stems_str "${pretty_stems_str}") # Validate that only alphanumeric with underscores (but not the reserved three underscores) string(REGEX MATCH "[/a-z0-9_]*" only_alphanum_and_underscores "${command_file_no_ext}") if(NOT only_alphanum_and_underscores STREQUAL "${command_file_no_ext}") message(WARNING "Ignoring user script ${CMAKE_CURRENT_SOURCE_DIR}/${command_file}. The stems of the user script (${pretty_stems_str}) must only contain letters, numbers and underscores.") continue() endif() string(FIND "${command_file_no_ext}" "___" reserved_underscores) if(reserved_underscores GREATER_EQUAL 0) message(WARNING "Ignoring user script ${CMAKE_CURRENT_SOURCE_DIR}/${command_file}. No stem of the user script (${pretty_stems_str}) can contain a triple underscore ('___').") continue() endif() # Translate dev/xxx.cmake to the "user" namespaced function name # `user__dev__xxx` and `user.dev.xxx`. set(command_stems ${command_stems_no_namespace}) list(PREPEND command_stems "user") string(JOIN "___" command_function_name ${command_stems}) string(JOIN "." dot_function_name ${command_stems}) list(APPEND dot_function_names ${dot_function_name}) # In a new scope (to avoid a global, leaky namespace) register the function. message(VERBOSE "Shimming ${command_function_name}") cmake_language(EVAL CODE " function(${command_function_name}) include(\"${CMAKE_CURRENT_SOURCE_DIR}/cmake/scripts/${command_file}\") if(COMMAND run) run(${quotedArgs}) else() message(FATAL_ERROR [[The user script ${CMAKE_CURRENT_SOURCE_DIR}/cmake/scripts/${command_file} was missing: function(run) # Your user code endfunction() ]]) endif() endfunction() ") endforeach() # Include all the system scripts. # - Since the system scripts come after the user scripts, the user scripts # don't override the system scripts unless the user scripts use deferred # hooks or redefine CMake built-in functions. Regardless, the user # scripts are namespaced with `user__` prefix if(NOT IS_DIRECTORY cmake/scripts/dksdk) # If this project (ex. dktool) has the system scripts, it must # have all of them. Otherwise we download the system scripts. FetchContent_Populate(dktool QUIET GIT_REPOSITORY https://gitlab.com/diskuv/dktool.git GIT_TAG 1.0 ) file(GLOB_RECURSE system_command_files LIST_DIRECTORIES FALSE RELATIVE ${dktool_SOURCE_DIR}/cmake/scripts ${dktool_SOURCE_DIR}/cmake/scripts/dkml/*.cmake ${dktool_SOURCE_DIR}/cmake/scripts/dksdk/*.cmake) foreach(command_file IN LISTS system_command_files) # Normalize and lowercase cmake_path(NORMAL_PATH command_file) string(TOLOWER "${command_file}" command_file) cmake_path(REMOVE_EXTENSION command_file OUTPUT_VARIABLE command_file_no_ext) # Convert to list string(REPLACE "/" ";" command_stems_no_namespace ${command_file_no_ext}) # Translate dksdk/xxx.cmake to the function name `dksdk__xxx` and `dksdk.xxx` set(command_stems ${command_stems_no_namespace}) string(JOIN "___" command_function_name ${command_stems}) string(JOIN "." dot_function_name ${command_stems}) list(APPEND dot_function_names ${dot_function_name}) # In a new scope (to avoid a global, leaky namespace) register the function. message(VERBOSE "Shimming ${command_function_name}") cmake_language(EVAL CODE " function(${command_function_name}) include(\"${dktool_SOURCE_DIR}/cmake/scripts/${command_file}\") if(COMMAND run) run(${quotedArgs}) else() message(FATAL_ERROR [[The system script ${dktool_SOURCE_DIR}/cmake/scripts/${command_file} was missing: function(run) # The system code endfunction() ]]) endif() endfunction() ") endforeach() endif() # Validate the exists if(NOT COMMAND ${expected_function_name}) set(pretty_function_names ${dot_function_names}) list(TRANSFORM pretty_function_names PREPEND " ") list(TRANSFORM pretty_function_names APPEND "\n") string(JOIN "" str_pretty_function_names ${pretty_function_names}) message(FATAL_ERROR "No command '${command}' exists. The following commands are available: ${str_pretty_function_names}") message(FATAL_ERROR "No command '${command}' exists") endif() # Call the function cmake_language(EVAL CODE "${expected_function_name}()") endfunction() # DkML data home if(WIN32) set(DKML_DATA_HOME "$ENV{LOCALAPPDATA}/Programs/DiskuvOCaml") elseif(DEFINED ENV{XDG_DATA_HOME}) set(DKML_DATA_HOME "$ENV{XDG_DATA_HOME}/diskuv-ocaml") else() set(DKML_DATA_HOME "$ENV{HOME}/.local/share/diskuv-ocaml") endif() # DkSDK data home if(WIN32) set(DKSDK_DATA_HOME "$ENV{LOCALAPPDATA}/Programs/DkSDK") elseif(DEFINED ENV{XDG_DATA_HOME}) set(DKSDK_DATA_HOME "$ENV{XDG_DATA_HOME}/dksdk") else() set(DKSDK_DATA_HOME "$ENV{HOME}/.local/share/dksdk") endif() # Splat DKTOOL_CMDLINE cmake_language(EVAL CODE "parse_dktool_command_line(${DKTOOL_CMDLINE})")