From dd54290dab61c3342866c71052145271c13468ad Mon Sep 17 00:00:00 2001 From: Alex Turbov Date: Tue, 5 Nov 2019 23:15:54 +0200 Subject: [PATCH 1/3] Refactor: Modernize `function` command --- Source/cmFunctionCommand.cxx | 57 +++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index b3ddfe01f3..bd961156bf 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFunctionCommand.h" -#include #include #include @@ -21,6 +20,10 @@ #include "cmStringAlgorithms.h" namespace { +std::string const ARGC = "ARGC"; +std::string const ARGN = "ARGN"; +std::string const ARGV = "ARGV"; + // define the class for function commands class cmFunctionHelperCommand { @@ -37,7 +40,6 @@ public: cmPolicies::PolicyMap Policies; std::string FilePath; }; -} bool cmFunctionHelperCommand::operator()( std::vector const& args, @@ -52,9 +54,9 @@ bool cmFunctionHelperCommand::operator()( // make sure the number of arguments passed is at least the number // required by the signature if (expandedArgs.size() < this->Args.size() - 1) { - std::string errorMsg = cmStrCat( + auto const errorMsg = cmStrCat( "Function invoked with incorrect arguments for function named: ", - this->Args[0]); + this->Args.front()); inStatus.SetError(errorMsg); return false; } @@ -63,30 +65,29 @@ bool cmFunctionHelperCommand::operator()( this->Policies); // set the value of argc - makefile.AddDefinition("ARGC", std::to_string(expandedArgs.size())); - makefile.MarkVariableAsUsed("ARGC"); + makefile.AddDefinition(ARGC, std::to_string(expandedArgs.size())); + makefile.MarkVariableAsUsed(ARGC); // set the values for ARGV0 ARGV1 ... - for (unsigned int t = 0; t < expandedArgs.size(); ++t) { - std::ostringstream tmpStream; - tmpStream << "ARGV" << t; - makefile.AddDefinition(tmpStream.str(), expandedArgs[t]); - makefile.MarkVariableAsUsed(tmpStream.str()); + for (auto t = 0u; t < expandedArgs.size(); ++t) { + auto const value = cmStrCat(ARGV, std::to_string(t)); + makefile.AddDefinition(value, expandedArgs[t]); + makefile.MarkVariableAsUsed(value); } // define the formal arguments - for (unsigned int j = 1; j < this->Args.size(); ++j) { + for (auto j = 1u; j < this->Args.size(); ++j) { makefile.AddDefinition(this->Args[j], expandedArgs[j - 1]); } // define ARGV and ARGN - std::string argvDef = cmJoin(expandedArgs, ";"); - auto eit = expandedArgs.begin() + (this->Args.size() - 1); - std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";"); - makefile.AddDefinition("ARGV", argvDef); - makefile.MarkVariableAsUsed("ARGV"); - makefile.AddDefinition("ARGN", argnDef); - makefile.MarkVariableAsUsed("ARGN"); + auto const argvDef = cmJoin(expandedArgs, ";"); + auto const eit = expandedArgs.begin() + (this->Args.size() - 1); + auto const argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";"); + makefile.AddDefinition(ARGV, argvDef); + makefile.MarkVariableAsUsed(ARGV); + makefile.AddDefinition(ARGN, argnDef); + makefile.MarkVariableAsUsed(ARGN); // Invoke all the functions that were collected in the block. // for each function @@ -100,7 +101,7 @@ bool cmFunctionHelperCommand::operator()( return false; } if (status.GetReturnInvoked()) { - return true; + break; } } @@ -129,7 +130,8 @@ bool cmFunctionFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, std::vector expandedArguments; mf.ExpandArguments(lff.Arguments, expandedArguments, this->GetStartingContext().FilePath.c_str()); - return expandedArguments.empty() || expandedArguments[0] == this->Args[0]; + return expandedArguments.empty() || + expandedArguments.front() == this->Args.front(); } bool cmFunctionFunctionBlocker::Replay( @@ -142,10 +144,12 @@ bool cmFunctionFunctionBlocker::Replay( f.Functions = std::move(functions); f.FilePath = this->GetStartingContext().FilePath; mf.RecordPolicies(f.Policies); - mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f)); + mf.GetState()->AddScriptedCommand(this->Args.front(), std::move(f)); return true; } +} // anonymous namespace + bool cmFunctionCommand(std::vector const& args, cmExecutionStatus& status) { @@ -155,10 +159,9 @@ bool cmFunctionCommand(std::vector const& args, } // create a function blocker - { - auto fb = cm::make_unique(); - cmAppend(fb->Args, args); - status.GetMakefile().AddFunctionBlocker(std::move(fb)); - } + auto fb = cm::make_unique(); + cmAppend(fb->Args, args); + status.GetMakefile().AddFunctionBlocker(std::move(fb)); + return true; } From 90e3e2a7778dc0ec5b421e9657ec49936a3cf174 Mon Sep 17 00:00:00 2001 From: Alex Turbov Date: Sun, 8 Dec 2019 02:26:14 +0200 Subject: [PATCH 2/3] cmFunctionCommand: Introduce `CMAKE_CURRENT_FUNCTION*` variables `CMAKE_CURRENT_FUNCTION` Can be used for diagnostic or debugging messages like the `__PRETTY_FUNCTION__` macro of GCC. `CMAKE_CURRENT_FUNCTION_LIST_DIR` Eliminates the necessity of the additional "global" variables inside a module used to access additional "resource" files from functions defined in the module. ... --- Help/command/macro.rst | 6 ++ Help/manual/cmake-variables.7.rst | 4 + Help/release/dev/CMAKE_CURRENT_FUNCTION.rst | 9 ++ Help/variable/CMAKE_CURRENT_FUNCTION.rst | 6 ++ .../CMAKE_CURRENT_FUNCTION_LIST_DIR.rst | 33 +++++++ .../CMAKE_CURRENT_FUNCTION_LIST_FILE.rst | 5 + .../CMAKE_CURRENT_FUNCTION_LIST_LINE.rst | 5 + Source/cmFunctionCommand.cxx | 21 +++++ Tests/RunCMake/CMakeLists.txt | 1 + .../CMAKE_CURRENT_FUNCTION-stdout.txt | 7 ++ .../function/CMAKE_CURRENT_FUNCTION.cmake | 94 +++++++++++++++++++ Tests/RunCMake/function/CMakeLists.txt | 3 + Tests/RunCMake/function/DummyMacro.cmake | 20 ++++ Tests/RunCMake/function/RunCMakeTest.cmake | 3 + 14 files changed, 217 insertions(+) create mode 100644 Help/release/dev/CMAKE_CURRENT_FUNCTION.rst create mode 100644 Help/variable/CMAKE_CURRENT_FUNCTION.rst create mode 100644 Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst create mode 100644 Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst create mode 100644 Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst create mode 100644 Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION-stdout.txt create mode 100644 Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION.cmake create mode 100644 Tests/RunCMake/function/CMakeLists.txt create mode 100644 Tests/RunCMake/function/DummyMacro.cmake create mode 100644 Tests/RunCMake/function/RunCMakeTest.cmake diff --git a/Help/command/macro.rst b/Help/command/macro.rst index 05e5d79ac6..3f6f2f9564 100644 --- a/Help/command/macro.rst +++ b/Help/command/macro.rst @@ -91,6 +91,12 @@ just terminate execution of the macro; rather, control is returned from the scope of the macro call. To avoid confusion, it is recommended to avoid :command:`return()` in macros altogether. +Unlike a function, the :variable:`CMAKE_CURRENT_FUNCTION`, +:variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR`, +:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE`, +:variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE` variables are not +set for macro. + .. _`Argument Caveats`: Argument Caveats diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 84018b7cd3..4c797a5d26 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -37,6 +37,10 @@ Variables that Provide Information /variable/CMAKE_CROSSCOMPILING_EMULATOR /variable/CMAKE_CTEST_COMMAND /variable/CMAKE_CURRENT_BINARY_DIR + /variable/CMAKE_CURRENT_FUNCTION + /variable/CMAKE_CURRENT_FUNCTION_LIST_DIR + /variable/CMAKE_CURRENT_FUNCTION_LIST_FILE + /variable/CMAKE_CURRENT_FUNCTION_LIST_LINE /variable/CMAKE_CURRENT_LIST_DIR /variable/CMAKE_CURRENT_LIST_FILE /variable/CMAKE_CURRENT_LIST_LINE diff --git a/Help/release/dev/CMAKE_CURRENT_FUNCTION.rst b/Help/release/dev/CMAKE_CURRENT_FUNCTION.rst new file mode 100644 index 0000000000..a15e63d718 --- /dev/null +++ b/Help/release/dev/CMAKE_CURRENT_FUNCTION.rst @@ -0,0 +1,9 @@ +CMAKE_CURRENT_FUNCTION +---------------------- + +* Define the following variables inside a function: + + - :variable:`CMAKE_CURRENT_FUNCTION` + - :variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR` + - :variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE` + - :variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE` diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION.rst b/Help/variable/CMAKE_CURRENT_FUNCTION.rst new file mode 100644 index 0000000000..aa2936c440 --- /dev/null +++ b/Help/variable/CMAKE_CURRENT_FUNCTION.rst @@ -0,0 +1,6 @@ +CMAKE_CURRENT_FUNCTION +---------------------- + +When executing code inside a :command:`function`, this variable +contains the name of the current function. It can be used for +diagnostic or debug messages. diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst new file mode 100644 index 0000000000..0119381ae9 --- /dev/null +++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst @@ -0,0 +1,33 @@ +CMAKE_CURRENT_FUNCTION_LIST_DIR +------------------------------- + +When executing code inside a :command:`function`, this variable +contains the full directory of the listfile defining the current function. + +It is quite common practice in CMake that modules use some additional files +(e.g., templates to render). And the code typically did the following: + +.. code-block:: cmake + :caption: Bad + + set(_THIS_MODULE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}") + + function(foo) + configure_file( + "${_THIS_MODULE_BASE_DIR}/some.template.in" + some.output + ) + endfunction() + +Using this variable inside a function eliminates the neccessity of the +additional one with "global" scope: + +.. code-block:: cmake + :caption: Good + + function(foo) + configure_file( + "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/some.template.in" + some.output + ) + endfunction() diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst new file mode 100644 index 0000000000..d2c846ad64 --- /dev/null +++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst @@ -0,0 +1,5 @@ +CMAKE_CURRENT_FUNCTION_LIST_FILE +-------------------------------- + +When executing code inside a :command:`function`, this variable +contains the full path to the listfile declaring a current function. diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst new file mode 100644 index 0000000000..5a7cd13a08 --- /dev/null +++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst @@ -0,0 +1,5 @@ +CMAKE_CURRENT_FUNCTION_LIST_LINE +-------------------------------- + +When executing code inside a :command:`function`, this variable +contains the line number in the listfile where a current function has defined. diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index bd961156bf..4b2f145961 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -18,11 +18,19 @@ #include "cmRange.h" #include "cmState.h" #include "cmStringAlgorithms.h" +#include "cmSystemTools.h" namespace { std::string const ARGC = "ARGC"; std::string const ARGN = "ARGN"; std::string const ARGV = "ARGV"; +std::string const CMAKE_CURRENT_FUNCTION = "CMAKE_CURRENT_FUNCTION"; +std::string const CMAKE_CURRENT_FUNCTION_LIST_FILE = + "CMAKE_CURRENT_FUNCTION_LIST_FILE"; +std::string const CMAKE_CURRENT_FUNCTION_LIST_DIR = + "CMAKE_CURRENT_FUNCTION_LIST_DIR"; +std::string const CMAKE_CURRENT_FUNCTION_LIST_LINE = + "CMAKE_CURRENT_FUNCTION_LIST_LINE"; // define the class for function commands class cmFunctionHelperCommand @@ -39,6 +47,7 @@ public: std::vector Functions; cmPolicies::PolicyMap Policies; std::string FilePath; + long Line; }; bool cmFunctionHelperCommand::operator()( @@ -89,6 +98,17 @@ bool cmFunctionHelperCommand::operator()( makefile.AddDefinition(ARGN, argnDef); makefile.MarkVariableAsUsed(ARGN); + makefile.AddDefinition(CMAKE_CURRENT_FUNCTION, this->Args.front()); + makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION); + makefile.AddDefinition(CMAKE_CURRENT_FUNCTION_LIST_FILE, this->FilePath); + makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION_LIST_FILE); + makefile.AddDefinition(CMAKE_CURRENT_FUNCTION_LIST_DIR, + cmSystemTools::GetFilenamePath(this->FilePath)); + makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION_LIST_DIR); + makefile.AddDefinition(CMAKE_CURRENT_FUNCTION_LIST_LINE, + std::to_string(this->Line)); + makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION_LIST_LINE); + // Invoke all the functions that were collected in the block. // for each function for (cmListFileFunction const& func : this->Functions) { @@ -143,6 +163,7 @@ bool cmFunctionFunctionBlocker::Replay( f.Args = this->Args; f.Functions = std::move(functions); f.FilePath = this->GetStartingContext().FilePath; + f.Line = this->GetStartingContext().Line; mf.RecordPolicies(f.Policies); mf.GetState()->AddScriptedCommand(this->Args.front(), std::move(f)); return true; diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 31b280b779..18ac6f980e 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -272,6 +272,7 @@ add_RunCMake_test(find_package) add_RunCMake_test(find_path) add_RunCMake_test(find_program -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}) add_RunCMake_test(foreach) +add_RunCMake_test(function) add_RunCMake_test(get_filename_component) add_RunCMake_test(get_property) add_RunCMake_test(if) diff --git a/Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION-stdout.txt b/Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION-stdout.txt new file mode 100644 index 0000000000..5ebc89ae1c --- /dev/null +++ b/Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION-stdout.txt @@ -0,0 +1,7 @@ +function\(print_self\) + file\(STRINGS "\${CMAKE_CURRENT_FUNCTION_LIST_FILE}" _lines\) + math\(EXPR _begin "\${CMAKE_CURRENT_FUNCTION_LIST_LINE} - 1"\) + list\(SUBLIST _lines \${_begin} 7 _lines\) # This function has 7 lines only + list\(JOIN _lines "\\n" _lines\) + message\(STATUS "Print the `\${CMAKE_CURRENT_FUNCTION}` function:\\n\${_lines}"\) +endfunction\(\) diff --git a/Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION.cmake b/Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION.cmake new file mode 100644 index 0000000000..38c032ffdb --- /dev/null +++ b/Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION.cmake @@ -0,0 +1,94 @@ +set(_THIS_FILE "${CMAKE_CURRENT_LIST_FILE}") +set(_THIS_DIR "${CMAKE_CURRENT_LIST_DIR}") + +if(CMAKE_CURRENT_FUNCTION) + message(SEND_ERROR "`CMAKE_CURRENT_FUNCTION` is not expected to be set here") +endif() +if(CMAKE_CURRENT_FUNCTION_LIST_FILE) + message(SEND_ERROR "`CMAKE_CURRENT_FUNCTION_LIST_FILE` is not expected to be set here") +endif() +if(CMAKE_CURRENT_FUNCTION_LIST_DIR) + message(SEND_ERROR "`CMAKE_CURRENT_FUNCTION_LIST_DIR` is not expected to be set here") +endif() +if(CMAKE_CURRENT_FUNCTION_LIST_LINE) + message(SEND_ERROR "`CMAKE_CURRENT_FUNCTION_LIST_LINE` is not expected to be set here") +endif() + +function(bar) + if(NOT CMAKE_CURRENT_FUNCTION STREQUAL "bar") + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_FILE MATCHES "^.*/CMAKE_CURRENT_FUNCTION.cmake$") + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_FILE`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_FILE STREQUAL _THIS_FILE) + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_FILE`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_DIR MATCHES "^.*/Tests/RunCMake/function$") + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_DIR`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_DIR STREQUAL _THIS_DIR) + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_DIR`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_LINE EQUAL 17) + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_LINE`") + endif() +endfunction() + +function(foo) + if(NOT CMAKE_CURRENT_FUNCTION STREQUAL "foo") + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_FILE MATCHES "^.*/function/CMAKE_CURRENT_FUNCTION.cmake$") + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_FILE`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_FILE STREQUAL _THIS_FILE) + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_FILE`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_DIR MATCHES "^.*/Tests/RunCMake/function$") + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_DIR`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_LINE EQUAL 38) + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_LINE`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_DIR STREQUAL _THIS_DIR) + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_DIR`") + endif() + bar() +endfunction() + +foo() + +if(CMAKE_CURRENT_FUNCTION) + message(SEND_ERROR "`CMAKE_CURRENT_FUNCTION` is not expected to be set here") +endif() +if(CMAKE_CURRENT_FUNCTION_LIST_FILE) + message(SEND_ERROR "`CMAKE_CURRENT_FUNCTION_LIST_FILE` is not expected to be set here") +endif() +if(CMAKE_CURRENT_FUNCTION_LIST_DIR) + message(SEND_ERROR "`CMAKE_CURRENT_FUNCTION_LIST_DIR` is not expected to be set here") +endif() +if(CMAKE_CURRENT_FUNCTION_LIST_LINE) + message(SEND_ERROR "`CMAKE_CURRENT_FUNCTION_LIST_LINE` is not expected to be set here") +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/DummyMacro.cmake") + +function(calling_macro) + dummy() +endfunction() + +calling_macro() + +cmake_policy(SET CMP0007 NEW) + +# ATTENTION `CMAKE_CURRENT_LIST_LINE` can't be used in `math()' +function(print_self) + file(STRINGS "${CMAKE_CURRENT_FUNCTION_LIST_FILE}" _lines) + math(EXPR _begin "${CMAKE_CURRENT_FUNCTION_LIST_LINE} - 1") + list(SUBLIST _lines ${_begin} 7 _lines) # This function has 7 lines only + list(JOIN _lines "\n" _lines) + message(STATUS "Print the `${CMAKE_CURRENT_FUNCTION}` function:\n${_lines}") +endfunction() + +print_self() diff --git a/Tests/RunCMake/function/CMakeLists.txt b/Tests/RunCMake/function/CMakeLists.txt new file mode 100644 index 0000000000..2632ffa91f --- /dev/null +++ b/Tests/RunCMake/function/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.16) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/function/DummyMacro.cmake b/Tests/RunCMake/function/DummyMacro.cmake new file mode 100644 index 0000000000..1ab53e419c --- /dev/null +++ b/Tests/RunCMake/function/DummyMacro.cmake @@ -0,0 +1,20 @@ +macro(dummy) + if(NOT CMAKE_CURRENT_FUNCTION STREQUAL "calling_macro") + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_FILE MATCHES "^.*/function/CMAKE_CURRENT_FUNCTION.cmake$") + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_FILE`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_FILE STREQUAL _THIS_FILE) + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_FILE`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_DIR MATCHES "^.*/Tests/RunCMake/function$") + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_DIR`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_LINE EQUAL 77) + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_LINE`") + endif() + if(NOT CMAKE_CURRENT_FUNCTION_LIST_DIR STREQUAL _THIS_DIR) + message(SEND_ERROR "Bad value of `CMAKE_CURRENT_FUNCTION_LIST_DIR`") + endif() +endmacro() diff --git a/Tests/RunCMake/function/RunCMakeTest.cmake b/Tests/RunCMake/function/RunCMakeTest.cmake new file mode 100644 index 0000000000..88f48af391 --- /dev/null +++ b/Tests/RunCMake/function/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(CMAKE_CURRENT_FUNCTION) From 24fdd51f4503ccee33c07881cc8dd487cdc8b347 Mon Sep 17 00:00:00 2001 From: Alex Turbov Date: Sun, 8 Dec 2019 02:39:02 +0200 Subject: [PATCH 3/3] Refactor: Replace CMAKE_CURRENT_LIST_DIR with CMAKE_CURRENT_FUNCTION_LIST_DIR Some modules define an intermediate global scope visible variables to access "resource" files from functions. Now these variables could be eliminated. --- Modules/AndroidTestUtilities.cmake | 4 +--- Modules/CMakeAddFortranSubdirectory.cmake | 5 ++--- Modules/DeployQt4.cmake | 3 +-- Modules/FetchContent.cmake | 5 +---- Modules/UseJava.cmake | 3 +-- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/Modules/AndroidTestUtilities.cmake b/Modules/AndroidTestUtilities.cmake index e333cdbc6a..95e2ef7e94 100644 --- a/Modules/AndroidTestUtilities.cmake +++ b/Modules/AndroidTestUtilities.cmake @@ -76,8 +76,6 @@ Module Functions include(${CMAKE_CURRENT_LIST_DIR}/ExternalData.cmake) -set(_AndroidTestUtilities_SELF_DIR "${CMAKE_CURRENT_LIST_DIR}") - # The parameters to this function should be set to the list of directories, # files, and libraries that need to be installed prior to testing. function(android_add_test_data test_name) @@ -159,6 +157,6 @@ function(android_add_test_data test_name) "-Darg_files=${processed_FILES}" "-Darg_libs=${AST_LIBS}" "-Darg_src_dir=${CMAKE_CURRENT_SOURCE_DIR}" - -P ${_AndroidTestUtilities_SELF_DIR}/AndroidTestUtilities/PushToAndroidDevice.cmake) + -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/AndroidTestUtilities/PushToAndroidDevice.cmake) endif() endfunction() diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index 2613569d19..d4b537f67d 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -43,7 +43,6 @@ future version that supports installation of the external project binaries during ``make install``. #]=======================================================================] -set(_MS_MINGW_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) include(CheckLanguage) include(ExternalProject) @@ -87,11 +86,11 @@ function(_setup_mingw_config_and_build source_dir build_dir) file(TO_NATIVE_PATH "${MINGW_PATH}" MINGW_PATH) string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}") configure_file( - ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/config_mingw.cmake.in + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/CMakeAddFortranSubdirectory/config_mingw.cmake.in ${build_dir}/config_mingw.cmake @ONLY) configure_file( - ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/build_mingw.cmake.in + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/CMakeAddFortranSubdirectory/build_mingw.cmake.in ${build_dir}/build_mingw.cmake @ONLY) endfunction() diff --git a/Modules/DeployQt4.cmake b/Modules/DeployQt4.cmake index 4a18927c25..9aa43838e5 100644 --- a/Modules/DeployQt4.cmake +++ b/Modules/DeployQt4.cmake @@ -106,7 +106,6 @@ and plugin installation. See documentation of FIXUP_QT4_BUNDLE. # The functions defined in this file depend on the fixup_bundle function # (and others) found in BundleUtilities.cmake -set(DeployQt4_cmake_dir "${CMAKE_CURRENT_LIST_DIR}") set(DeployQt4_apple_plugins_dir "PlugIns") function(write_qt4_conf qt_conf_dir qt_conf_contents) @@ -392,7 +391,7 @@ function(install_qt4_executable executable) resolve_qt4_paths(libs "") install(CODE -"include(\"${DeployQt4_cmake_dir}/DeployQt4.cmake\") +"include(\"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/DeployQt4.cmake\") set(BU_CHMOD_BUNDLE_ITEMS TRUE) FIXUP_QT4_EXECUTABLE(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")" ${component} diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 5716b0112f..f3e1b51ff9 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -596,9 +596,6 @@ current working directory. #]=======================================================================] - -set(__FetchContent_privateDir "${CMAKE_CURRENT_LIST_DIR}/FetchContent") - #======================================================================= # Recording and retrieving content details for later population #======================================================================= @@ -888,7 +885,7 @@ function(__FetchContent_directPopulate contentName) # anything to be updated, so extra rebuilds of the project won't occur. # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project # has this set to something not findable on the PATH. - configure_file("${__FetchContent_privateDir}/CMakeLists.cmake.in" + configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent/CMakeLists.cmake.in" "${ARG_SUBBUILD_DIR}/CMakeLists.txt") execute_process( COMMAND ${CMAKE_COMMAND} ${generatorOpts} . diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 07984885bc..a73fc2a6ef 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -405,7 +405,6 @@ endfunction() # define helper scripts set(_JAVA_EXPORT_TARGETS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/javaTargets.cmake.in) -set(_JAVA_CLASS_FILELIST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaClassFilelist.cmake) set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake) function(add_jar _TARGET_NAME) @@ -627,7 +626,7 @@ function(add_jar _TARGET_NAME) COMMAND ${CMAKE_COMMAND} -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH} -DCMAKE_JAR_CLASSES_PREFIX="${CMAKE_JAR_CLASSES_PREFIX}" - -P ${_JAVA_CLASS_FILELIST_SCRIPT} + -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJavaClassFilelist.cmake DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )