From 33e865c041d95e383ce7e843a1a785cda78d13b7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 25 Aug 2008 10:31:29 -0400 Subject: ENH: Add unset() command. This introduces the unset() command to make it easy to unset CMake variables, environment variables, and CMake cache variables. Previously it was not even possible to unset ENV or CACHE variables (as in completely remove them). Changes based on patch from Philip Lowman. See issue #7507. --- Docs/cmake-syntax.vim | 4 +- Source/cmBootstrapCommands.cxx | 2 + Source/cmCacheManager.cxx | 4 -- Source/cmMakefile.cxx | 5 +++ Source/cmMakefile.h | 2 + Source/cmSetCommand.h | 5 ++- Source/cmUnsetCommand.cxx | 64 ++++++++++++++++++++++++++++++++ Source/cmUnsetCommand.h | 84 ++++++++++++++++++++++++++++++++++++++++++ Tests/CMakeLists.txt | 1 + Tests/Unset/CMakeLists.txt | 40 ++++++++++++++++++++ Tests/Unset/unset.cc | 4 ++ 11 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 Source/cmUnsetCommand.cxx create mode 100644 Source/cmUnsetCommand.h create mode 100644 Tests/Unset/CMakeLists.txt create mode 100644 Tests/Unset/unset.cc diff --git a/Docs/cmake-syntax.vim b/Docs/cmake-syntax.vim index 17c2b32..80b348e 100644 --- a/Docs/cmake-syntax.vim +++ b/Docs/cmake-syntax.vim @@ -41,7 +41,7 @@ syn region cmakeString start=/"/ end=/"/ syn region cmakeArguments start=/(/ end=/)/ \ contains=ALLBUT,cmakeArguments,cmakeTodo syn keyword cmakeSystemVariables - \ WIN32 UNIX APPLE CYGWIN BORLAND MINGW MSVC MSVC_IDE MSVC60 MSVC70 MSVC71 MSVC80 + \ WIN32 UNIX APPLE CYGWIN BORLAND MINGW MSVC MSVC_IDE MSVC60 MSVC70 MSVC71 MSVC80 MSVC90 syn keyword cmakeOperators \ ABSOLUTE AND BOOL CACHE COMMAND DEFINED DOC EQUAL EXISTS EXT FALSE GREATER INTERNAL LESS MATCHES NAME NAMES NAME_WE NOT OFF ON OR PATH PATHS PROGRAM STREQUAL STRGREATER STRING STRLESS TRUE \ contained @@ -50,7 +50,7 @@ syn keyword cmakeDeprecated ABSTRACT_FILES BUILD_NAME SOURCE_FILES SOURCE_FILES_ " The keywords are generated as: cmake --help-command-list | tr "\n" " " syn keyword cmakeStatement - \ ADD_CUSTOM_COMMAND ADD_CUSTOM_TARGET ADD_DEFINITIONS ADD_DEPENDENCIES ADD_EXECUTABLE ADD_LIBRARY ADD_SUBDIRECTORY ADD_TEST AUX_SOURCE_DIRECTORY BUILD_COMMAND BUILD_NAME CMAKE_MINIMUM_REQUIRED CONFIGURE_FILE CREATE_TEST_SOURCELIST ELSE ELSEIF ENABLE_LANGUAGE ENABLE_TESTING ENDFOREACH ENDFUNCTION ENDIF ENDMACRO ENDWHILE EXEC_PROGRAM EXECUTE_PROCESS EXPORT_LIBRARY_DEPENDENCIES FILE FIND_FILE FIND_LIBRARY FIND_PACKAGE FIND_PATH FIND_PROGRAM FLTK_WRAP_UI FOREACH FUNCTION GET_CMAKE_PROPERTY GET_DIRECTORY_PROPERTY GET_FILENAME_COMPONENT GET_SOURCE_FILE_PROPERTY GET_TARGET_PROPERTY GET_TEST_PROPERTY IF INCLUDE INCLUDE_DIRECTORIES INCLUDE_EXTERNAL_MSPROJECT INCLUDE_REGULAR_EXPRESSION INSTALL INSTALL_FILES INSTALL_PROGRAMS INSTALL_TARGETS LINK_DIRECTORIES LINK_LIBRARIES LIST LOAD_CACHE LOAD_COMMAND MACRO MAKE_DIRECTORY MARK_AS_ADVANCED MATH MESSAGE OPTION OUTPUT_REQUIRED_FILES PROJECT QT_WRAP_CPP QT_WRAP_UI REMOVE REMOVE_DEFINITIONS SEPARATE_ARGUMENTS SET SET_DIRECTORY_PROPERTIES SET_SOURCE_FILES_PROPERTIES SET_TARGET_PROPERTIES SET_TESTS_PROPERTIES SITE_NAME SOURCE_GROUP STRING SUBDIR_DEPENDS SUBDIRS TARGET_LINK_LIBRARIES TRY_COMPILE TRY_RUN USE_MANGLED_MESA UTILITY_SOURCE VARIABLE_REQUIRES VTK_MAKE_INSTANTIATOR VTK_WRAP_JAVA VTK_WRAP_PYTHON VTK_WRAP_TCL WHILE WRITE_FILE + \ ADD_CUSTOM_COMMAND ADD_CUSTOM_TARGET ADD_DEFINITIONS ADD_DEPENDENCIES ADD_EXECUTABLE ADD_LIBRARY ADD_SUBDIRECTORY ADD_TEST AUX_SOURCE_DIRECTORY BUILD_COMMAND BUILD_NAME CMAKE_MINIMUM_REQUIRED CONFIGURE_FILE CREATE_TEST_SOURCELIST ELSE ELSEIF ENABLE_LANGUAGE ENABLE_TESTING ENDFOREACH ENDFUNCTION ENDIF ENDMACRO ENDWHILE EXEC_PROGRAM EXECUTE_PROCESS EXPORT_LIBRARY_DEPENDENCIES FILE FIND_FILE FIND_LIBRARY FIND_PACKAGE FIND_PATH FIND_PROGRAM FLTK_WRAP_UI FOREACH FUNCTION GET_CMAKE_PROPERTY GET_DIRECTORY_PROPERTY GET_FILENAME_COMPONENT GET_SOURCE_FILE_PROPERTY GET_TARGET_PROPERTY GET_TEST_PROPERTY IF INCLUDE INCLUDE_DIRECTORIES INCLUDE_EXTERNAL_MSPROJECT INCLUDE_REGULAR_EXPRESSION INSTALL INSTALL_FILES INSTALL_PROGRAMS INSTALL_TARGETS LINK_DIRECTORIES LINK_LIBRARIES LIST LOAD_CACHE LOAD_COMMAND MACRO MAKE_DIRECTORY MARK_AS_ADVANCED MATH MESSAGE OPTION OUTPUT_REQUIRED_FILES PROJECT QT_WRAP_CPP QT_WRAP_UI REMOVE REMOVE_DEFINITIONS SEPARATE_ARGUMENTS SET SET_DIRECTORY_PROPERTIES SET_SOURCE_FILES_PROPERTIES SET_TARGET_PROPERTIES SET_TESTS_PROPERTIES SITE_NAME SOURCE_GROUP STRING SUBDIR_DEPENDS SUBDIRS TARGET_LINK_LIBRARIES TRY_COMPILE TRY_RUN UNSET USE_MANGLED_MESA UTILITY_SOURCE VARIABLE_REQUIRES VTK_MAKE_INSTANTIATOR VTK_WRAP_JAVA VTK_WRAP_PYTHON VTK_WRAP_TCL WHILE WRITE_FILE \ nextgroup=cmakeArguments syn keyword cmakeTodo \ TODO FIXME XXX diff --git a/Source/cmBootstrapCommands.cxx b/Source/cmBootstrapCommands.cxx index b8031fc..f14b024 100644 --- a/Source/cmBootstrapCommands.cxx +++ b/Source/cmBootstrapCommands.cxx @@ -93,6 +93,7 @@ #include "cmTargetLinkLibrariesCommand.cxx" #include "cmTryCompileCommand.cxx" #include "cmTryRunCommand.cxx" +#include "cmUnsetCommand.cxx" void GetBootstrapCommands(std::list& commands) { @@ -163,4 +164,5 @@ void GetBootstrapCommands(std::list& commands) commands.push_back(new cmTargetLinkLibrariesCommand); commands.push_back(new cmTryCompileCommand); commands.push_back(new cmTryRunCommand); + commands.push_back(new cmUnsetCommand); } diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index bd95354..52cb448 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -714,10 +714,6 @@ void cmCacheManager::RemoveCacheEntry(const char* key) { this->Cache.erase(i); } - else - { - std::cerr << "Failed to remove entry:" << key << std::endl; - } } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 102ca44..a251462 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1648,6 +1648,11 @@ void cmMakefile::RemoveDefinition(const char* name) #endif } +void cmMakefile::RemoveCacheDefinition(const char* name) +{ + this->GetCacheManager()->RemoveCacheEntry(name); +} + void cmMakefile::SetProjectName(const char* p) { this->ProjectName = p; diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index f9d10b6..f78a1dd 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -278,6 +278,8 @@ public: * for cache entries, and will only affect the current makefile. */ void RemoveDefinition(const char* name); + ///! Remove a definition from the cache. + void RemoveCacheDefinition(const char* name); /** * Specify the name of the project for this build. diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h index e818d6a..39d0bc3 100644 --- a/Source/cmSetCommand.h +++ b/Source/cmSetCommand.h @@ -87,8 +87,9 @@ public: "above the current scope. Each new directory or function creates a new " "scope. This command will set the value of a variable into the parent " "directory or calling function (whichever is applicable to the case at " - "hand) If VALUE is not specified then the variable is removed from the " - "parent scope.\n" + "hand).\n" + "If is not specified then the variable is removed " + "instead of set. See also: the unset() command.\n" " set( ... )\n" "In this case is set to a semicolon separated list of " "values.\n" diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx new file mode 100644 index 0000000..d45b50b --- /dev/null +++ b/Source/cmUnsetCommand.cxx @@ -0,0 +1,64 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmUnsetCommand.h" + +// cmUnsetCommand +bool cmUnsetCommand::InitialPass(std::vector const& args, + cmExecutionStatus &) +{ + if(args.size() < 1 || args.size() > 2) + { + this->SetError("called with incorrect number of arguments"); + return false; + } + + const char* variable = args[0].c_str(); + + // unset(ENV{VAR}) + if (!strncmp(variable,"ENV{",4) && strlen(variable) > 5) + { + // what is the variable name + char *envVarName = new char [strlen(variable)]; + strncpy(envVarName,variable+4,strlen(variable)-5); + envVarName[strlen(variable)-5] = '\0'; + +#ifdef CMAKE_BUILD_WITH_CMAKE + cmSystemTools::UnsetEnv(envVarName); +#endif + delete[] envVarName; + return true; + } + // unset(VAR) + else if (args.size() == 1) + { + this->Makefile->RemoveDefinition(variable); + return true; + } + // unset(VAR CACHE) + else if ((args.size() == 2) && (args[1] == "CACHE")) + { + this->Makefile->RemoveCacheDefinition(variable); + return true; + } + // ERROR: second argument isn't CACHE + else + { + this->SetError("called with an invalid second argument"); + return false; + } +} + diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h new file mode 100644 index 0000000..d125a18 --- /dev/null +++ b/Source/cmUnsetCommand.h @@ -0,0 +1,84 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmUnsetCommand_h +#define cmUnsetCommand_h + +#include "cmCommand.h" + +/** \class cmUnsetCommand + * \brief Unset a CMAKE variable + * + * cmUnsetCommand unsets or removes a variable. + */ +class cmUnsetCommand : public cmCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmUnsetCommand; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector const& args, + cmExecutionStatus &status); + + /** + * This determines if the command is invoked when in script mode. + */ + virtual bool IsScriptable() { return true; } + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() {return "unset";} + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() + { + return "Unset a variable, cache variable, or environment variable."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() + { + return + " unset( [CACHE])\n" + "Removes the specified variable causing it to become undefined. " + "If CACHE is present then the variable is removed from the cache " + "instead of the current scope.\n" + " can be an environment variable such as:\n" + " unset(ENV{LD_LIBRARY_PATH})\n" + "in which case the variable will be removed from the current " + "environment."; + } + + cmTypeMacro(cmUnsetCommand, cmCommand); +}; + + + +#endif diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index ce0cd42..14366b3 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -94,6 +94,7 @@ IF(BUILD_TESTING) ADD_TEST_MACRO(SourceGroups SourceGroups) ADD_TEST_MACRO(Preprocess Preprocess) ADD_TEST_MACRO(ExportImport ExportImport) + ADD_TEST_MACRO(Unset Unset) # If we are running right now with a UnixMakefiles based generator, diff --git a/Tests/Unset/CMakeLists.txt b/Tests/Unset/CMakeLists.txt new file mode 100644 index 0000000..6260950 --- /dev/null +++ b/Tests/Unset/CMakeLists.txt @@ -0,0 +1,40 @@ +project(Unset) + +# Local variable +set(x 42) +if(NOT x EQUAL 42) + message(FATAL_ERROR "x!=42") +endif(NOT x EQUAL 42) + +if(NOT DEFINED x) + message(FATAL_ERROR "x should be defined!") +endif(NOT DEFINED x) + +unset(x) +if(DEFINED x) + message(FATAL_ERROR "x should be undefined now!") +endif(DEFINED x) + +# Local variable test unset via set() +set(x 43) +if(NOT x EQUAL 43) + message(FATAL_ERROR "x!=43") +endif(NOT x EQUAL 43) +set(x) +if(DEFINED x) + message(FATAL_ERROR "x should be undefined now!") +endif(DEFINED x) + +# Cache variable +set(BAR "test" CACHE STRING "documentation") +if(NOT DEFINED BAR) + message(FATAL_ERROR "BAR not defined") +endif(NOT DEFINED BAR) + +unset(BAR CACHE) +if(DEFINED BAR) + message(FATAL_ERROR "BAR still defined") +endif(DEFINED BAR) + + +add_executable(Unset unset.cc) diff --git a/Tests/Unset/unset.cc b/Tests/Unset/unset.cc new file mode 100644 index 0000000..f8b643a --- /dev/null +++ b/Tests/Unset/unset.cc @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} -- cgit v0.12