Explorar o código

add_compile_definitions: add new command

This command manages preprocessor definitions at directory level and
supports generator expressions.

Fixes: #15374
Marc Chevrier %!s(int64=7) %!d(string=hai) anos
pai
achega
cb83314e65

+ 23 - 0
Help/command/add_compile_definitions.rst

@@ -0,0 +1,23 @@
+add_compile_definitions
+-----------------------
+
+Adds preprocessor definitions to the compilation of source files.
+
+::
+
+  add_compile_definitions(<definition> ...)
+
+Adds preprocessor definitions to the compiler command line for targets in the
+current directory and below that are added after this command is invoked.
+See documentation of the :prop_dir:`directory <COMPILE_DEFINITIONS>` and
+:prop_tgt:`target <COMPILE_DEFINITIONS>` ``COMPILE_DEFINITIONS`` properties.
+
+Definitions are specified using the syntax ``VAR`` or ``VAR=value``.
+Function-style definitions are not supported. CMake will automatically
+escape the value correctly for the native build system (note that CMake
+language syntax may require escapes to specify some values).
+
+Arguments to ``add_compile_definitions`` may use "generator expressions" with
+the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.

+ 1 - 1
Help/command/add_compile_options.rst

@@ -14,7 +14,7 @@ See documentation of the :prop_dir:`directory <COMPILE_OPTIONS>` and
 
 This command can be used to add any options, but alternative commands
 exist to add preprocessor definitions (:command:`target_compile_definitions`
-and :command:`add_definitions`) or include directories
+and :command:`add_compile_definitions`) or include directories
 (:command:`target_include_directories` and :command:`include_directories`).
 
 Arguments to ``add_compile_options`` may use "generator expressions" with

+ 10 - 2
Help/command/add_definitions.rst

@@ -10,8 +10,16 @@ Adds -D define flags to the compilation of source files.
 Adds definitions to the compiler command line for targets in the current
 directory and below (whether added before or after this command is invoked).
 This command can be used to add any flags, but it is intended to add
-preprocessor definitions (see the :command:`add_compile_options` command
-to add other flags).
+preprocessor definitions.
+
+.. note::
+
+  This command has been superseded by alternatives:
+
+  * Use :command:`add_compile_definitions` to add preprocessor definitions.
+  * Use :command:`include_directories` to add include directories.
+  * Use :command:`add_compile_options` to add other options.
+
 Flags beginning in -D or /D that look like preprocessor definitions are
 automatically added to the :prop_dir:`COMPILE_DEFINITIONS` directory
 property for the current directory.  Definitions with non-trivial values

+ 2 - 2
Help/command/target_compile_options.rst

@@ -19,8 +19,8 @@ instead of being appended.
 
 This command can be used to add any options, but
 alternative commands exist to add preprocessor definitions
-(:command:`target_compile_definitions` and :command:`add_definitions`) or
-include directories (:command:`target_include_directories` and
+(:command:`target_compile_definitions` and :command:`add_compile_definitions`)
+or include directories (:command:`target_include_directories` and
 :command:`include_directories`).  See documentation of the
 :prop_dir:`directory <COMPILE_OPTIONS>` and
 :prop_tgt:`target <COMPILE_OPTIONS>` ``COMPILE_OPTIONS`` properties.

+ 1 - 1
Help/manual/cmake-buildsystem.7.rst

@@ -821,7 +821,7 @@ Directory-Scoped Commands
 The :command:`target_include_directories`,
 :command:`target_compile_definitions` and
 :command:`target_compile_options` commands have an effect on only one
-target at a time.  The commands :command:`add_definitions`,
+target at a time.  The commands :command:`add_compile_definitions`,
 :command:`add_compile_options` and :command:`include_directories` have
 a similar function, but operate at directory scope instead of target
 scope for convenience.

+ 1 - 0
Help/manual/cmake-commands.7.rst

@@ -70,6 +70,7 @@ These commands are available only in CMake projects.
 .. toctree::
    :maxdepth: 1
 
+   /command/add_compile_definitions
    /command/add_compile_options
    /command/add_custom_command
    /command/add_custom_target

+ 1 - 1
Help/prop_dir/COMPILE_DEFINITIONS.rst

@@ -4,7 +4,7 @@ COMPILE_DEFINITIONS
 Preprocessor definitions for compiling a directory's sources.
 
 This property specifies the list of options given so far to the
-:command:`add_definitions` command.
+:command:`add_compile_definitions` (or :command:`add_definitions`) command.
 
 The ``COMPILE_DEFINITIONS`` property may be set to a semicolon-separated
 list of preprocessor definitions using the syntax ``VAR`` or ``VAR=value``.

+ 5 - 0
Help/release/dev/command-add_compile_definitions.rst

@@ -0,0 +1,5 @@
+command-add_compile_definitions
+-------------------------------
+
+* The :command:`add_compile_definitions` command was added to set preprocessor
+  definitions at directory level.  This supersedes :command:`add_definitions`.

+ 2 - 0
Source/CMakeLists.txt

@@ -375,6 +375,8 @@ set(SRCS
   cmCommand.h
   cmCommands.cxx
   cmCommands.h
+  cmAddCompileDefinitionsCommand.cxx
+  cmAddCompileDefinitionsCommand.h
   cmAddCompileOptionsCommand.cxx
   cmAddCompileOptionsCommand.h
   cmAddCustomCommandCommand.cxx

+ 20 - 0
Source/cmAddCompileDefinitionsCommand.cxx

@@ -0,0 +1,20 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#include "cmAddCompileDefinitionsCommand.h"
+
+#include "cmMakefile.h"
+
+class cmExecutionStatus;
+
+bool cmAddCompileDefinitionsCommand::InitialPass(
+  std::vector<std::string> const& args, cmExecutionStatus&)
+{
+  if (args.empty()) {
+    return true;
+  }
+
+  for (std::string const& i : args) {
+    this->Makefile->AddCompileDefinition(i);
+  }
+  return true;
+}

+ 31 - 0
Source/cmAddCompileDefinitionsCommand.h

@@ -0,0 +1,31 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmAddCompileDefinitionsCommand_h
+#define cmAddCompileDefinitionsCommand_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+#include <vector>
+
+#include "cmCommand.h"
+
+class cmExecutionStatus;
+
+class cmAddCompileDefinitionsCommand : public cmCommand
+{
+public:
+  /**
+   * This is a virtual constructor for the command.
+   */
+  cmCommand* Clone() override { return new cmAddCompileDefinitionsCommand; }
+
+  /**
+   * This is called when the command is first encountered in
+   * the CMakeLists.txt file.
+   */
+  bool InitialPass(std::vector<std::string> const& args,
+                   cmExecutionStatus& status) override;
+};
+
+#endif

+ 3 - 0
Source/cmCommands.cxx

@@ -4,6 +4,7 @@
 #include "cmPolicies.h"
 #include "cmState.h"
 
+#include "cmAddCompileDefinitionsCommand.h"
 #include "cmAddCustomCommandCommand.h"
 #include "cmAddCustomTargetCommand.h"
 #include "cmAddDefinitionsCommand.h"
@@ -253,6 +254,8 @@ void GetProjectCommands(cmState* state)
   state->AddBuiltinCommand("try_run", new cmTryRunCommand);
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
+  state->AddBuiltinCommand("add_compile_definitions",
+                           new cmAddCompileDefinitionsCommand);
   state->AddBuiltinCommand("add_compile_options",
                            new cmAddCompileOptionsCommand);
   state->AddBuiltinCommand("aux_source_directory",

+ 5 - 0
Source/cmMakefile.cxx

@@ -1195,6 +1195,11 @@ void cmMakefile::RemoveDefineFlag(std::string const& flag,
   }
 }
 
+void cmMakefile::AddCompileDefinition(std::string const& option)
+{
+  this->AppendProperty("COMPILE_DEFINITIONS", option.c_str());
+}
+
 void cmMakefile::AddCompileOption(std::string const& option)
 {
   this->AppendProperty("COMPILE_OPTIONS", option.c_str());

+ 1 - 0
Source/cmMakefile.h

@@ -168,6 +168,7 @@ public:
    */
   void AddDefineFlag(std::string const& definition);
   void RemoveDefineFlag(std::string const& definition);
+  void AddCompileDefinition(std::string const& definition);
   void AddCompileOption(std::string const& option);
 
   /** Create a new imported target with the name and type given.  */

+ 15 - 0
Tests/CMakeCommands/add_compile_definitions/CMakeLists.txt

@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(add_compile_definitions LANGUAGES CXX)
+
+add_compile_definitions(TEST_DEFINITION
+                        $<$<COMPILE_LANGUAGE:CXX>:LANG_$<COMPILE_LANGUAGE>>
+                        $<$<EQUAL:0,1>:UNEXPECTED_DEFINITION>)
+
+add_executable(add_compile_definitions main.cpp)
+
+add_library(imp UNKNOWN IMPORTED)
+get_target_property(_res imp COMPILE_DEFINITIONS)
+if (_res)
+  message(SEND_ERROR "add_compile_definitions populated the COMPILE_DEFINITIONS target property")
+endif()

+ 17 - 0
Tests/CMakeCommands/add_compile_definitions/main.cpp

@@ -0,0 +1,17 @@
+
+#ifndef TEST_DEFINITION
+#error Expected TEST_DEFINITION
+#endif
+
+#ifndef LANG_CXX
+#error Expected LANG_CXX
+#endif
+
+#ifdef UNPEXTED_DEFINITION
+#error Unexpected UNPEXTED_DEFINITION
+#endif
+
+int main(void)
+{
+  return 0;
+}

+ 1 - 0
Tests/CMakeLists.txt

@@ -2756,6 +2756,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     --output-log "${CMake_BINARY_DIR}/Tests/CTestConfig/ScriptWithArgs.log"
     )
 
+  ADD_TEST_MACRO(CMakeCommands.add_compile_definitions add_compile_definitions)
   ADD_TEST_MACRO(CMakeCommands.add_compile_options add_compile_options)
   ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries)
   ADD_TEST_MACRO(CMakeCommands.target_include_directories target_include_directories)