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

View File

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

View File

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

View File

@ -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,

View File

@ -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 "

View File

@ -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.

View 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
{ {

View File

@ -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.

View File

@ -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
) )

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 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.

View File

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