ENH: Support exporting/importing of AppBundle targets.
- Imported bundles have the MACOSX_BUNDLE property set - Added cmTarget::IsAppBundleOnApple method to simplify checks - Document BUNDLE keyword in INSTALL command - Updated IMPORTED_LOCATION property documentation for bundles - Updated ExportImport test to test bundles
This commit is contained in:
parent
437043bb04
commit
e3b1bdb058
|
@ -84,6 +84,11 @@ cmExportBuildFileGenerator
|
||||||
std::string prop = "IMPORTED_LOCATION";
|
std::string prop = "IMPORTED_LOCATION";
|
||||||
prop += suffix;
|
prop += suffix;
|
||||||
std::string value = target->GetFullPath(config, false);
|
std::string value = target->GetFullPath(config, false);
|
||||||
|
if(target->IsAppBundleOnApple())
|
||||||
|
{
|
||||||
|
value += ".app/Contents/MacOS/";
|
||||||
|
value += target->GetFullName(config, false);
|
||||||
|
}
|
||||||
properties[prop] = value;
|
properties[prop] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -282,14 +282,19 @@ cmExportFileGenerator
|
||||||
<< " PROPERTY ENABLE_EXPORTS 1)\n";
|
<< " PROPERTY ENABLE_EXPORTS 1)\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the imported framework. This is done even on non-Apple
|
// Mark the imported library if it is a framework.
|
||||||
// platforms for reference and consistency purposes.
|
if(target->IsFrameworkOnApple())
|
||||||
if(target->GetType() == cmTarget::SHARED_LIBRARY &&
|
|
||||||
target->GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
os << "SET_PROPERTY(TARGET " << targetName
|
os << "SET_PROPERTY(TARGET " << targetName
|
||||||
<< " PROPERTY FRAMEWORK 1)\n";
|
<< " PROPERTY FRAMEWORK 1)\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark the imported executable if it is an application bundle.
|
||||||
|
if(target->IsAppBundleOnApple())
|
||||||
|
{
|
||||||
|
os << "SET_PROPERTY(TARGET " << targetName
|
||||||
|
<< " PROPERTY MACOSX_BUNDLE 1)\n";
|
||||||
|
}
|
||||||
os << "\n";
|
os << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,8 +160,8 @@ cmExportInstallFileGenerator
|
||||||
te->RuntimeGenerator, properties);
|
te->RuntimeGenerator, properties);
|
||||||
this->SetImportLocationProperty(config, suffix,
|
this->SetImportLocationProperty(config, suffix,
|
||||||
te->FrameworkGenerator, properties);
|
te->FrameworkGenerator, properties);
|
||||||
|
this->SetImportLocationProperty(config, suffix,
|
||||||
// TODO: Bundles?
|
te->BundleGenerator, properties);
|
||||||
|
|
||||||
// If any file location was set for the target add it to the
|
// If any file location was set for the target add it to the
|
||||||
// import file.
|
// import file.
|
||||||
|
@ -227,12 +227,17 @@ cmExportInstallFileGenerator
|
||||||
std::string fname = itgen->GetInstallFilename(config);
|
std::string fname = itgen->GetInstallFilename(config);
|
||||||
value += fname;
|
value += fname;
|
||||||
|
|
||||||
// Fix name for frameworks.
|
// Fix name for frameworks and bundles.
|
||||||
if(itgen->GetTarget()->IsFrameworkOnApple())
|
if(itgen->GetTarget()->IsFrameworkOnApple())
|
||||||
{
|
{
|
||||||
value += ".framework/";
|
value += ".framework/";
|
||||||
value += fname;
|
value += fname;
|
||||||
}
|
}
|
||||||
|
else if(itgen->GetTarget()->IsAppBundleOnApple())
|
||||||
|
{
|
||||||
|
value += ".app/Contents/MacOS/";
|
||||||
|
value += fname;
|
||||||
|
}
|
||||||
|
|
||||||
// Store the property.
|
// Store the property.
|
||||||
properties[prop] = value;
|
properties[prop] = value;
|
||||||
|
|
|
@ -451,9 +451,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
||||||
break;
|
break;
|
||||||
case cmTarget::EXECUTABLE:
|
case cmTarget::EXECUTABLE:
|
||||||
{
|
{
|
||||||
// Executables use the RUNTIME properties.
|
if(target.IsAppBundleOnApple())
|
||||||
if(target.GetPropertyAsBool("MACOSX_BUNDLE"))
|
|
||||||
{
|
{
|
||||||
|
// Application bundles use the BUNDLE properties.
|
||||||
if (!bundleArgs.GetDestination().empty())
|
if (!bundleArgs.GetDestination().empty())
|
||||||
{
|
{
|
||||||
bundleGenerator = CreateInstallTargetGenerator(target, bundleArgs,
|
bundleGenerator = CreateInstallTargetGenerator(target, bundleArgs,
|
||||||
|
@ -470,6 +470,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Executables use the RUNTIME properties.
|
||||||
if (!runtimeArgs.GetDestination().empty())
|
if (!runtimeArgs.GetDestination().empty())
|
||||||
{
|
{
|
||||||
runtimeGenerator = CreateInstallTargetGenerator(target,
|
runtimeGenerator = CreateInstallTargetGenerator(target,
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
"\n"
|
"\n"
|
||||||
"The TARGETS signature:\n"
|
"The TARGETS signature:\n"
|
||||||
" install(TARGETS targets... [EXPORT <export-name>]\n"
|
" install(TARGETS targets... [EXPORT <export-name>]\n"
|
||||||
" [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK]\n"
|
" [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE]\n"
|
||||||
" [DESTINATION <dir>]\n"
|
" [DESTINATION <dir>]\n"
|
||||||
" [PERMISSIONS permissions...]\n"
|
" [PERMISSIONS permissions...]\n"
|
||||||
" [CONFIGURATIONS [Debug|Release|...]]\n"
|
" [CONFIGURATIONS [Debug|Release|...]]\n"
|
||||||
|
@ -107,10 +107,12 @@ public:
|
||||||
" [OPTIONAL]\n"
|
" [OPTIONAL]\n"
|
||||||
" ] [...])\n"
|
" ] [...])\n"
|
||||||
"The TARGETS form specifies rules for installing targets from a "
|
"The TARGETS form specifies rules for installing targets from a "
|
||||||
"project. There are four kinds of target files that may be "
|
"project. There are five kinds of target files that may be "
|
||||||
"installed: archive, library, runtime, and framework. "
|
"installed: archive, library, runtime, framework, and bundle. "
|
||||||
|
|
||||||
"Executables are always treated as runtime targets. "
|
"Executables are treated as runtime targets, except that those "
|
||||||
|
"marked with the MACOSX_BUNDLE property are treated as bundle "
|
||||||
|
"targets on OS X. "
|
||||||
"Static libraries are always treated as archive targets. "
|
"Static libraries are always treated as archive targets. "
|
||||||
"Module libraries are always treated as library targets. "
|
"Module libraries are always treated as library targets. "
|
||||||
"For non-DLL platforms shared libraries are treated as library "
|
"For non-DLL platforms shared libraries are treated as library "
|
||||||
|
|
|
@ -176,8 +176,7 @@ cmInstallTargetGenerator
|
||||||
from1 += targetName;
|
from1 += targetName;
|
||||||
|
|
||||||
// Handle OSX Bundles.
|
// Handle OSX Bundles.
|
||||||
if(this->Target->GetMakefile()->IsOn("APPLE") &&
|
if(this->Target->IsAppBundleOnApple())
|
||||||
this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
|
|
||||||
{
|
{
|
||||||
// Compute the source locations of the bundle executable and
|
// Compute the source locations of the bundle executable and
|
||||||
// Info.plist file.
|
// Info.plist file.
|
||||||
|
|
|
@ -205,6 +205,8 @@ void cmTarget::DefineProperties(cmake *cm)
|
||||||
"Full path to the main file on disk for an IMPORTED target.",
|
"Full path to the main file on disk for an IMPORTED target.",
|
||||||
"Specifies the location of an IMPORTED target file on disk. "
|
"Specifies the location of an IMPORTED target file on disk. "
|
||||||
"For executables this is the location of the executable file. "
|
"For executables this is the location of the executable file. "
|
||||||
|
"For bundles on OS X this is the location of the executable file "
|
||||||
|
"inside Contents/MacOS under the application bundle folder. "
|
||||||
"For static libraries and modules this is the location of the "
|
"For static libraries and modules this is the location of the "
|
||||||
"library or module. "
|
"library or module. "
|
||||||
"For shared libraries on non-DLL platforms this is the location of "
|
"For shared libraries on non-DLL platforms this is the location of "
|
||||||
|
@ -605,6 +607,14 @@ bool cmTarget::IsFrameworkOnApple()
|
||||||
this->GetPropertyAsBool("FRAMEWORK"));
|
this->GetPropertyAsBool("FRAMEWORK"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmTarget::IsAppBundleOnApple()
|
||||||
|
{
|
||||||
|
return (this->GetType() == cmTarget::EXECUTABLE &&
|
||||||
|
this->Makefile->IsOn("APPLE") &&
|
||||||
|
this->GetPropertyAsBool("MACOSX_BUNDLE"));
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class cmTargetTraceDependencies
|
class cmTargetTraceDependencies
|
||||||
{
|
{
|
||||||
|
|
|
@ -324,6 +324,9 @@ public:
|
||||||
Apple. */
|
Apple. */
|
||||||
bool IsFrameworkOnApple();
|
bool IsFrameworkOnApple();
|
||||||
|
|
||||||
|
/** Return whether this target is an executable Bundle on Apple. */
|
||||||
|
bool IsAppBundleOnApple();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||||
|
|
|
@ -21,14 +21,18 @@ add_library(testLib3 SHARED testLib3.c)
|
||||||
add_library(testLib4 SHARED testLib4.c)
|
add_library(testLib4 SHARED testLib4.c)
|
||||||
set_property(TARGET testLib4 PROPERTY FRAMEWORK 1)
|
set_property(TARGET testLib4 PROPERTY FRAMEWORK 1)
|
||||||
|
|
||||||
|
add_executable(testExe3 testExe3.c)
|
||||||
|
set_property(TARGET testExe3 PROPERTY MACOSX_BUNDLE 1)
|
||||||
|
|
||||||
# Install and export from install tree.
|
# Install and export from install tree.
|
||||||
install(
|
install(
|
||||||
TARGETS testExe1 testLib1 testLib2 testExe2 testLib3 testLib4
|
TARGETS testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3
|
||||||
EXPORT exp
|
EXPORT exp
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
LIBRARY DESTINATION lib
|
LIBRARY DESTINATION lib
|
||||||
ARCHIVE DESTINATION lib
|
ARCHIVE DESTINATION lib
|
||||||
FRAMEWORK DESTINATION Frameworks
|
FRAMEWORK DESTINATION Frameworks
|
||||||
|
BUNDLE DESTINATION Applications
|
||||||
)
|
)
|
||||||
install(EXPORT exp NAMESPACE exp_ DESTINATION lib/exp)
|
install(EXPORT exp NAMESPACE exp_ DESTINATION lib/exp)
|
||||||
|
|
||||||
|
@ -37,7 +41,7 @@ export(TARGETS testExe1 testLib1 testLib2
|
||||||
NAMESPACE bld_
|
NAMESPACE bld_
|
||||||
FILE ExportBuildTree.cmake
|
FILE ExportBuildTree.cmake
|
||||||
)
|
)
|
||||||
export(TARGETS testExe2 testLib3 testLib4
|
export(TARGETS testExe2 testLib3 testLib4 testExe3
|
||||||
NAMESPACE bld_
|
NAMESPACE bld_
|
||||||
APPEND FILE ExportBuildTree.cmake
|
APPEND FILE ExportBuildTree.cmake
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[])
|
||||||
|
{
|
||||||
|
if(argc < 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Must specify output file.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FILE* f = fopen(argv[1], "w");
|
||||||
|
if(f)
|
||||||
|
{
|
||||||
|
fprintf(f, "int generated_by_testExe3() { return 0; }\n");
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing to %s\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -17,10 +17,16 @@ add_custom_command(
|
||||||
COMMAND exp_testExe1 ${Import_BINARY_DIR}/exp_generated.c
|
COMMAND exp_testExe1 ${Import_BINARY_DIR}/exp_generated.c
|
||||||
DEPENDS exp_testExe1
|
DEPENDS exp_testExe1
|
||||||
)
|
)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${Import_BINARY_DIR}/exp_generated3.c
|
||||||
|
COMMAND exp_testExe3 ${Import_BINARY_DIR}/exp_generated3.c
|
||||||
|
DEPENDS exp_testExe3
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(imp_testExe1
|
add_executable(imp_testExe1
|
||||||
imp_testExe1.c
|
imp_testExe1.c
|
||||||
${Import_BINARY_DIR}/exp_generated.c
|
${Import_BINARY_DIR}/exp_generated.c
|
||||||
|
${Import_BINARY_DIR}/exp_generated3.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Try linking to a library imported from the install tree.
|
# Try linking to a library imported from the install tree.
|
||||||
|
@ -36,10 +42,16 @@ add_custom_command(
|
||||||
COMMAND bld_testExe1 ${Import_BINARY_DIR}/bld_generated.c
|
COMMAND bld_testExe1 ${Import_BINARY_DIR}/bld_generated.c
|
||||||
DEPENDS bld_testExe1
|
DEPENDS bld_testExe1
|
||||||
)
|
)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${Import_BINARY_DIR}/bld_generated3.c
|
||||||
|
COMMAND bld_testExe3 ${Import_BINARY_DIR}/bld_generated3.c
|
||||||
|
DEPENDS bld_testExe3
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(imp_testExe1b
|
add_executable(imp_testExe1b
|
||||||
imp_testExe1.c
|
imp_testExe1.c
|
||||||
${Import_BINARY_DIR}/bld_generated.c
|
${Import_BINARY_DIR}/bld_generated.c
|
||||||
|
${Import_BINARY_DIR}/bld_generated3.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Try linking to a library imported from the build tree.
|
# Try linking to a library imported from the build tree.
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
extern int generated_by_testExe1();
|
extern int generated_by_testExe1();
|
||||||
|
extern int generated_by_testExe3();
|
||||||
extern int testLib2();
|
extern int testLib2();
|
||||||
extern int testLib3();
|
extern int testLib3();
|
||||||
extern int testLib4();
|
extern int testLib4();
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
return testLib2() + generated_by_testExe1() + testLib3() + testLib4();
|
return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
|
||||||
|
+ generated_by_testExe3());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue