From e3b1bdb058ac23bc535b941fc2ed66a410932d74 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 28 Jan 2008 14:46:16 -0500 Subject: 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 --- Source/cmExportBuildFileGenerator.cxx | 5 +++++ Source/cmExportFileGenerator.cxx | 13 +++++++++---- Source/cmExportInstallFileGenerator.cxx | 11 ++++++++--- Source/cmInstallCommand.cxx | 5 +++-- Source/cmInstallCommand.h | 10 ++++++---- Source/cmInstallTargetGenerator.cxx | 3 +-- Source/cmTarget.cxx | 10 ++++++++++ Source/cmTarget.h | 3 +++ Tests/ExportImport/Export/CMakeLists.txt | 8 ++++++-- Tests/ExportImport/Export/testExe3.c | 24 ++++++++++++++++++++++++ Tests/ExportImport/Import/CMakeLists.txt | 12 ++++++++++++ Tests/ExportImport/Import/imp_testExe1.c | 4 +++- 12 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 Tests/ExportImport/Export/testExe3.c diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 0412c90..3b634e6 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -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; } diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index d2c8ccb..6cf30c9 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -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"; } diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index f378106..fe6cdb5 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -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; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 863f138..056e276 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -451,9 +451,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector 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 const& args) } else { + // Executables use the RUNTIME properties. if (!runtimeArgs.GetDestination().empty()) { runtimeGenerator = CreateInstallTargetGenerator(target, diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index ed3a3a2..e93c1f7 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -99,7 +99,7 @@ public: "\n" "The TARGETS signature:\n" " install(TARGETS targets... [EXPORT ]\n" - " [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK]\n" + " [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE]\n" " [DESTINATION ]\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 " diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index ae16288..2cbb31e 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -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. diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 39b8a4e..5e37ced 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -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 " @@ -606,6 +608,14 @@ bool cmTarget::IsFrameworkOnApple() } //---------------------------------------------------------------------------- +bool cmTarget::IsAppBundleOnApple() +{ + return (this->GetType() == cmTarget::EXECUTABLE && + this->Makefile->IsOn("APPLE") && + this->GetPropertyAsBool("MACOSX_BUNDLE")); +} + +//---------------------------------------------------------------------------- class cmTargetTraceDependencies { public: diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 45359bb..c1de1a3 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -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. diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index ac2f10f..24a3a56 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -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 ) diff --git a/Tests/ExportImport/Export/testExe3.c b/Tests/ExportImport/Export/testExe3.c new file mode 100644 index 0000000..895e2fc --- /dev/null +++ b/Tests/ExportImport/Export/testExe3.c @@ -0,0 +1,24 @@ +#include + +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; +} diff --git a/Tests/ExportImport/Import/CMakeLists.txt b/Tests/ExportImport/Import/CMakeLists.txt index e6be1a8..b54a069 100644 --- a/Tests/ExportImport/Import/CMakeLists.txt +++ b/Tests/ExportImport/Import/CMakeLists.txt @@ -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. diff --git a/Tests/ExportImport/Import/imp_testExe1.c b/Tests/ExportImport/Import/imp_testExe1.c index 52ad8ff..0fbb689 100644 --- a/Tests/ExportImport/Import/imp_testExe1.c +++ b/Tests/ExportImport/Import/imp_testExe1.c @@ -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()); } -- cgit v0.12