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:
Brad King 2008-01-28 14:46:16 -05:00
parent 437043bb04
commit e3b1bdb058
12 changed files with 90 additions and 18 deletions

View File

@ -84,6 +84,11 @@ cmExportBuildFileGenerator
std::string prop = "IMPORTED_LOCATION";
prop += suffix;
std::string value = target->GetFullPath(config, false);
if(target->IsAppBundleOnApple())
{
value += ".app/Contents/MacOS/";
value += target->GetFullName(config, false);
}
properties[prop] = value;
}

View File

@ -282,14 +282,19 @@ cmExportFileGenerator
<< " PROPERTY ENABLE_EXPORTS 1)\n";
}
// Mark the imported framework. This is done even on non-Apple
// platforms for reference and consistency purposes.
if(target->GetType() == cmTarget::SHARED_LIBRARY &&
target->GetPropertyAsBool("FRAMEWORK"))
// Mark the imported library if it is a framework.
if(target->IsFrameworkOnApple())
{
os << "SET_PROPERTY(TARGET " << targetName
<< " 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";
}

View File

@ -160,8 +160,8 @@ cmExportInstallFileGenerator
te->RuntimeGenerator, properties);
this->SetImportLocationProperty(config, suffix,
te->FrameworkGenerator, properties);
// TODO: Bundles?
this->SetImportLocationProperty(config, suffix,
te->BundleGenerator, properties);
// If any file location was set for the target add it to the
// import file.
@ -227,12 +227,17 @@ cmExportInstallFileGenerator
std::string fname = itgen->GetInstallFilename(config);
value += fname;
// Fix name for frameworks.
// Fix name for frameworks and bundles.
if(itgen->GetTarget()->IsFrameworkOnApple())
{
value += ".framework/";
value += fname;
}
else if(itgen->GetTarget()->IsAppBundleOnApple())
{
value += ".app/Contents/MacOS/";
value += fname;
}
// Store the property.
properties[prop] = value;

View File

@ -451,9 +451,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
break;
case cmTarget::EXECUTABLE:
{
// Executables use the RUNTIME properties.
if(target.GetPropertyAsBool("MACOSX_BUNDLE"))
if(target.IsAppBundleOnApple())
{
// Application bundles use the BUNDLE properties.
if (!bundleArgs.GetDestination().empty())
{
bundleGenerator = CreateInstallTargetGenerator(target, bundleArgs,
@ -470,6 +470,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
else
{
// Executables use the RUNTIME properties.
if (!runtimeArgs.GetDestination().empty())
{
runtimeGenerator = CreateInstallTargetGenerator(target,

View File

@ -99,7 +99,7 @@ public:
"\n"
"The TARGETS signature:\n"
" install(TARGETS targets... [EXPORT <export-name>]\n"
" [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK]\n"
" [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE]\n"
" [DESTINATION <dir>]\n"
" [PERMISSIONS permissions...]\n"
" [CONFIGURATIONS [Debug|Release|...]]\n"
@ -107,10 +107,12 @@ public:
" [OPTIONAL]\n"
" ] [...])\n"
"The TARGETS form specifies rules for installing targets from a "
"project. There are four kinds of target files that may be "
"installed: archive, library, runtime, and framework. "
"project. There are five kinds of target files that may be "
"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. "
"Module libraries are always treated as library targets. "
"For non-DLL platforms shared libraries are treated as library "

View File

@ -176,8 +176,7 @@ cmInstallTargetGenerator
from1 += targetName;
// Handle OSX Bundles.
if(this->Target->GetMakefile()->IsOn("APPLE") &&
this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
if(this->Target->IsAppBundleOnApple())
{
// Compute the source locations of the bundle executable and
// Info.plist file.

View File

@ -205,6 +205,8 @@ void cmTarget::DefineProperties(cmake *cm)
"Full path to the main file on disk for an IMPORTED target.",
"Specifies the location of an IMPORTED target file on disk. "
"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 "
"library or module. "
"For shared libraries on non-DLL platforms this is the location of "
@ -605,6 +607,14 @@ bool cmTarget::IsFrameworkOnApple()
this->GetPropertyAsBool("FRAMEWORK"));
}
//----------------------------------------------------------------------------
bool cmTarget::IsAppBundleOnApple()
{
return (this->GetType() == cmTarget::EXECUTABLE &&
this->Makefile->IsOn("APPLE") &&
this->GetPropertyAsBool("MACOSX_BUNDLE"));
}
//----------------------------------------------------------------------------
class cmTargetTraceDependencies
{

View File

@ -324,6 +324,9 @@ public:
Apple. */
bool IsFrameworkOnApple();
/** Return whether this target is an executable Bundle on Apple. */
bool IsAppBundleOnApple();
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.

View File

@ -21,14 +21,18 @@ add_library(testLib3 SHARED testLib3.c)
add_library(testLib4 SHARED testLib4.c)
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(
TARGETS testExe1 testLib1 testLib2 testExe2 testLib3 testLib4
TARGETS testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3
EXPORT exp
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
FRAMEWORK DESTINATION Frameworks
BUNDLE DESTINATION Applications
)
install(EXPORT exp NAMESPACE exp_ DESTINATION lib/exp)
@ -37,7 +41,7 @@ export(TARGETS testExe1 testLib1 testLib2
NAMESPACE bld_
FILE ExportBuildTree.cmake
)
export(TARGETS testExe2 testLib3 testLib4
export(TARGETS testExe2 testLib3 testLib4 testExe3
NAMESPACE bld_
APPEND FILE ExportBuildTree.cmake
)

View File

@ -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;
}

View File

@ -17,10 +17,16 @@ add_custom_command(
COMMAND exp_testExe1 ${Import_BINARY_DIR}/exp_generated.c
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
imp_testExe1.c
${Import_BINARY_DIR}/exp_generated.c
${Import_BINARY_DIR}/exp_generated3.c
)
# 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
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
imp_testExe1.c
${Import_BINARY_DIR}/bld_generated.c
${Import_BINARY_DIR}/bld_generated3.c
)
# Try linking to a library imported from the build tree.

View File

@ -1,9 +1,11 @@
extern int generated_by_testExe1();
extern int generated_by_testExe3();
extern int testLib2();
extern int testLib3();
extern int testLib4();
int main()
{
return testLib2() + generated_by_testExe1() + testLib3() + testLib4();
return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
+ generated_by_testExe3());
}