From 4c66432f9fe573134b5a7d7281df92863f1c2210 Mon Sep 17 00:00:00 2001 From: Ben Cumming <louncharf@gmail.com> Date: Fri, 16 Mar 2018 08:13:31 +0100 Subject: [PATCH] refactor git submodule support in cmake (#448) In some places our CMake scripts were attempting to check out git submodules when required, if they have not already been checked out. The code that does this was cut and pasted, and was getting unwieldy. To minimise the responsibilities of CMake, this PR removes calls to git introduces a function check_git_submodule that can be used to test if a git submodule is installed, and print a helpful message that informs the user how to check it out if needed. introduces a function add_error_target that makes a target that prints a message then quits with an error. This can be used to generate a proxy target when a problem is detected during CMake setup. This means that an error is only generated when building a target with a missing dependency, instead of an error during CMake setup. refactors the CMake setup for the docs and ubenches targets to use these new features. --- CMakeLists.txt | 16 +++++++++++++- cmake/ErrorTarget.cmake | 11 ++++++++++ cmake/GitSubmodule.cmake | 24 +++++++++++++++++++++ doc/CMakeLists.txt | 42 ++++--------------------------------- tests/CMakeLists.txt | 10 ++++++++- tests/ubench/CMakeLists.txt | 25 ---------------------- 6 files changed, 63 insertions(+), 65 deletions(-) create mode 100644 cmake/ErrorTarget.cmake create mode 100644 cmake/GitSubmodule.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index df3894c1..11f98abf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -291,9 +291,23 @@ if(NOT use_external_modcc) add_subdirectory(modcc) endif() +#---------------------------------------------------------- +# set up for targets that require git submodules. +#---------------------------------------------------------- +include(GitSubmodule) # required for check_git_submodule +include(ErrorTarget) # reguired for add_error_target +check_git_submodule(rtdtheme "${PROJECT_SOURCE_DIR}/doc/rtd_theme") + add_subdirectory(src) add_subdirectory(mechanisms) # after src path so that gpu_mechanism library is last on link line add_subdirectory(tests) add_subdirectory(example) add_subdirectory(lmorpho) -add_subdirectory(doc) +if (rtdtheme_avail) + add_subdirectory(doc) +else() + add_error_target( docs + "Generating Sphinx documentation" + "The git submodule for read the docs is not available") +endif() + diff --git a/cmake/ErrorTarget.cmake b/cmake/ErrorTarget.cmake new file mode 100644 index 00000000..6e4a836b --- /dev/null +++ b/cmake/ErrorTarget.cmake @@ -0,0 +1,11 @@ +# Creates a target that prints an error message and returns 1 when built. +# name : the name of the target +# comment : the COMMENT string for the real target, e.g. "Building the Sphinx documentation" +# message : the error message + +function(add_error_target name comment message) + add_custom_target(${name} + COMMAND echo " Error: ${message}." + COMMAND exit 1 + COMMENT "${comment}") +endfunction() diff --git a/cmake/GitSubmodule.cmake b/cmake/GitSubmodule.cmake new file mode 100644 index 00000000..b693f370 --- /dev/null +++ b/cmake/GitSubmodule.cmake @@ -0,0 +1,24 @@ +# Call to ensure that the git submodule in location `path` is loaded. +# If the submodule is not loaded, an error message that describes +# how to update the submodules is printed. +# Sets the variable name_avail to `ON` if the submodule is available, +# or `OFF` otherwise. + +function(check_git_submodule name path) + set(success_var "${name}_avail") + set(${success_var} ON PARENT_SCOPE) + + if(NOT EXISTS "${path}/.git") + message( + "\nThe git submodule for ${name} is not available.\n" + "To check out all submodules use the following commands:\n" + " git submodule init\n" + " git submodule update\n" + "Or download submodules recursively when checking out:\n" + " git clone --recursive https://github.com/eth-cscs/arbor.git\n" + ) + + # if the repository was not available, and git failed, set AVAIL to false + set(${success_var} OFF PARENT_SCOPE) + endif() +endfunction() diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index fbe7d567..7ca6bd5a 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,30 +1,3 @@ -# Set up rtd theme as an external project. -set(rtdtheme_src_dir "${CMAKE_CURRENT_SOURCE_DIR}/rtd_theme") - -find_package(Git) -if(NOT EXISTS "${rtdtheme_src_dir}/.git") - set(git_failed) - - if(GIT_FOUND) - message(STATUS "Updating the ReadTheDocs theme submodule ${rtdtheme_src_dir}") - execute_process( - COMMAND "${GIT_EXECUTABLE}" submodule update --init "${rtdtheme_src_dir}" - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - ERROR_VARIABLE git_error - RESULT_VARIABLE git_result) - if(NOT git_result EQUAL 0) - set(git_failed "${git_error}") - endif() - else() - set(git_failed "git not found") - endif() - - if(git_failed) - message(WARNING "Unable to update the ReadTheDocs theme submodule: ${git_failed}") - endif() - -endif() - # a static path is required to avoid warning messages from sphinx-build file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/static") @@ -33,9 +6,8 @@ find_package(Sphinx) set(DOCS_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/html") set(DOCS_DOC_TREE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees") -set(DOCS_TARGET_NAME docs) if (SPHINX_FOUND) - add_custom_target( ${DOCS_TARGET_NAME} + add_custom_target(docs COMMAND ${SPHINX_EXECUTABLE} -b html @@ -46,16 +18,10 @@ if (SPHINX_FOUND) COMMENT "Generating Sphinx documentation") else() - add_custom_target( ${DOCS_TARGET_NAME} - COMMAND - echo "Error: Sphinx must be installed to build documentation." - COMMAND - exit 1 # return error code to let CMake know that the build proccess should fail - COMMENT - "Generating Sphinx documentation") + add_error_target(docs + "Generating Sphinx documentation" + "Sphinx must be installed to build documentation") endif() # remove generated documentation when make clean is run set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${DOCS_BUILD_DIR}") - -unset(git_failed) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 476d1961..72254906 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,7 +14,15 @@ add_subdirectory(global_communication) add_subdirectory(performance) # Microbenchmarks. -add_subdirectory(ubench) +# Attempt to update git submodule if required. +check_git_submodule(google_bench "${CMAKE_CURRENT_SOURCE_DIR}/ubench/google-benchmark") +if (google_bench_avail) + add_subdirectory(ubench) +else() + add_error_target(ubenches + "Building micro benchmarks" + "The git submodule for google benchmark is not available") +endif() # regression / delta tests # Employing the full simulator. validated using deltas on output data diff --git a/tests/ubench/CMakeLists.txt b/tests/ubench/CMakeLists.txt index 75e4cf90..c0486931 100644 --- a/tests/ubench/CMakeLists.txt +++ b/tests/ubench/CMakeLists.txt @@ -24,30 +24,6 @@ set(gbench_cmake_args "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}" "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}") - -# Attempt to update git submodule if required. -find_package(Git) -if(NOT EXISTS "${gbench_src_dir}/.git") - set(git_failed) - if(GIT_FOUND) - message(STATUS "Updating the google-benchmark submodule ${gbench_src_dir}") - execute_process( - COMMAND "${GIT_EXECUTABLE}" submodule update --init "${gbench_src_dir}" - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - ERROR_VARIABLE git_error - RESULT_VARIABLE git_result) - if(NOT git_result EQUAL 0) - set(git_failed "${git_error}") - endif() - else() - set(git_failed "git not found") - endif() - - if(git_failed) - message(WARNING "Unable to update the google-benchmark submodule: ${git_failed}") - endif() -endif() - ExternalProject_Add(gbench # Add dummy DOWNLOAD_COMMAND to stop ExternalProject_Add terminating CMake if the # git submodule had not been udpated. @@ -85,4 +61,3 @@ if(ARB_WITH_CUDA) endif() add_custom_target(ubenches DEPENDS ${bench_exe_list}) - -- GitLab