# include guard include_guard(DIRECTORY) # MacroUtilities - useful macros and functions for generic tasks # include(CMakeDependentOption) include(CMakeParseArguments) # ----------------------------------------------------------------------- # function - capitalize - make a string capitalized (first letter is capital) # function(CAPITALIZE str var) # make string lower string(TOLOWER "${str}" str) string(SUBSTRING "${str}" 0 1 _first) string(TOUPPER "${_first}" _first) string(SUBSTRING "${str}" 1 -1 _remainder) string(CONCAT str "${_first}" "${_remainder}") set(${var} "${str}" PARENT_SCOPE) endfunction() # ----------------------------------------------------------------------------------------# # function CHECKOUT_GIT_SUBMODULE() # # Run "git submodule update" if a file in a submodule does not exist # # ARGS: RECURSIVE (option) -- add "--recursive" flag RELATIVE_PATH (one value) -- # typically the relative path to submodule from PROJECT_SOURCE_DIR WORKING_DIRECTORY (one # value) -- (default: PROJECT_SOURCE_DIR) TEST_FILE (one value) -- file to check for # (default: CMakeLists.txt) ADDITIONAL_CMDS (many value) -- any addition commands to pass # function(CHECKOUT_GIT_SUBMODULE) # parse args cmake_parse_arguments( CHECKOUT "RECURSIVE" "RELATIVE_PATH;WORKING_DIRECTORY;TEST_FILE;REPO_URL;REPO_BRANCH" "ADDITIONAL_CMDS" ${ARGN} ) if(NOT CHECKOUT_WORKING_DIRECTORY) set(CHECKOUT_WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) endif() if(NOT CHECKOUT_TEST_FILE) set(CHECKOUT_TEST_FILE "CMakeLists.txt") endif() # default assumption if(NOT CHECKOUT_REPO_BRANCH) set(CHECKOUT_REPO_BRANCH "master") endif() find_package(Git) set(_DIR "${CHECKOUT_WORKING_DIRECTORY}/${CHECKOUT_RELATIVE_PATH}") # ensure the (possibly empty) directory exists if(NOT EXISTS "${_DIR}") if(NOT CHECKOUT_REPO_URL) message(FATAL_ERROR "submodule directory does not exist") endif() endif() # if this file exists --> project has been checked out if not exists --> not been # checked out set(_TEST_FILE "${_DIR}/${CHECKOUT_TEST_FILE}") # assuming a .gitmodules file exists set(_SUBMODULE "${PROJECT_SOURCE_DIR}/.gitmodules") set(_TEST_FILE_EXISTS OFF) if(EXISTS "${_TEST_FILE}" AND NOT IS_DIRECTORY "${_TEST_FILE}") set(_TEST_FILE_EXISTS ON) endif() if(_TEST_FILE_EXISTS) return() endif() find_package(Git REQUIRED) set(_SUBMODULE_EXISTS OFF) if(EXISTS "${_SUBMODULE}" AND NOT IS_DIRECTORY "${_SUBMODULE}") set(_SUBMODULE_EXISTS ON) else() set(_SUBMODULE "${CMAKE_SOURCE_DIR}/.gitmodules") if(EXISTS "${_SUBMODULE}" AND NOT IS_DIRECTORY "${_SUBMODULE}") set(_SUBMODULE_EXISTS ON) endif() endif() set(_HAS_REPO_URL OFF) if(NOT "${CHECKOUT_REPO_URL}" STREQUAL "") set(_HAS_REPO_URL ON) endif() # if the module has not been checked out if(NOT _TEST_FILE_EXISTS AND _SUBMODULE_EXISTS) # perform the checkout execute_process( COMMAND ${GIT_EXECUTABLE} submodule update --init ${_RECURSE} ${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH} WORKING_DIRECTORY ${CHECKOUT_WORKING_DIRECTORY} RESULT_VARIABLE RET ) # check the return code if(RET GREATER 0) set(_CMD "${GIT_EXECUTABLE} submodule update --init ${_RECURSE} ${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH}" ) message(STATUS "function(CHECKOUT_GIT_SUBMODULE) failed.") message(FATAL_ERROR "Command: \"${_CMD}\"") else() set(_TEST_FILE_EXISTS ON) endif() endif() if(NOT _TEST_FILE_EXISTS AND _HAS_REPO_URL) message( STATUS "Checking out '${CHECKOUT_REPO_URL}' @ '${CHECKOUT_REPO_BRANCH}'..." ) # remove the existing directory if(EXISTS "${_DIR}") execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${_DIR}) endif() # perform the checkout execute_process( COMMAND ${GIT_EXECUTABLE} clone -b ${CHECKOUT_REPO_BRANCH} ${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_REPO_URL} ${CHECKOUT_RELATIVE_PATH} WORKING_DIRECTORY ${CHECKOUT_WORKING_DIRECTORY} RESULT_VARIABLE RET ) # perform the submodule update if(CHECKOUT_RECURSIVE AND EXISTS "${_DIR}" AND IS_DIRECTORY "${_DIR}") execute_process( COMMAND ${GIT_EXECUTABLE} submodule update --init ${_RECURSE} WORKING_DIRECTORY ${_DIR} RESULT_VARIABLE RET ) endif() # check the return code if(RET GREATER 0) set(_CMD "${GIT_EXECUTABLE} clone -b ${CHECKOUT_REPO_BRANCH} ${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_REPO_URL} ${CHECKOUT_RELATIVE_PATH}" ) message(STATUS "function(CHECKOUT_GIT_SUBMODULE) failed.") message(FATAL_ERROR "Command: \"${_CMD}\"") else() set(_TEST_FILE_EXISTS ON) endif() endif() if(NOT EXISTS "${_TEST_FILE}" OR NOT _TEST_FILE_EXISTS) message( FATAL_ERROR "Error checking out submodule: '${CHECKOUT_RELATIVE_PATH}' to '${_DIR}'" ) endif() endfunction()