diff options
author | Stephen Kelly <steveire@gmail.com> | 2013-06-04 08:30:24 (GMT) |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2013-06-04 09:36:55 (GMT) |
commit | a984f3257e95f29a72da6566859d4c6a8a5d749b (patch) | |
tree | f174238c2d4c5b582fd5f892ea1c64e2b8418c06 | |
parent | 00c3840cc8c36adea76c6e833a9e2069645aec8a (diff) | |
download | CMake-a984f3257e95f29a72da6566859d4c6a8a5d749b.zip CMake-a984f3257e95f29a72da6566859d4c6a8a5d749b.tar.gz CMake-a984f3257e95f29a72da6566859d4c6a8a5d749b.tar.bz2 |
Introduce add_compile_options command.
This command is similar to add_definitions, in that it affects
the compile options of all targets which follow it. The implementation
is similar to the implementation of the include_directories command,
in that it is based on populating a COMPILE_OPTIONS directory property
and using that to initialize the same property on targets.
Unlike the include_directories command however, the add_compile_options
command does not affect previously defined targets. That is, in
the following code, foo will not be compiled with -Wall, but bar
will be:
add_library(foo ...)
add_compile_options(-Wall)
add_library(bar ...)
-rw-r--r-- | Source/cmAddCompileOptionsCommand.cxx | 28 | ||||
-rw-r--r-- | Source/cmAddCompileOptionsCommand.h | 72 | ||||
-rw-r--r-- | Source/cmCommands.cxx | 2 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 60 | ||||
-rw-r--r-- | Source/cmMakefile.h | 6 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 10 | ||||
-rw-r--r-- | Tests/CMakeCommands/add_compile_options/CMakeLists.txt | 14 | ||||
-rw-r--r-- | Tests/CMakeCommands/add_compile_options/main.cpp | 11 |
8 files changed, 202 insertions, 1 deletions
diff --git a/Source/cmAddCompileOptionsCommand.cxx b/Source/cmAddCompileOptionsCommand.cxx new file mode 100644 index 0000000..a6c3c00 --- /dev/null +++ b/Source/cmAddCompileOptionsCommand.cxx @@ -0,0 +1,28 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmAddCompileOptionsCommand.h" + +bool cmAddCompileOptionsCommand +::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) +{ + if(args.size() < 1 ) + { + return true; + } + + for(std::vector<std::string>::const_iterator i = args.begin(); + i != args.end(); ++i) + { + this->Makefile->AddCompileOption(i->c_str()); + } + return true; +} diff --git a/Source/cmAddCompileOptionsCommand.h b/Source/cmAddCompileOptionsCommand.h new file mode 100644 index 0000000..4504795 --- /dev/null +++ b/Source/cmAddCompileOptionsCommand.h @@ -0,0 +1,72 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmAddCompileOptionsCommand_h +#define cmAddCompileOptionsCommand_h + +#include "cmCommand.h" +#include "cmDocumentGeneratorExpressions.h" + +class cmAddCompileOptionsCommand : public cmCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmAddCompileOptionsCommand; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus &status); + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() const {return "add_compile_options";} + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() const + { + return "Adds options to the compilation of source files."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() const + { + return + " add_compile_options(<option> ...)\n" + "Adds options to the compiler command line for sources in the " + "current directory and below. This command can be used to add any " + "options, but alternative commands exist to add preprocessor " + "definitions or include directories. " + "See documentation of the directory and target COMPILE_OPTIONS " + "properties for details. " + "Arguments to add_compile_options may use \"generator " + "expressions\" with the syntax \"$<...>\". " + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS + ; + } + + cmTypeMacro(cmAddCompileOptionsCommand, cmCommand); +}; + +#endif diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 75f2ae8..3cfbf43 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmCommands.h" #if defined(CMAKE_BUILD_WITH_CMAKE) +#include "cmAddCompileOptionsCommand.cxx" #include "cmAuxSourceDirectoryCommand.cxx" #include "cmBuildNameCommand.cxx" #include "cmElseIfCommand.cxx" @@ -52,6 +53,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& ) { #if defined(CMAKE_BUILD_WITH_CMAKE) + commands.push_back(new cmAddCompileOptionsCommand); commands.push_back(new cmAuxSourceDirectoryCommand); commands.push_back(new cmBuildNameCommand); commands.push_back(new cmElseIfCommand); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 606ec93..e1c1241 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -21,6 +21,7 @@ #include "cmCacheManager.h" #include "cmFunctionBlocker.h" #include "cmListFileCache.h" +#include "cmDocumentGeneratorExpressions.h" #include "cmCommandArgumentParserHelper.h" #include "cmDocumentCompileDefinitions.h" #include "cmGeneratorExpression.h" @@ -1270,6 +1271,11 @@ void cmMakefile::RemoveDefineFlag(const char* flag, } } +void cmMakefile::AddCompileOption(const char* option) +{ + this->AppendProperty("COMPILE_OPTIONS", option); +} + bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove) { // Create a regular expression to match valid definitions. @@ -1493,6 +1499,12 @@ void cmMakefile::InitializeFromParent() parentIncludes.begin(), parentIncludes.end()); + const std::vector<cmValueWithOrigin> parentOptions = + parent->GetCompileOptionsEntries(); + this->CompileOptionsEntries.insert(this->CompileOptionsEntries.end(), + parentOptions.begin(), + parentOptions.end()); + this->SystemIncludeDirectories = parent->SystemIncludeDirectories; // define flags @@ -3468,6 +3480,18 @@ void cmMakefile::SetProperty(const char* prop, const char* value) cmValueWithOrigin(value, lfbt)); return; } + if (propname == "COMPILE_OPTIONS") + { + this->CompileOptionsEntries.clear(); + if (!value) + { + return; + } + cmListFileBacktrace lfbt; + this->GetBacktrace(lfbt); + this->CompileOptionsEntries.push_back(cmValueWithOrigin(value, lfbt)); + return; + } if ( propname == "INCLUDE_REGULAR_EXPRESSION" ) { @@ -3507,6 +3531,14 @@ void cmMakefile::AppendProperty(const char* prop, const char* value, cmValueWithOrigin(value, lfbt)); return; } + if (propname == "COMPILE_OPTIONS") + { + cmListFileBacktrace lfbt; + this->GetBacktrace(lfbt); + this->CompileOptionsEntries.push_back( + cmValueWithOrigin(value, lfbt)); + return; + } if ( propname == "LINK_DIRECTORIES" ) { std::vector<std::string> varArgsExpanded; @@ -3632,6 +3664,20 @@ const char *cmMakefile::GetProperty(const char* prop, } return output.c_str(); } + else if (!strcmp("COMPILE_OPTIONS",prop)) + { + std::string sep; + for (std::vector<cmValueWithOrigin>::const_iterator + it = this->CompileOptionsEntries.begin(), + end = this->CompileOptionsEntries.end(); + it != end; ++it) + { + output += sep; + output += it->Value; + sep = ";"; + } + return output.c_str(); + } bool chain = false; const char *retVal = @@ -4003,6 +4049,20 @@ void cmMakefile::DefineProperties(cmake *cm) "See also the include_directories command."); cm->DefineProperty + ("COMPILE_OPTIONS", cmProperty::DIRECTORY, + "List of options to pass to the compiler.", + "This property specifies the list of directories given " + "so far for this property. " + "This property exists on directories and targets. " + "\n" + "The target property values are used by the generators to set " + "the options for the compiler.\n" + "Contents of COMPILE_OPTIONS may use \"generator expressions\" with " + "the syntax \"$<...>\". " + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS); + + cm->DefineProperty ("LINK_DIRECTORIES", cmProperty::DIRECTORY, "List of linker search directories.", "This read-only property specifies the list of directories given " diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 74a731d..0a87752 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -206,6 +206,7 @@ public: */ void AddDefineFlag(const char* definition); void RemoveDefineFlag(const char* definition); + void AddCompileOption(const char* option); /** Create a new imported target with the name and type given. */ cmTarget* AddImportedTarget(const char* name, cmTarget::TargetType type, @@ -866,6 +867,10 @@ public: { return this->IncludeDirectoriesEntries; } + std::vector<cmValueWithOrigin> GetCompileOptionsEntries() const + { + return this->CompileOptionsEntries; + } bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; } void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; } @@ -919,6 +924,7 @@ protected: std::string DefineFlags; std::vector<cmValueWithOrigin> IncludeDirectoriesEntries; + std::vector<cmValueWithOrigin> CompileOptionsEntries; // Track the value of the computed DEFINITIONS property. void AddDefineFlag(const char*, std::string&); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index f1d0ac3..eb1e3b2 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -297,7 +297,7 @@ void cmTarget::DefineProperties(cmake *cm) "List of options to pass to the compiler.", "This property specifies the list of options specified " "so far for this property. " - "This property exists on targets only. " + "This property exists on directories and targets. " "\n" "The target property values are used by the generators to set " "the options for the compiler.\n" @@ -1611,6 +1611,14 @@ void cmTarget::SetMakefile(cmMakefile* mf) { this->InsertInclude(*it); } + const std::vector<cmValueWithOrigin> parentOptions = + this->Makefile->GetCompileOptionsEntries(); + + for (std::vector<cmValueWithOrigin>::const_iterator it + = parentOptions.begin(); it != parentOptions.end(); ++it) + { + this->InsertCompileOption(*it); + } if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY || this->TargetTypeValue == cmTarget::MODULE_LIBRARY) diff --git a/Tests/CMakeCommands/add_compile_options/CMakeLists.txt b/Tests/CMakeCommands/add_compile_options/CMakeLists.txt new file mode 100644 index 0000000..1652cf6 --- /dev/null +++ b/Tests/CMakeCommands/add_compile_options/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 2.8) + +project(add_compile_options) + +add_compile_options(-DTEST_OPTION) + +add_executable(add_compile_options main.cpp) + +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + target_compile_definitions(add_compile_options + PRIVATE + "DO_GNU_TESTS" + ) +endif() diff --git a/Tests/CMakeCommands/add_compile_options/main.cpp b/Tests/CMakeCommands/add_compile_options/main.cpp new file mode 100644 index 0000000..2bb20ac --- /dev/null +++ b/Tests/CMakeCommands/add_compile_options/main.cpp @@ -0,0 +1,11 @@ + +#ifdef DO_GNU_TESTS +# ifndef TEST_OPTION +# error Expected TEST_OPTION +# endif +#endif + +int main(void) +{ + return 0; +} |