summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2020-08-19 16:41:24 -0400
committerBrad King <brad.king@kitware.com>2020-08-21 09:17:27 -0400
commit3ef0c40962312a97d5a083c79ec563045fe28de3 (patch)
tree1b6231bd299e24a59ab83e8af875d77a1e287ba3
parent8de3a25ec34c4b2d3cd7e519d3c3607e81de34c4 (diff)
downloadcmake-3ef0c40962312a97d5a083c79ec563045fe28de3.tar.gz
WIN32_EXECUTABLE: Add support for generator expressions
-rw-r--r--Help/prop_tgt/WIN32_EXECUTABLE.rst4
-rw-r--r--Help/release/dev/win32-executable-genex.rst5
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx3
-rw-r--r--Source/cmGeneratorTarget.cxx6
-rw-r--r--Source/cmGeneratorTarget.h3
-rw-r--r--Source/cmGlobalGenerator.cxx6
-rw-r--r--Source/cmLocalGenerator.cxx2
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx2
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx3
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx20
-rw-r--r--Tests/CMakeLists.txt4
-rw-r--r--Tests/CSharpWin32GenEx/CMakeLists.txt5
-rw-r--r--Tests/CSharpWin32GenEx/csharpwin32genex.cs9
-rw-r--r--Tests/RunCMake/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/Win32GenEx/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Win32GenEx/RunCMakeTest.cmake28
-rw-r--r--Tests/RunCMake/Win32GenEx/Win32GenEx-debug.cmake1
-rw-r--r--Tests/RunCMake/Win32GenEx/Win32GenEx-release.cmake1
-rw-r--r--Tests/RunCMake/Win32GenEx/Win32GenEx.cmake7
-rw-r--r--Tests/RunCMake/Win32GenEx/main.c14
20 files changed, 118 insertions, 12 deletions
diff --git a/Help/prop_tgt/WIN32_EXECUTABLE.rst b/Help/prop_tgt/WIN32_EXECUTABLE.rst
index 060d16671a..eac28ae3bd 100644
--- a/Help/prop_tgt/WIN32_EXECUTABLE.rst
+++ b/Help/prop_tgt/WIN32_EXECUTABLE.rst
@@ -11,3 +11,7 @@ configure use of the Microsoft Foundation Classes (MFC) for WinMain
executables. This property is initialized by the value of the
:variable:`CMAKE_WIN32_EXECUTABLE` variable if it is set when
a target is created.
+
+This property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`, except if the
+target is managed (contains C# code.)
diff --git a/Help/release/dev/win32-executable-genex.rst b/Help/release/dev/win32-executable-genex.rst
new file mode 100644
index 0000000000..f03203d87a
--- /dev/null
+++ b/Help/release/dev/win32-executable-genex.rst
@@ -0,0 +1,5 @@
+win32-executable-genex
+----------------------
+
+* The :prop_tgt:`WIN32_EXECUTABLE` target property now supports
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 511168bacf..df68033b59 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -689,7 +689,8 @@ int cmExtraCodeBlocksGenerator::GetCBTargetType(cmGeneratorTarget* target)
{
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
- if ((target->GetPropertyAsBool("WIN32_EXECUTABLE")) ||
+ if ((target->IsWin32Executable(
+ target->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"))) ||
(target->GetPropertyAsBool("MACOSX_BUNDLE"))) {
return 0;
}
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 9611e142e7..7c526a02a8 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -2266,6 +2266,12 @@ bool cmGeneratorTarget::IsBundleOnApple() const
this->IsCFBundleOnApple();
}
+bool cmGeneratorTarget::IsWin32Executable(const std::string& config) const
+{
+ return cmIsOn(cmGeneratorExpression::Evaluate(
+ this->GetSafeProperty("WIN32_EXECUTABLE"), this->LocalGenerator, config));
+}
+
std::string cmGeneratorTarget::GetCFBundleDirectory(
const std::string& config, BundleDirectoryLevel level) const
{
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 69c5fafd7b..544b27a968 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -284,6 +284,9 @@ public:
or CFBundle on Apple. */
bool IsBundleOnApple() const;
+ /** Return whether this target is a Win32 executable */
+ bool IsWin32Executable(const std::string& config) const;
+
/** Get the full name of the target according to the settings in its
makefile. */
std::string GetFullName(const std::string& config,
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index cad5d1f68b..a192ffd57f 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -335,13 +335,13 @@ bool cmGlobalGenerator::CheckTargetsForType() const
bool failed = false;
for (const auto& generator : this->LocalGenerators) {
for (const auto& target : generator->GetGeneratorTargets()) {
- if (target->GetType() == cmStateEnums::EXECUTABLE &&
- target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
+ if (target->GetType() == cmStateEnums::EXECUTABLE) {
std::vector<std::string> const& configs =
target->Makefile->GetGeneratorConfigs(
cmMakefile::IncludeEmptyConfig);
for (std::string const& config : configs) {
- if (target->GetLinkerLanguage(config) == "Swift") {
+ if (target->IsWin32Executable(config) &&
+ target->GetLinkerLanguage(config) == "Swift") {
this->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
"WIN32_EXECUTABLE property is not supported on Swift "
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 2380ccebe5..3cbc8ac4f1 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1520,7 +1520,7 @@ void cmLocalGenerator::GetTargetFlags(
return;
}
- if (target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
+ if (target->IsWin32Executable(config)) {
exeFlags +=
this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE");
exeFlags += " ";
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 50ffe8d2ec..ee7f74c516 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1113,7 +1113,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
cmComputeLinkInformation& cli = *pcli;
std::string linkLanguage = cli.GetLinkLanguage();
- bool isWin32Executable = target->GetPropertyAsBool("WIN32_EXECUTABLE");
+ bool isWin32Executable = target->IsWin32Executable(configName);
// Compute the variable name to lookup standard libraries for this
// language.
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index bc288ace9d..9b5c6e60a8 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -371,7 +371,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->AddConfigVariableFlags(
linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->GetConfigName());
- if (this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE")) {
+ if (this->GeneratorTarget->IsWin32Executable(
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"))) {
this->LocalGenerator->AppendFlags(
linkFlags, this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE"));
} else {
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index db9dc53e99..fa6ad472e1 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -595,14 +595,24 @@ void cmVisualStudio10TargetGenerator::Generate()
case cmStateEnums::MODULE_LIBRARY:
outputType = "Module";
break;
- case cmStateEnums::EXECUTABLE:
- if (this->GeneratorTarget->Target->GetPropertyAsBool(
- "WIN32_EXECUTABLE")) {
+ case cmStateEnums::EXECUTABLE: {
+ auto const win32 =
+ this->GeneratorTarget->GetSafeProperty("WIN32_EXECUTABLE");
+ if (win32.find("$<") != std::string::npos) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Target \"", this->GeneratorTarget->GetName(),
+ "\" has a generator expression in its WIN32_EXECUTABLE "
+ "property. This is not supported on managed executables."));
+ return;
+ }
+ if (cmIsOn(win32)) {
outputType = "WinExe";
} else {
outputType = "Exe";
}
- break;
+ } break;
case cmStateEnums::UTILITY:
case cmStateEnums::INTERFACE_LIBRARY:
case cmStateEnums::GLOBAL_TARGET:
@@ -3731,7 +3741,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
}
if (this->MSTools) {
- if (this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE")) {
+ if (this->GeneratorTarget->IsWin32Executable(config)) {
if (this->GlobalGenerator->TargetsWindowsCE()) {
linkOptions.AddFlag("SubSystem", "WindowsCE");
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index e4e09faf84..5d4ffaeaec 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -440,6 +440,10 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(CSharpOnly CSharpOnly)
ADD_TEST_MACRO(CSharpLinkToCxx CSharpLinkToCxx)
ADD_TEST_MACRO(CSharpLinkFromCxx CSharpLinkFromCxx)
+ ADD_TEST_MACRO(CSharpWin32GenEx CSharpWin32GenEx)
+ set_tests_properties(CSharpWin32GenEx PROPERTIES
+ PASS_REGULAR_EXPRESSION "Target \"CSharpWin32GenEx\" has a generator expression in its\n WIN32_EXECUTABLE property\\. This is not supported on managed executables\\."
+ )
endif()
ADD_TEST_MACRO(COnly COnly)
diff --git a/Tests/CSharpWin32GenEx/CMakeLists.txt b/Tests/CSharpWin32GenEx/CMakeLists.txt
new file mode 100644
index 0000000000..f4a8d00f68
--- /dev/null
+++ b/Tests/CSharpWin32GenEx/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.18)
+project(CSharpWin32GenEx CSharp)
+
+add_executable(CSharpWin32GenEx csharpwin32genex.cs)
+set_property(TARGET CSharpWin32GenEx PROPERTY WIN32_EXECUTABLE $<1:1>)
diff --git a/Tests/CSharpWin32GenEx/csharpwin32genex.cs b/Tests/CSharpWin32GenEx/csharpwin32genex.cs
new file mode 100644
index 0000000000..9892ee029e
--- /dev/null
+++ b/Tests/CSharpWin32GenEx/csharpwin32genex.cs
@@ -0,0 +1,9 @@
+namespace CSharpWin32GenEx
+{
+ class CSharpWin32GenEx
+ {
+ public static void Main(string[] args)
+ {
+ }
+ }
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index bbb195273d..fed2852e55 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -732,3 +732,7 @@ add_RunCMake_test("CTestCommandExpandLists")
add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
add_RunCMake_test("UnityBuild")
+
+if(WIN32)
+ add_RunCMake_test(Win32GenEx)
+endif()
diff --git a/Tests/RunCMake/Win32GenEx/CMakeLists.txt b/Tests/RunCMake/Win32GenEx/CMakeLists.txt
new file mode 100644
index 0000000000..b646c4ac67
--- /dev/null
+++ b/Tests/RunCMake/Win32GenEx/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.18)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Win32GenEx/RunCMakeTest.cmake b/Tests/RunCMake/Win32GenEx/RunCMakeTest.cmake
new file mode 100644
index 0000000000..d5529b022d
--- /dev/null
+++ b/Tests/RunCMake/Win32GenEx/RunCMakeTest.cmake
@@ -0,0 +1,28 @@
+include(RunCMake)
+
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Win32GenEx-build)
+ run_cmake(Win32GenEx)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(Win32GenEx-debug-build ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --config Debug)
+ run_cmake_command(Win32GenEx-release-build ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --config Release)
+ unset(RunCMake_TEST_NO_CLEAN)
+else()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Win32GenEx-debug-build)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ run_cmake(Win32GenEx-debug)
+ unset(RunCMake_TEST_OPTIONS)
+
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(Win32GenEx-debug-build ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR})
+ unset(RunCMake_TEST_NO_CLEAN)
+
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Win32GenEx-release-build)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
+ run_cmake(Win32GenEx-release)
+ unset(RunCMake_TEST_OPTIONS)
+
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(Win32GenEx-release-build ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR})
+ unset(RunCMake_TEST_NO_CLEAN)
+endif()
diff --git a/Tests/RunCMake/Win32GenEx/Win32GenEx-debug.cmake b/Tests/RunCMake/Win32GenEx/Win32GenEx-debug.cmake
new file mode 100644
index 0000000000..74c5bd8a27
--- /dev/null
+++ b/Tests/RunCMake/Win32GenEx/Win32GenEx-debug.cmake
@@ -0,0 +1 @@
+include(Win32GenEx.cmake)
diff --git a/Tests/RunCMake/Win32GenEx/Win32GenEx-release.cmake b/Tests/RunCMake/Win32GenEx/Win32GenEx-release.cmake
new file mode 100644
index 0000000000..74c5bd8a27
--- /dev/null
+++ b/Tests/RunCMake/Win32GenEx/Win32GenEx-release.cmake
@@ -0,0 +1 @@
+include(Win32GenEx.cmake)
diff --git a/Tests/RunCMake/Win32GenEx/Win32GenEx.cmake b/Tests/RunCMake/Win32GenEx/Win32GenEx.cmake
new file mode 100644
index 0000000000..80f8b80190
--- /dev/null
+++ b/Tests/RunCMake/Win32GenEx/Win32GenEx.cmake
@@ -0,0 +1,7 @@
+enable_language(C)
+
+add_executable(Win32GenEx main.c)
+set_target_properties(Win32GenEx PROPERTIES
+ WIN32_EXECUTABLE $<CONFIG:Release>
+ )
+target_compile_definitions(Win32GenEx PRIVATE $<$<CONFIG:Release>:USE_WIN32_MAIN>)
diff --git a/Tests/RunCMake/Win32GenEx/main.c b/Tests/RunCMake/Win32GenEx/main.c
new file mode 100644
index 0000000000..1cf9f81164
--- /dev/null
+++ b/Tests/RunCMake/Win32GenEx/main.c
@@ -0,0 +1,14 @@
+#ifdef USE_WIN32_MAIN
+# include <windows.h>
+
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine, int nShowCmd)
+{
+ return 0;
+}
+#else
+int main(void)
+{
+ return 0;
+}
+#endif