Bläddra i källkod

Autogen: Add AUTOGEN_USE_SYSTEM_INCLUDE target property

`AUTOGEN_USE_SYSTEM_INCLUDE` was added. `AUTOGEN_USE_SYSTEM_INCLUDE`
is a boolean property that can be set on a target to indicate that the
autogen target include directory should be added as a system include
directory or normal include directory to the target.
Orkun Tokdemir 2 år sedan
förälder
incheckning
033dc7ee2f

+ 2 - 0
Auxiliary/vim/syntax/cmake.vim

@@ -73,6 +73,7 @@ syn keyword cmakeProperty contained
             \ AUTOGEN_ORIGIN_DEPENDS
             \ AUTOGEN_PARALLEL
             \ AUTOGEN_SOURCE_GROUP
+            \ AUTOGEN_USE_SYSTEM_INCLUDE
             \ AUTOGEN_TARGETS_FOLDER
             \ AUTOGEN_TARGET_DEPENDS
             \ AUTOMOC
@@ -683,6 +684,7 @@ syn keyword cmakeVariable contained
             \ CMAKE_ASM_VISIBILITY_PRESET
             \ CMAKE_AUTOGEN_ORIGIN_DEPENDS
             \ CMAKE_AUTOGEN_PARALLEL
+            \ CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE
             \ CMAKE_AUTOGEN_VERBOSE
             \ CMAKE_AUTOMOC
             \ CMAKE_AUTOMOC_COMPILER_PREDEFINES

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

@@ -133,6 +133,7 @@ Properties on Targets
    /prop_tgt/AUTOGEN_ORIGIN_DEPENDS
    /prop_tgt/AUTOGEN_PARALLEL
    /prop_tgt/AUTOGEN_TARGET_DEPENDS
+   /prop_tgt/AUTOGEN_USE_SYSTEM_INCLUDE
    /prop_tgt/AUTOMOC
    /prop_tgt/AUTOMOC_COMPILER_PREDEFINES
    /prop_tgt/AUTOMOC_DEPEND_FILTERS

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

@@ -397,6 +397,7 @@ Variables that Control the Build
    /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG
    /variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS
    /variable/CMAKE_AUTOGEN_PARALLEL
+   /variable/CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE
    /variable/CMAKE_AUTOGEN_VERBOSE
    /variable/CMAKE_AUTOMOC
    /variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES

+ 14 - 0
Help/prop_tgt/AUTOGEN_USE_SYSTEM_INCLUDE.rst

@@ -0,0 +1,14 @@
+AUTOGEN_USE_SYSTEM_INCLUDE
+--------------------------
+
+``AUTOGEN_USE_SYSTEM_INCLUDE`` is a boolean property that can be set
+on a target to indicate that the autogen target include directory should
+be added as a system include directory or normal include directory to the
+target.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
+
+This property is initialized by the
+:variable:`CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE` variable if it is set when
+a target is created.

+ 7 - 0
Help/release/dev/autogen-system-include.rst

@@ -0,0 +1,7 @@
+autogen-system-include
+----------------------
+
+* The :prop_tgt:`AUTOGEN_USE_SYSTEM_INCLUDE` target property and
+  corresponding :variable:`CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE` were
+  added to explicitly control whether autogen headers are
+  considered system headers.

+ 10 - 0
Help/variable/CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE.rst

@@ -0,0 +1,10 @@
+CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE
+--------------------------------
+
+.. versionadded:: 3.27
+
+This variable is used to initialize the :prop_tgt:`AUTOGEN_USE_SYSTEM_INCLUDE`
+property on all targets as they are created.  See that target property for
+additional information.
+
+By default ``CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE`` is unset.

+ 23 - 0
Source/cmGeneratorTarget.cxx

@@ -731,6 +731,29 @@ void cmGeneratorTarget::AddIncludeDirectory(const std::string& src,
       BT<std::string>(src, this->Makefile->GetBacktrace()), true));
 }
 
+void cmGeneratorTarget::AddSystemIncludeDirectory(std::string const& inc,
+                                                  std::string const& lang)
+{
+  std::string config_upper;
+  auto const& configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+
+  for (auto const& config : configs) {
+    std::string inc_with_config = inc;
+    if (!config.empty()) {
+      cmSystemTools::ReplaceString(inc_with_config, "$<CONFIG>", config);
+      config_upper = cmSystemTools::UpperCase(config);
+    }
+    auto const& key = cmStrCat(config_upper, "/", lang);
+    this->Target->AddSystemIncludeDirectories({ inc_with_config });
+    this->SystemIncludesCache[key].emplace_back(inc_with_config);
+
+    // SystemIncludesCache should be sorted so that binary search can be used
+    std::sort(this->SystemIncludesCache[key].begin(),
+              this->SystemIncludesCache[key].end());
+  }
+}
+
 std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends(
   cmSourceFile const* sf) const
 {

+ 2 - 0
Source/cmGeneratorTarget.h

@@ -912,6 +912,8 @@ public:
   std::vector<std::string> GetGeneratedISPCObjects(
     std::string const& config) const;
 
+  void AddSystemIncludeDirectory(std::string const& inc,
+                                 std::string const& lang);
   bool AddHeaderSetVerification();
   std::string GenerateHeaderSetVerificationFile(
     cmSourceFile& source, const std::string& dir,

+ 14 - 1
Source/cmQtAutoGenInitializer.cxx

@@ -576,7 +576,20 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
 
   // Add autogen include directory to the origin target INCLUDE_DIRECTORIES
   if (this->MocOrUicEnabled() || (this->Rcc.Enabled && this->MultiConfig)) {
-    this->GenTarget->AddIncludeDirectory(this->Dir.IncludeGenExp, true);
+    auto addBefore = false;
+    auto const& value =
+      this->GenTarget->GetProperty("AUTOGEN_USE_SYSTEM_INCLUDE");
+    if (value.IsSet()) {
+      if (cmIsOn(value)) {
+        this->GenTarget->AddSystemIncludeDirectory(this->Dir.IncludeGenExp,
+                                                   "CXX");
+      } else {
+        addBefore = true;
+      }
+    } else {
+      addBefore = true;
+    }
+    this->GenTarget->AddIncludeDirectory(this->Dir.IncludeGenExp, addBefore);
   }
 
   // Scan files

+ 1 - 0
Source/cmTarget.cxx

@@ -546,6 +546,7 @@ TargetProperty const StaticTargetProperties[] = {
   // -- Autogen
   { "AUTOGEN_ORIGIN_DEPENDS"_s, IC::CanCompileSources },
   { "AUTOGEN_PARALLEL"_s, IC::CanCompileSources },
+  { "AUTOGEN_USE_SYSTEM_INCLUDE"_s, IC::CanCompileSources },
   // -- moc
   { "AUTOMOC_DEPEND_FILTERS"_s, IC::CanCompileSources },
   // -- C++

+ 28 - 0
Tests/QtAutogen/GlobalAutogenSystemUseInclude/CMakeLists.txt

@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 3.26)
+project(GlobalAutogenSystemUseInclude)
+
+include("../AutogenCoreTest.cmake")
+
+block()
+  set(test_autogen_use_system_include ON)
+  set(CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE ${test_autogen_use_system_include})
+
+  add_executable(autogen_test_on main.cpp)
+  get_target_property(target_autogen_use_system_include autogen_test_on AUTOGEN_USE_SYSTEM_INCLUDE)
+
+  if(NOT ${CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE} STREQUAL ${target_autogen_use_system_include})
+    message(FATAL_ERROR "CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE not set")
+  endif()
+endblock()
+
+block()
+  set(test_autogen_use_system_include OFF)
+  set(CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE ${test_autogen_use_system_include})
+
+  add_executable(autogen_test_off main.cpp)
+  get_target_property(target_autogen_use_system_include autogen_test_off AUTOGEN_USE_SYSTEM_INCLUDE)
+
+  if(NOT ${CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE} STREQUAL ${target_autogen_use_system_include})
+    message(FATAL_ERROR "CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE not set")
+  endif()
+endblock()

+ 4 - 0
Tests/QtAutogen/GlobalAutogenSystemUseInclude/main.cpp

@@ -0,0 +1,4 @@
+int main()
+{
+  return 0;
+}

+ 1 - 0
Tests/QtAutogen/Tests.cmake

@@ -3,6 +3,7 @@ ADD_AUTOGEN_TEST(AutogenOriginDependsOff autogenOriginDependsOff)
 ADD_AUTOGEN_TEST(AutogenOriginDependsOn)
 ADD_AUTOGEN_TEST(AutogenTargetDepends)
 ADD_AUTOGEN_TEST(Complex QtAutogen)
+ADD_AUTOGEN_TEST(GlobalAutogenSystemUseInclude)
 ADD_AUTOGEN_TEST(GlobalAutogenTarget)
 ADD_AUTOGEN_TEST(GlobalAutogenExecutable)
 ADD_AUTOGEN_TEST(LowMinimumVersion lowMinimumVersion)

+ 10 - 0
Tests/RunCMake/Autogen/AutogenUseSystemIncludeCommon.cmake

@@ -0,0 +1,10 @@
+enable_language(CXX)
+
+find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
+
+set(CMAKE_AUTOMOC ON)
+
+add_library(dummy SHARED empty.cpp)
+target_link_libraries(dummy Qt${with_qt_version}::Core
+                            Qt${with_qt_version}::Widgets
+                            Qt${with_qt_version}::Gui)

+ 3 - 0
Tests/RunCMake/Autogen/AutogenUseSystemIncludeOff.cmake

@@ -0,0 +1,3 @@
+include("${CMAKE_CURRENT_LIST_DIR}/AutogenUseSystemIncludeCommon.cmake")
+
+set_target_properties(dummy PROPERTIES AUTOGEN_USE_SYSTEM_INCLUDE OFF)

+ 3 - 0
Tests/RunCMake/Autogen/AutogenUseSystemIncludeOn.cmake

@@ -0,0 +1,3 @@
+include("${CMAKE_CURRENT_LIST_DIR}/AutogenUseSystemIncludeCommon.cmake")
+
+set_target_properties(dummy PROPERTIES AUTOGEN_USE_SYSTEM_INCLUDE ON)

+ 13 - 0
Tests/RunCMake/Autogen/Inspect.cmake

@@ -0,0 +1,13 @@
+enable_language(CXX)
+
+set(info "")
+foreach(var
+    CMAKE_INCLUDE_FLAG_CXX
+    CMAKE_INCLUDE_SYSTEM_FLAG_CXX
+    )
+  if(DEFINED ${var})
+    string(APPEND info "set(${var} \"${${var}}\")\n")
+  endif()
+endforeach()
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")

+ 48 - 0
Tests/RunCMake/Autogen/RunCMakeTest.cmake

@@ -22,4 +22,52 @@ if (DEFINED with_qt_version)
     set(RunCMake_TEST_NO_CLEAN 1)
     run_cmake_command(MocPredefs-build ${CMAKE_COMMAND} --build . --config Debug)
   endblock()
+
+  # Detect information from the toolchain:
+  # - CMAKE_INCLUDE_FLAG_CXX
+  # - CMAKE_INCLUDE_SYSTEM_FLAG_CXX
+  run_cmake(Inspect)
+  include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
+
+  if(CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+    if(RunCMake_GENERATOR MATCHES "Visual Studio")
+      string(REGEX REPLACE "^-" "/" test_expect_stdout "${CMAKE_INCLUDE_SYSTEM_FLAG_CXX}")
+    else()
+      set(test_expect_stdout "-*${CMAKE_INCLUDE_SYSTEM_FLAG_CXX}")
+    endif()
+    string(APPEND test_expect_stdout " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
+    if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+      string(APPEND test_expect_stdout "_Debug")
+    endif()
+
+    block()
+      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeOn-build)
+      run_cmake(AutogenUseSystemIncludeOn)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+      message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
+      run_cmake_command(AutogenUseSystemIncludeOn ${CMAKE_COMMAND} --build . --config Debug --verbose)
+    endblock()
+  endif()
+
+  if(CMAKE_INCLUDE_FLAG_CXX)
+    if(RunCMake_GENERATOR MATCHES "Visual Studio")
+      string(REGEX REPLACE "^-" "/" test_expect_stdout "${CMAKE_INCLUDE_FLAG_CXX}")
+    else()
+      set(test_expect_stdout "-*${CMAKE_INCLUDE_FLAG_CXX}")
+    endif()
+    string(APPEND test_expect_stdout " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
+    if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+      string(APPEND test_expect_stdout "_Debug")
+    endif()
+
+    block()
+      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeOff-build)
+      run_cmake(AutogenUseSystemIncludeOff)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+      message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
+      run_cmake_command(AutogenUseSystemIncludeOff ${CMAKE_COMMAND} --build . --config Debug --verbose)
+    endblock()
+  endif()
 endif ()