mirror of
https://github.com/reactos/CMake.git
synced 2025-01-31 08:52:21 +00:00
Add support for FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
This commit is contained in:
parent
d016637eef
commit
ad3f69c86e
@ -200,6 +200,7 @@ Properties on Targets
|
||||
/prop_tgt/Fortran_FORMAT
|
||||
/prop_tgt/Fortran_MODULE_DIRECTORY
|
||||
/prop_tgt/FRAMEWORK
|
||||
/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG
|
||||
/prop_tgt/FRAMEWORK_VERSION
|
||||
/prop_tgt/GENERATOR_FILE_NAME
|
||||
/prop_tgt/GHS_INTEGRITY_APP
|
||||
|
@ -388,6 +388,7 @@ Variables that Control the Build
|
||||
/variable/CMAKE_EXE_LINKER_FLAGS_INIT
|
||||
/variable/CMAKE_FOLDER
|
||||
/variable/CMAKE_FRAMEWORK
|
||||
/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG
|
||||
/variable/CMAKE_Fortran_FORMAT
|
||||
/variable/CMAKE_Fortran_MODULE_DIRECTORY
|
||||
/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE
|
||||
|
@ -8,3 +8,6 @@ is appended to the target file name built on disk. For non-executable
|
||||
targets, this property is initialized by the value of the variable
|
||||
CMAKE_<CONFIG>_POSTFIX if it is set when a target is created. This
|
||||
property is ignored on the Mac for Frameworks and App Bundles.
|
||||
|
||||
For macOS see also the :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>`
|
||||
target property.
|
||||
|
25
Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
Normal file
25
Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
Normal file
@ -0,0 +1,25 @@
|
||||
FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
|
||||
---------------------------------------
|
||||
|
||||
Postfix to append to the framework file name for configuration <CONFIG>,
|
||||
when using a multi-config generator (like Xcode and Ninja Multi-Config).
|
||||
|
||||
When building with configuration <CONFIG> the value of this property
|
||||
is appended to the framework file name built on disk.
|
||||
|
||||
For example given a framework called ``my_fw``, a value of ``_debug``
|
||||
for the :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` property, and
|
||||
``Debug;Release`` in `CMAKE_CONFIGURATION_TYPES`, the following relevant
|
||||
files would be created for the ``Debug`` and ``Release`` configurations:
|
||||
|
||||
- Release/my_fw.framework/my_fw
|
||||
- Release/my_fw.framework/Versions/A/my_fw
|
||||
- Debug/my_fw.framework/my_fw_debug
|
||||
- Debug/my_fw.framework/Versions/A/my_fw_debug
|
||||
|
||||
For framework targets, this property is initialized by the value of the
|
||||
variable :variable:`CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` if it
|
||||
is set when a target is created.
|
||||
|
||||
This property is ignored for non-framework targets, and when using single
|
||||
config generators.
|
7
Help/release/dev/framework-multi-config-postfix.rst
Normal file
7
Help/release/dev/framework-multi-config-postfix.rst
Normal file
@ -0,0 +1,7 @@
|
||||
framework-multi-config-postfix
|
||||
------------------------------
|
||||
|
||||
* The :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` target property
|
||||
and associated :variable:`CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>`
|
||||
variable were created to allow adding a postfix to the name of a
|
||||
framework file name when using a multi-config generator.
|
@ -0,0 +1,8 @@
|
||||
CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
|
||||
---------------------------------------------
|
||||
|
||||
Default framework filename postfix under configuration ``<CONFIG>`` when
|
||||
using a multi-config generator.
|
||||
|
||||
When a framework target is created its :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>`
|
||||
target property is initialized with the value of this variable if it is set.
|
@ -539,15 +539,43 @@ std::string cmGeneratorTarget::GetFileSuffix(
|
||||
std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
|
||||
{
|
||||
const char* postfix = nullptr;
|
||||
std::string frameworkPostfix;
|
||||
if (!config.empty()) {
|
||||
std::string configProp =
|
||||
cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
|
||||
postfix = this->GetProperty(configProp);
|
||||
// Mac application bundles and frameworks have no postfix.
|
||||
|
||||
// Mac application bundles and frameworks have no regular postfix like
|
||||
// libraries do.
|
||||
if (!this->IsImported() && postfix &&
|
||||
(this->IsAppBundleOnApple() || this->IsFrameworkOnApple())) {
|
||||
postfix = nullptr;
|
||||
}
|
||||
|
||||
// Frameworks created by multi config generators can have a special
|
||||
// framework postfix.
|
||||
frameworkPostfix = GetFrameworkMultiConfigPostfix(config);
|
||||
if (!frameworkPostfix.empty()) {
|
||||
postfix = frameworkPostfix.c_str();
|
||||
}
|
||||
}
|
||||
return postfix ? postfix : std::string();
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix(
|
||||
const std::string& config) const
|
||||
{
|
||||
const char* postfix = nullptr;
|
||||
if (!config.empty()) {
|
||||
std::string configProp = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
|
||||
cmSystemTools::UpperCase(config));
|
||||
postfix = this->GetProperty(configProp);
|
||||
|
||||
if (!this->IsImported() && postfix &&
|
||||
(this->IsFrameworkOnApple() &&
|
||||
!GetGlobalGenerator()->IsMultiConfig())) {
|
||||
postfix = nullptr;
|
||||
}
|
||||
}
|
||||
return postfix ? postfix : std::string();
|
||||
}
|
||||
@ -4241,8 +4269,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
|
||||
targetNames.Real += this->GetFrameworkVersion();
|
||||
targetNames.Real += "/";
|
||||
}
|
||||
targetNames.Real += targetNames.Base;
|
||||
targetNames.SharedObject = targetNames.Real;
|
||||
targetNames.Real += targetNames.Base + suffix;
|
||||
targetNames.SharedObject = targetNames.Real + suffix;
|
||||
} else {
|
||||
// The library's soname.
|
||||
this->ComputeVersionedName(targetNames.SharedObject, prefix,
|
||||
@ -4417,7 +4445,15 @@ void cmGeneratorTarget::GetFullNameInternal(
|
||||
outBase += this->GetOutputName(config, artifact);
|
||||
|
||||
// Append the per-configuration postfix.
|
||||
outBase += configPostfix;
|
||||
// When using Xcode, the postfix should be part of the suffix rather than the
|
||||
// base, because the suffix ends up being used in Xcode's EXECUTABLE_SUFFIX
|
||||
// attribute.
|
||||
if (this->IsFrameworkOnApple() &&
|
||||
GetGlobalGenerator()->GetName() == "Xcode") {
|
||||
targetSuffix = configPostfix.c_str();
|
||||
} else {
|
||||
outBase += configPostfix;
|
||||
}
|
||||
|
||||
// Name shared libraries with their version number on some platforms.
|
||||
if (const char* soversion = this->GetProperty("SOVERSION")) {
|
||||
|
@ -588,6 +588,9 @@ public:
|
||||
/** Get target file postfix */
|
||||
std::string GetFilePostfix(const std::string& config) const;
|
||||
|
||||
/** Get framework multi-config-specific postfix */
|
||||
std::string GetFrameworkMultiConfigPostfix(const std::string& config) const;
|
||||
|
||||
/** Clears cached meta data for local and external source files.
|
||||
* The meta data will be recomputed on demand.
|
||||
*/
|
||||
|
@ -812,8 +812,20 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
||||
targetOutputReal = this->ConvertToNinjaPath(targetOutputReal);
|
||||
} else if (gt->IsFrameworkOnApple()) {
|
||||
// Create the library framework.
|
||||
|
||||
cmOSXBundleGenerator::SkipParts bundleSkipParts;
|
||||
if (globalGen->GetName() == "Ninja Multi-Config") {
|
||||
const auto postFix = this->GeneratorTarget->GetFilePostfix(config);
|
||||
// Skip creating Info.plist when there are multiple configurations, and
|
||||
// the current configuration has a postfix. The non-postfix configuration
|
||||
// Info.plist can be used by all the other configurations.
|
||||
if (!postFix.empty()) {
|
||||
bundleSkipParts.infoPlist = true;
|
||||
}
|
||||
}
|
||||
|
||||
this->OSXBundleGenerator->CreateFramework(
|
||||
tgtNames.Output, gt->GetDirectory(config), config);
|
||||
tgtNames.Output, gt->GetDirectory(config), config, bundleSkipParts);
|
||||
} else if (gt->IsCFBundleOnApple()) {
|
||||
// Create the core foundation bundle.
|
||||
this->OSXBundleGenerator->CreateCFBundle(tgtNames.Output,
|
||||
|
@ -56,9 +56,9 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
|
||||
outpath = out;
|
||||
}
|
||||
|
||||
void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
|
||||
const std::string& outpath,
|
||||
const std::string& config)
|
||||
void cmOSXBundleGenerator::CreateFramework(
|
||||
const std::string& targetName, const std::string& outpath,
|
||||
const std::string& config, const cmOSXBundleGenerator::SkipParts& skipParts)
|
||||
{
|
||||
if (this->MustSkip()) {
|
||||
return;
|
||||
@ -77,16 +77,18 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
|
||||
|
||||
std::string frameworkVersion = this->GT->GetFrameworkVersion();
|
||||
|
||||
// Configure the Info.plist file
|
||||
std::string plist = newoutpath;
|
||||
if (!this->Makefile->PlatformIsAppleEmbedded()) {
|
||||
// Put the Info.plist file into the Resources directory.
|
||||
this->MacContentFolders->insert("Resources");
|
||||
plist += "/Resources";
|
||||
}
|
||||
plist += "/Info.plist";
|
||||
std::string name = cmSystemTools::GetFilenameName(targetName);
|
||||
this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
|
||||
if (!skipParts.infoPlist) {
|
||||
// Configure the Info.plist file
|
||||
std::string plist = newoutpath;
|
||||
if (!this->Makefile->PlatformIsAppleEmbedded()) {
|
||||
// Put the Info.plist file into the Resources directory.
|
||||
this->MacContentFolders->insert("Resources");
|
||||
plist += "/Resources";
|
||||
}
|
||||
plist += "/Info.plist";
|
||||
this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
|
||||
}
|
||||
|
||||
// Generate Versions directory only for MacOSX frameworks
|
||||
if (this->Makefile->PlatformIsAppleEmbedded()) {
|
||||
|
@ -19,6 +19,15 @@ class cmOSXBundleGenerator
|
||||
public:
|
||||
cmOSXBundleGenerator(cmGeneratorTarget* target);
|
||||
|
||||
struct SkipParts
|
||||
{
|
||||
SkipParts()
|
||||
: infoPlist(false)
|
||||
{
|
||||
}
|
||||
bool infoPlist; // NOLINT(modernize-use-default-member-init)
|
||||
};
|
||||
|
||||
// create an app bundle at a given root, and return
|
||||
// the directory within the bundle that contains the executable
|
||||
void CreateAppBundle(const std::string& targetName, std::string& root,
|
||||
@ -26,7 +35,8 @@ public:
|
||||
|
||||
// create a framework at a given root
|
||||
void CreateFramework(const std::string& targetName, const std::string& root,
|
||||
const std::string& config);
|
||||
const std::string& config,
|
||||
const SkipParts& skipParts = SkipParts());
|
||||
|
||||
// create a cf bundle at a given root
|
||||
void CreateCFBundle(const std::string& targetName, const std::string& root,
|
||||
|
@ -300,6 +300,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
||||
initProp("PDB_OUTPUT_DIRECTORY");
|
||||
initProp("COMPILE_PDB_OUTPUT_DIRECTORY");
|
||||
initProp("FRAMEWORK");
|
||||
initProp("FRAMEWORK_MULTI_CONFIG_POSTFIX");
|
||||
initProp("Fortran_FORMAT");
|
||||
initProp("Fortran_MODULE_DIRECTORY");
|
||||
initProp("Fortran_COMPILER_LAUNCHER");
|
||||
@ -435,6 +436,13 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
||||
cmStrCat(cmSystemTools::UpperCase(configName), "_POSTFIX");
|
||||
initProp(property);
|
||||
}
|
||||
|
||||
if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
|
||||
impl->TargetType == cmStateEnums::STATIC_LIBRARY) {
|
||||
std::string property = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
|
||||
cmSystemTools::UpperCase(configName));
|
||||
initProp(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,45 @@
|
||||
include("${RunCMake_TEST_BINARY_DIR}/FrameworkMultiConfigPostfixInfo.cmake")
|
||||
|
||||
get_filename_component(framework_location "${framework_dir}" DIRECTORY)
|
||||
set(non_existent_debug_framework_dir "${framework_location}/${target_file_name}_debug.framework")
|
||||
set(framework_resources "${framework_dir}/Resources")
|
||||
set(plist_file "${framework_resources}/Info.plist")
|
||||
|
||||
set(symlink_release_path "${framework_dir}/${target_file_name}")
|
||||
set(framework_release_path "${framework_dir}/Versions/A/${target_file_name}")
|
||||
|
||||
# When using a multi config generator (like Ninja Multi-Config and Xcode),
|
||||
# the postfix will be applied to the debug framework library name and the symlink name.
|
||||
# For single config generators, the name stays the same as the the release framework.
|
||||
if(is_multi_config)
|
||||
set(symlink_debug_path "${framework_dir}/${target_file_name}_debug")
|
||||
set(framework_debug_path "${framework_dir}/Versions/A/${target_file_name}_debug")
|
||||
else()
|
||||
set(symlink_debug_path "${framework_dir}/${target_file_name}")
|
||||
set(framework_debug_path "${framework_dir}/Versions/A/${target_file_name}")
|
||||
endif()
|
||||
|
||||
if(NOT IS_DIRECTORY ${framework_dir})
|
||||
message(SEND_ERROR "Framework dir not found at ${framework_dir}")
|
||||
endif()
|
||||
|
||||
if(IS_DIRECTORY ${non_existent_debug_framework_dir})
|
||||
message(SEND_ERROR
|
||||
"A framework dir with a debug suffix should not exist at ${non_existent_debug_framework_dir}")
|
||||
endif()
|
||||
|
||||
if(NOT IS_SYMLINK "${symlink_release_path}")
|
||||
message(SEND_ERROR "Release framework symlink not found at ${symlink_release_path}")
|
||||
endif()
|
||||
|
||||
if(NOT IS_SYMLINK "${symlink_debug_path}")
|
||||
message(SEND_ERROR "Debug framework symlink not found at ${symlink_debug_path}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${framework_release_path}")
|
||||
message(SEND_ERROR "Release framework not found at ${framework_release_path}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${framework_debug_path}")
|
||||
message(SEND_ERROR "Debug framework not found at ${framework_debug_path}")
|
||||
endif()
|
25
Tests/RunCMake/Framework/FrameworkMultiConfigPostfix.cmake
Normal file
25
Tests/RunCMake/Framework/FrameworkMultiConfigPostfix.cmake
Normal file
@ -0,0 +1,25 @@
|
||||
enable_language(C)
|
||||
|
||||
set(CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_DEBUG "_debug")
|
||||
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
|
||||
set(target_name "mylib")
|
||||
add_library(${target_name} SHARED foo.c)
|
||||
set_property(TARGET ${target_name} PROPERTY FRAMEWORK ON)
|
||||
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
|
||||
string(APPEND content
|
||||
"set(is_multi_config \"${is_multi_config}\")\n"
|
||||
"set(framework_dir \"$<TARGET_BUNDLE_DIR:${target_name}>\")\n"
|
||||
"set(target_file_name ${target_name})\n")
|
||||
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/FrameworkMultiConfigPostfixInfo.cmake
|
||||
CONTENT "${content}")
|
@ -45,3 +45,39 @@ framework_type_test(ios SHARED YES)
|
||||
framework_type_test(ios STATIC YES)
|
||||
framework_type_test(osx SHARED YES)
|
||||
framework_type_test(osx STATIC YES)
|
||||
|
||||
function(framework_multi_config_postfix_test)
|
||||
set(configure_name "FrameworkMultiConfigPostfix")
|
||||
set(build_name "${configure_name}-build-intermediate")
|
||||
set(build_name_final "${configure_name}-build-final")
|
||||
|
||||
if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
|
||||
set(RunCMake_TEST_OPTIONS
|
||||
"-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
|
||||
elseif(RunCMake_GENERATOR MATCHES "Xcode")
|
||||
set(RunCMake_TEST_OPTIONS
|
||||
"-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release")
|
||||
else()
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE=Debug")
|
||||
endif()
|
||||
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${configure_name})
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
run_cmake(${configure_name})
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
|
||||
if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
|
||||
run_cmake_command(${build_name_final} ${CMAKE_COMMAND} --build . --target all:all)
|
||||
elseif(RunCMake_GENERATOR MATCHES "Xcode")
|
||||
run_cmake_command(${build_name} ${CMAKE_COMMAND} --build . --config Release)
|
||||
run_cmake_command(${build_name} ${CMAKE_COMMAND} --build . --config Debug)
|
||||
run_cmake_command(${build_name_final} ${CMAKE_COMMAND} --build . --config Debug)
|
||||
else()
|
||||
run_cmake_command(${build_name_final} ${CMAKE_COMMAND} --build .)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
framework_multi_config_postfix_test()
|
||||
|
Loading…
x
Reference in New Issue
Block a user