summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarragh Coy <darragh.coy@ea.com>2024-10-01 16:23:23 (GMT)
committerBrad King <brad.king@kitware.com>2024-10-01 18:00:00 (GMT)
commit55831faf5ba43650dcab14fbb08b51890cbe954c (patch)
treeddfd6c4265004dd620a74ce1577ff0719741ce4c
parentd0ad8fd49c2d211081d32cdc2a7f96990947c340 (diff)
downloadCMake-55831faf5ba43650dcab14fbb08b51890cbe954c.zip
CMake-55831faf5ba43650dcab14fbb08b51890cbe954c.tar.gz
CMake-55831faf5ba43650dcab14fbb08b51890cbe954c.tar.bz2
VS: Honor VS_TOOL_OVERRIDE for known source file types too
Visual Studio Generator: The `VS_TOOL_OVERRIDE` source file property would previously only be respected for file types that CMake didn't know how to build out of the box. This change allows the user to override how any source file is built with a custom build tool, even ones with standard/recognized extensions such as `.cxx`, `.idl`, etc. Fixes: #26336
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx125
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/VS10Project/VsToolOverride-check.cmake64
-rw-r--r--Tests/RunCMake/VS10Project/VsToolOverride.cmake7
-rw-r--r--Tests/RunCMake/VS10Project/bar.txt1
-rw-r--r--Tests/RunCMake/VS10Project/foo.txt1
6 files changed, 140 insertions, 59 deletions
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 1e338b2..694976e 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2544,66 +2544,73 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
}
const char* tool = nullptr;
- switch (si.Kind) {
- case cmGeneratorTarget::SourceKindAppManifest:
- tool = "AppxManifest";
- break;
- case cmGeneratorTarget::SourceKindCertificate:
- tool = "None";
- break;
- case cmGeneratorTarget::SourceKindCustomCommand:
- // Handled elsewhere.
- break;
- case cmGeneratorTarget::SourceKindExternalObject:
- tool = "Object";
- break;
- case cmGeneratorTarget::SourceKindExtra:
- this->WriteExtraSource(e1, si.Source, toolSettings);
- break;
- case cmGeneratorTarget::SourceKindHeader:
- this->WriteHeaderSource(e1, si.Source, toolSettings);
- break;
- case cmGeneratorTarget::SourceKindIDL:
- tool = "Midl";
- break;
- case cmGeneratorTarget::SourceKindManifest:
- // Handled elsewhere.
- break;
- case cmGeneratorTarget::SourceKindModuleDefinition:
- tool = "None";
- break;
- case cmGeneratorTarget::SourceKindCxxModuleSource:
- case cmGeneratorTarget::SourceKindUnityBatched:
- case cmGeneratorTarget::SourceKindObjectSource: {
- const std::string& lang = si.Source->GetLanguage();
- if (lang == "C"_s || lang == "CXX"_s) {
- tool = "ClCompile";
- } else if (lang == "ASM_MARMASM"_s &&
- this->GlobalGenerator->IsMarmasmEnabled()) {
- tool = "MARMASM";
- } else if (lang == "ASM_MASM"_s &&
- this->GlobalGenerator->IsMasmEnabled()) {
- tool = "MASM";
- } else if (lang == "ASM_NASM"_s &&
- this->GlobalGenerator->IsNasmEnabled()) {
- tool = "NASM";
- } else if (lang == "RC"_s) {
- tool = "ResourceCompile";
- } else if (lang == "CSharp"_s) {
- tool = "Compile";
- } else if (lang == "CUDA"_s &&
- this->GlobalGenerator->IsCudaEnabled()) {
- tool = "CudaCompile";
- } else {
+ const cmValue toolOverride = si.Source->GetProperty("VS_TOOL_OVERRIDE");
+
+ if (cmNonempty(toolOverride)) {
+ // Custom tool specified: the file will be built in a user-defined way
+ this->WriteExtraSource(e1, si.Source, toolSettings);
+ } else {
+ switch (si.Kind) {
+ case cmGeneratorTarget::SourceKindAppManifest:
+ tool = "AppxManifest";
+ break;
+ case cmGeneratorTarget::SourceKindCertificate:
tool = "None";
- }
- } break;
- case cmGeneratorTarget::SourceKindResx:
- this->ResxObjs.push_back(si.Source);
- break;
- case cmGeneratorTarget::SourceKindXaml:
- this->XamlObjs.push_back(si.Source);
- break;
+ break;
+ case cmGeneratorTarget::SourceKindCustomCommand:
+ // Handled elsewhere.
+ break;
+ case cmGeneratorTarget::SourceKindExternalObject:
+ tool = "Object";
+ break;
+ case cmGeneratorTarget::SourceKindExtra:
+ this->WriteExtraSource(e1, si.Source, toolSettings);
+ break;
+ case cmGeneratorTarget::SourceKindHeader:
+ this->WriteHeaderSource(e1, si.Source, toolSettings);
+ break;
+ case cmGeneratorTarget::SourceKindIDL:
+ tool = "Midl";
+ break;
+ case cmGeneratorTarget::SourceKindManifest:
+ // Handled elsewhere.
+ break;
+ case cmGeneratorTarget::SourceKindModuleDefinition:
+ tool = "None";
+ break;
+ case cmGeneratorTarget::SourceKindCxxModuleSource:
+ case cmGeneratorTarget::SourceKindUnityBatched:
+ case cmGeneratorTarget::SourceKindObjectSource: {
+ const std::string& lang = si.Source->GetLanguage();
+ if (lang == "C"_s || lang == "CXX"_s) {
+ tool = "ClCompile";
+ } else if (lang == "ASM_MARMASM"_s &&
+ this->GlobalGenerator->IsMarmasmEnabled()) {
+ tool = "MARMASM";
+ } else if (lang == "ASM_MASM"_s &&
+ this->GlobalGenerator->IsMasmEnabled()) {
+ tool = "MASM";
+ } else if (lang == "ASM_NASM"_s &&
+ this->GlobalGenerator->IsNasmEnabled()) {
+ tool = "NASM";
+ } else if (lang == "RC"_s) {
+ tool = "ResourceCompile";
+ } else if (lang == "CSharp"_s) {
+ tool = "Compile";
+ } else if (lang == "CUDA"_s &&
+ this->GlobalGenerator->IsCudaEnabled()) {
+ tool = "CudaCompile";
+ } else {
+ tool = "None";
+ }
+ } break;
+ case cmGeneratorTarget::SourceKindResx:
+ this->ResxObjs.push_back(si.Source);
+ break;
+ case cmGeneratorTarget::SourceKindXaml:
+ this->XamlObjs.push_back(si.Source);
+ break;
+ }
}
std::string config;
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 85fefbf..bbd8c8b 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -50,6 +50,7 @@ run_cmake(VsSettings)
run_cmake(VsSourceSettingsTool)
run_cmake(VsPlatformToolset)
run_cmake(VsControlFlowGuardLinkSetting)
+run_cmake(VsToolOverride)
run_cmake(VsWinRTByDefault)
diff --git a/Tests/RunCMake/VS10Project/VsToolOverride-check.cmake b/Tests/RunCMake/VS10Project/VsToolOverride-check.cmake
new file mode 100644
index 0000000..8d9adbb
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsToolOverride-check.cmake
@@ -0,0 +1,64 @@
+# Figure out which build tool the test files in a project are using
+macro(get_build_tools_from_project_file projectFile)
+ set(_s "[ \t\r\n]") # Whitespace character class
+
+ set(ItemGroupBeginRegex "<${_s}*ItemGroup${_s}*>")
+ set(ItemGroupEndRegex "</${_s}*ItemGroup${_s}*>")
+ set(GroupItemRegex ".*<${_s}*([A-Za-z0-9_]+)${_s}+Include${_s}*=${_s}*\"([^\"]*)\".*")
+
+ if(NOT EXISTS "${projectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+ return()
+ endif()
+
+ file(STRINGS "${projectFile}" lines)
+
+ foreach(line IN LISTS lines)
+ if(line MATCHES "${ItemGroupBeginRegex}")
+ set(InItemGroup TRUE)
+ elseif(line MATCHES "${ItemGroupEndRegex}")
+ set(InItemGroup FALSE)
+ elseif(line MATCHES "${GroupItemRegex}")
+ if(InItemGroup)
+ string(REGEX REPLACE "${GroupItemRegex}" "\\1" itemTool "${line}")
+ string(REGEX REPLACE "${GroupItemRegex}" "\\2" itemPath "${line}")
+
+ if(itemPath MATCHES ".*foo\\.cpp")
+ set(fooCppTool "${itemTool}")
+ elseif(itemPath MATCHES ".*foo\\.txt")
+ set(fooTxtTool "${itemTool}")
+ elseif(itemPath MATCHES ".*bar\\.cpp")
+ set(barCppTool "${itemTool}")
+ elseif(itemPath MATCHES ".*bar\\.txt")
+ set(barTxtTool "${itemTool}")
+ endif()
+ endif()
+ endif()
+ endforeach()
+endmacro()
+
+# Verify a build tool is as expected
+macro(verify_build_tool fileName expectedBuildTool actualBuildTool)
+ if("${actualBuildTool}" STREQUAL "${expectedBuildTool}")
+ message(STATUS "File '${fileName}' in project file '${projectFile}' has expected build tool '${expectedBuildTool}'")
+ else()
+ set(RunCMake_TEST_FAILED "File '${fileName}' in project file '${projectFile}' has unexpected build tool '${actualBuildTool}'! Expected: '${expectedBuildTool}'" PARENT_SCOPE)
+ return()
+ endif()
+endmacro()
+
+# Test using VS_TOOL_OVERRIDE
+block()
+ set(projectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+ get_build_tools_from_project_file("${projectFile}")
+ verify_build_tool("foo.cpp" "CustomFooCppTool" "${fooCppTool}")
+ verify_build_tool("foo.txt" "CustomFooTxtTool" "${fooTxtTool}")
+endblock()
+
+# Test default behavior without using VS_TOOL_OVERRIDE
+block()
+ set(projectFile "${RunCMake_TEST_BINARY_DIR}/bar.vcxproj")
+ get_build_tools_from_project_file("${projectFile}")
+ verify_build_tool("bar.cpp" "ClCompile" "${barCppTool}")
+ verify_build_tool("bar.txt" "None" "${barTxtTool}")
+endblock()
diff --git a/Tests/RunCMake/VS10Project/VsToolOverride.cmake b/Tests/RunCMake/VS10Project/VsToolOverride.cmake
new file mode 100644
index 0000000..62ae5e8
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsToolOverride.cmake
@@ -0,0 +1,7 @@
+enable_language(CXX)
+
+set_property(SOURCE "foo.cpp" PROPERTY VS_TOOL_OVERRIDE CustomFooCppTool)
+set_property(SOURCE "foo.txt" PROPERTY VS_TOOL_OVERRIDE CustomFooTxtTool)
+add_library(foo foo.cpp foo.txt)
+
+add_library(bar bar.cpp bar.txt)
diff --git a/Tests/RunCMake/VS10Project/bar.txt b/Tests/RunCMake/VS10Project/bar.txt
new file mode 100644
index 0000000..ebd7525
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/bar.txt
@@ -0,0 +1 @@
+Bar
diff --git a/Tests/RunCMake/VS10Project/foo.txt b/Tests/RunCMake/VS10Project/foo.txt
new file mode 100644
index 0000000..bc56c4d
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/foo.txt
@@ -0,0 +1 @@
+Foo