浏览代码

Merge topic 'compile-options-order'

8f68bcad8f Tests: Add cases verifying flag ordering rules
ccc83ce162 Help: Document order of flags from CMAKE_<LANG>_FLAGS and COMPILE_OPTIONS
df79fe055b Help: Remove incorrect "versionadded" for CMAKE_<LANG>_FLAGS_<CONFIG>
c48d2d8480 VS: Place per-source preprocessor definitions after target-wide ones

Acked-by: Kitware Robot <[email protected]>
Merge-request: !6187
Brad King 4 年之前
父节点
当前提交
d1517a4ef9

+ 5 - 2
Help/prop_sf/COMPILE_FLAGS.rst

@@ -4,8 +4,11 @@ COMPILE_FLAGS
 Additional flags to be added when compiling this source file.
 
 The ``COMPILE_FLAGS`` property, managed as a string, sets additional compiler
-flags used to build source files.  Use :prop_sf:`COMPILE_DEFINITIONS` to pass
-additional preprocessor definitions.
+flags used that will be added to the list of compile flags when this source
+file builds.  The flags will be added after target-wide flags (except in
+some cases not supported by the :generator:`Visual Studio 9 2008` generator).
+
+Use :prop_sf:`COMPILE_DEFINITIONS` to pass additional preprocessor definitions.
 
 Contents of ``COMPILE_FLAGS`` may use "generator expressions"
 with the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`

+ 4 - 3
Help/prop_sf/COMPILE_OPTIONS.rst

@@ -5,9 +5,10 @@ COMPILE_OPTIONS
 
 List of additional options to pass to the compiler.
 
-This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of options
-and will be added to the list of compile flags when this
-source file builds.
+This property holds a :ref:`semicolon-separated list <CMake Language Lists>`
+of options and will be added to the list of compile flags when this source
+file builds.  The options will be added after target-wide options (except in
+some cases not supported by the :generator:`Visual Studio 9 2008` generator).
 
 Contents of ``COMPILE_OPTIONS`` may use "generator expressions" with the
 syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)` manual

+ 7 - 3
Help/prop_tgt/COMPILE_OPTIONS.rst

@@ -3,9 +3,13 @@ COMPILE_OPTIONS
 
 List of options to pass to the compiler.
 
-This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of options
-specified so far for its target.  Use the :command:`target_compile_options`
-command to append more options.
+This property holds a :ref:`semicolon-separated list <CMake Language Lists>`
+of options specified so far for its target.  Use the
+:command:`target_compile_options` command to append more options.
+The options will be added after after flags in the
+:variable:`CMAKE_<LANG>_FLAGS` and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`
+variables, but before those propagated from dependencies by the
+:prop_tgt:`INTERFACE_COMPILE_OPTIONS` property.
 
 This property is initialized by the :prop_dir:`COMPILE_OPTIONS` directory
 property when a target is created, and is used by the generators to set

+ 7 - 0
Help/release/dev/compile-options-order.rst

@@ -0,0 +1,7 @@
+compile-options-order
+---------------------
+
+* The :ref:`Visual Studio Generators` for VS 2010 and above now place
+  per-source preprocessor definitions after target-wide preprocssor
+  definitions.  This makes VS consistent with the :ref:`Ninja Generators`
+  and the :ref:`Makefile Generators`.

+ 5 - 0
Help/variable/CMAKE_LANG_FLAGS.rst

@@ -18,3 +18,8 @@ This is initialized for each language from environment variables:
 
 This value is a command-line string fragment. Therefore, multiple options
 should be separated by spaces, and options with spaces should be quoted.
+
+The flags in this variable will be passed to the compiler before those
+in the per-configuration :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` variant,
+and before flags added by the :command:`add_compile_options` or
+:command:`target_compile_options` commands.

+ 5 - 2
Help/variable/CMAKE_LANG_FLAGS_CONFIG.rst

@@ -1,6 +1,9 @@
 CMAKE_<LANG>_FLAGS_<CONFIG>
 ---------------------------
 
-.. versionadded:: 3.11
-
 Flags for language ``<LANG>`` when building for the ``<CONFIG>`` configuration.
+
+The flags in this variable will be passed to the compiler after those
+in the :variable:`CMAKE_<LANG>_FLAGS` variable, but before flags added
+by the :command:`add_compile_options` or :command:`target_compile_options`
+commands.

+ 4 - 6
Source/cmVisualStudioGeneratorOptions.cxx

@@ -418,7 +418,9 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
   }
 
   std::ostringstream oss;
-  const char* sep = "";
+  if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
+    oss << "%(" << tag << ")";
+  }
   std::vector<std::string>::const_iterator de =
     cmRemoveDuplicates(this->Defines);
   for (std::string const& di : cmMakeRange(this->Defines.cbegin(), de)) {
@@ -437,11 +439,7 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
       }
     }
     // Store the flag in the project file.
-    oss << sep << define;
-    sep = ";";
-  }
-  if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
-    oss << ";%(" << tag << ")";
+    oss << ';' << define;
   }
 
   this->OutputFlag(fout, indent, tag, oss.str());

+ 5 - 0
Tests/CMakeLists.txt

@@ -489,6 +489,11 @@ if(BUILD_TESTING)
   if(CMAKE_Fortran_COMPILER)
     set(CompileOptions_BUILD_OPTIONS -DTEST_FORTRAN=1)
   endif()
+  if(_isMultiConfig)
+    set(CompileOptions_CTEST_OPTIONS --build-config $<CONFIGURATION>)
+  else()
+    set(CompileOptions_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=$<CONFIGURATION>)
+  endif()
   ADD_TEST_MACRO(CompileOptions CompileOptions)
   ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
   ADD_TEST_MACRO(AliasTarget AliasTarget)

+ 26 - 2
Tests/CompileOptions/CMakeLists.txt

@@ -1,5 +1,11 @@
-cmake_minimum_required(VERSION 2.8.12)
-
+cmake_minimum_required(VERSION 3.0)
+if(POLICY CMP0092)
+  cmake_policy(SET CMP0092 NEW)
+endif()
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(NOT _isMultiConfig AND NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build" FORCE)
+endif()
 project(CompileOptions)
 
 add_library(testlib other.cpp)
@@ -49,6 +55,24 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|Borland|Embarcadero" AND NOT "${CMAK
     )
 endif()
 
+if(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|AppleClang|MSVC)$")
+  target_compile_definitions(CompileOptions PRIVATE "DO_FLAG_TESTS")
+  if(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|AppleClang)$")
+    string(APPEND CMAKE_CXX_FLAGS " -w")
+  endif()
+  string(APPEND CMAKE_CXX_FLAGS                " -DFLAG_A=1 -DFLAG_B=1")
+  string(APPEND CMAKE_CXX_FLAGS_DEBUG          " -DFLAG_A=2 -DFLAG_C=1")
+  string(APPEND CMAKE_CXX_FLAGS_RELEASE        " -DFLAG_A=2 -DFLAG_C=1")
+  string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -DFLAG_A=2 -DFLAG_C=1")
+  string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL     " -DFLAG_A=2 -DFLAG_C=1")
+  set_property(TARGET CompileOptions APPEND PROPERTY COMPILE_OPTIONS "-DFLAG_B=2" "-DFLAG_C=2" "-DFLAG_D=1")
+  set_property(TARGET testlib APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "-DFLAG_D=2")
+  if(NOT CMAKE_GENERATOR MATCHES "^Visual Studio 9")
+    set_property(TARGET testlib APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "-DFLAG_E=1")
+    set_property(SOURCE main.cpp PROPERTY COMPILE_OPTIONS "-DFLAG_E=2")
+  endif()
+endif()
+
 target_link_libraries(CompileOptions testlib)
 
 if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")

+ 18 - 0
Tests/CompileOptions/main.cpp

@@ -37,6 +37,24 @@
 #  endif
 #endif
 
+#ifdef DO_FLAG_TESTS
+#  if FLAG_A != 2
+#    error "FLAG_A is not 2"
+#  endif
+#  if FLAG_B != 2
+#    error "FLAG_B is not 2"
+#  endif
+#  if FLAG_C != 2
+#    error "FLAG_C is not 2"
+#  endif
+#  if FLAG_D != 2
+#    error "FLAG_D is not 2"
+#  endif
+#  if defined(FLAG_E) && FLAG_E != 2
+#    error "FLAG_E is not 2"
+#  endif
+#endif
+
 #include <string.h>
 
 int main()

+ 4 - 1
Tests/RunCMake/CMakeLists.txt

@@ -595,7 +595,10 @@ set_property(TEST RunCMake.target_link_options APPEND
 
 add_RunCMake_test(target_compile_definitions)
 add_RunCMake_test(target_compile_features)
-add_RunCMake_test(target_compile_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
+add_RunCMake_test(target_compile_options
+  -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+  -DCMAKE_C_SIMULATE_ID=${CMAKE_C_SIMULATE_ID}
+  )
 add_RunCMake_test(target_include_directories)
 add_RunCMake_test(target_sources)
 add_RunCMake_test(CheckCompilerFlag   -DCMake_TEST_CUDA=${CMake_TEST_CUDA}

+ 3 - 0
Tests/RunCMake/target_compile_options/Order-build-stdout.txt

@@ -0,0 +1,3 @@
+-w +-O +-O0 [^
+]*-O1 +-O2 +-O3 [^
+]*CMakeFiles[\/]order\.dir[\/](Custom[\/])?order\.c\.o

+ 19 - 0
Tests/RunCMake/target_compile_options/Order.cmake

@@ -0,0 +1,19 @@
+get_property (isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(isMultiConfig)
+  set(CMAKE_CONFIGURATION_TYPES "Custom" CACHE STRING "" FORCE)
+else()
+  set(CMAKE_BUILD_TYPE "Custom" CACHE STRING "" FORCE)
+endif()
+enable_language(C)
+
+string(APPEND CMAKE_C_FLAGS " -w -O")
+set(CMAKE_C_FLAGS_CUSTOM "-O0")
+
+add_executable(order order.c)
+set_property(TARGET order APPEND PROPERTY COMPILE_OPTIONS -O1)
+
+add_library(iface INTERFACE)
+set_property(TARGET iface APPEND PROPERTY INTERFACE_COMPILE_OPTIONS -O2)
+target_link_libraries(order PRIVATE iface)
+
+set_property(SOURCE order.c PROPERTY COMPILE_OPTIONS -O3)

+ 13 - 0
Tests/RunCMake/target_compile_options/RunCMakeTest.cmake

@@ -19,3 +19,16 @@ if (CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
   run_cmake_target(CMP0101-BEFORE_keyword OLD CMP0101_OLD)
   run_cmake_target(CMP0101-BEFORE_keyword NEW CMP0101_NEW)
 endif()
+
+function(run_Order)
+  run_cmake_with_options(Order)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Order-build)
+  set(RunCMake_TEST_OUTPUT_MERGE 1)
+  run_cmake_command(Order-build ${CMAKE_COMMAND} --build . --verbose --config Custom)
+endfunction()
+if(RunCMake_GENERATOR MATCHES "Ninja|Make" AND
+    CMAKE_C_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$" AND
+    NOT CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
+  run_Order()
+endif()

+ 7 - 0
Tests/RunCMake/target_compile_options/order.c

@@ -0,0 +1,7 @@
+#ifndef __OPTIMIZE__
+#  error "Optimizations not enabled!"
+#endif
+int main(void)
+{
+  return 0;
+}