Hi there,

I refactored the patches of Brian Milco to support code signing of bundles
in MacOS. As we don't need AppStore support at the moment we didn't added
the special generator for it. That could be a separate step later.

As long as it runs codesign only it should be trivial enough to add it. Is
it possible to add it to cmake 3.1?

Original commits are taken from github: https://github.com/iPenguin/cmake

Best regards
   André Klitzing
From 2e2245942f9d30b4703f79584a2f48a801aac8ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= <aklitz...@gmail.com>
Date: Thu, 25 Sep 2014 16:15:24 +0200
Subject: [PATCH] Add support for codesign on MacOS

Refactored patch of Brian Milco <bcmi...@gmail.com>
https://github.com/iPenguin/cmake
---
 Modules/CPackDMG.cmake                     |  24 ++++++
 Source/CPack/cmCPackBundleGenerator.cxx    |  18 ++++-
 Source/CPack/cmCPackBundleGenerator.h      |   1 +
 Source/CPack/cmCPackDragNDropGenerator.cxx | 114 +++++++++++++++++++++++++++++
 Source/CPack/cmCPackDragNDropGenerator.h   |   1 +
 5 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/Modules/CPackDMG.cmake b/Modules/CPackDMG.cmake
index b7a6ba5..fb9fe39 100644
--- a/Modules/CPackDMG.cmake
+++ b/Modules/CPackDMG.cmake
@@ -36,6 +36,23 @@
 #  background image is set. The background image is applied after applying the
 #  custom .DS_Store file.
 #
+#
+#
+# .. variable:: CPACK_APPLE_CERT_APP
+#  The name of your Apple supplied code signing certificate for the application.
+#  The name usually takes the form "Developer ID Application: [Name]" or
+#  "3rd Party Mac Developer Application: [Name]". If this variable is not set
+#  the application will not be signed.
+#
+# .. variable:: CPACK_APPLE_ENTITLEMENTS
+#  The name of the plist file that contains your apple entitlements for sandboxing
+#  your application. This file is required for submission to the Mac App Store.
+#
+# .. variable:: CPACK_APPLE_CODESIGN_FILES
+#  A list of additional files that you wish to be signed. You do not need to
+#  list the main application folder, or the main executable. You should
+#  list any frameworks and plugins that are included in your app bundle.
+#
 # .. variable:: CPACK_COMMAND_HDIUTIL
 #
 #  Path to the hdiutil(1) command used to operate on disk image files on Mac
@@ -54,6 +71,13 @@
 #  Path to the Rez(1) command used to compile resources on Mac OS X. This
 #  variable can be used to override the automatically detected command (or
 #  specify its location if the auto-detection fails to find it.)
+#
+# .. variable:: CPACK_COMMAND_CODESIGN
+#  Path to the codesign(1) command used to sign applications with an
+#  Apple cert. This variable can be used to override the automatically
+#  detected command (or specify its location if the auto-detection fails
+#  to find it.)
+#
 
 #=============================================================================
 # Copyright 2006-2012 Kitware, Inc.
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
index 6c994f1..c5f7139 100644
--- a/Source/CPack/cmCPackBundleGenerator.cxx
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -53,7 +53,7 @@ const char* cmCPackBundleGenerator::GetPackagingInstallPrefix()
 }
 
 //----------------------------------------------------------------------
-int cmCPackBundleGenerator::PackageFiles()
+int cmCPackBundleGenerator::ConstructAppBundle()
 {
 
   // Get required arguments ...
@@ -165,6 +165,22 @@ int cmCPackBundleGenerator::PackageFiles()
     cmSystemTools::SetPermissions(command_target.str().c_str(), 0777);
     }
 
+  return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackBundleGenerator::PackageFiles()
+{
+  if(!this->ConstructAppBundle())
+    {
+    return 0;
+    }
+
+  if(!this->SignPackage(toplevel))
+    {
+    return 0;
+    }
+
   return this->CreateDMG(toplevel, packageFileNames[0]);
 }
 
diff --git a/Source/CPack/cmCPackBundleGenerator.h b/Source/CPack/cmCPackBundleGenerator.h
index ed0187d..fa9f2fa 100644
--- a/Source/CPack/cmCPackBundleGenerator.h
+++ b/Source/CPack/cmCPackBundleGenerator.h
@@ -31,6 +31,7 @@ public:
 protected:
   virtual int InitializeInternal();
   virtual const char* GetPackagingInstallPrefix();
+  int ConstructAppBundle();
   int PackageFiles();
   bool SupportsComponentInstallation() const;
 
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 9f0a77e..b3041f1 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -103,6 +103,17 @@ int cmCPackDragNDropGenerator::InitializeInternal()
     }
   this->SetOptionIfNotSet("CPACK_COMMAND_REZ", rez_path.c_str());
 
+  const std::string codesign_path = cmSystemTools::FindProgram("codesign",
+    std::vector<std::string>(), false);
+  if(codesign_path.empty())
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "Cannot locate codesign command"
+      << std::endl);
+    return 0;
+    }
+  this->SetOptionIfNotSet("CPACK_COMMAND_CODESIGN", codesign_path.c_str());
+
   return this->Superclass::InitializeInternal();
 }
 
@@ -121,6 +132,9 @@ int cmCPackDragNDropGenerator::PackageFiles()
   // monolith
   if(this->Components.empty())
     {
+    if(!this->SignPackage(toplevel))
+        return 0;
+
     return this->CreateDMG(toplevel, packageFileNames[0]);
     }
 
@@ -160,6 +174,9 @@ int cmCPackDragNDropGenerator::PackageFiles()
     src_dir += "/";
     src_dir += package_files[i];
 
+    if(!this->SignPackage(toplevel))
+        return 0;
+
     if(0 == this->CreateDMG(src_dir, full_package_name))
       {
       return 0;
@@ -216,6 +233,103 @@ bool cmCPackDragNDropGenerator::RunCommand(cmOStringStream& command,
   return true;
 }
 
+int cmCPackDragNDropGenerator::SignPackage(const std::string& src_dir)
+{
+  // Get optional arguments ...
+  const std::string cpack_apple_cert_app =
+    this->GetOption("CPACK_APPLE_CERT_APP")
+    ? this->GetOption("CPACK_APPLE_CERT_APP") : "";
+
+  //A list of additional files to sign, ie. frameworks and plugins.
+  const std::string sign_files =
+    this->GetOption("CPACK_APPLE_CODESIGN_FILES")
+    ? this->GetOption("CPACK_APPLE_CODESIGN_FILES") : "";
+
+  cmOStringStream staging;
+  staging << src_dir;
+
+  //Optionally codesign the application.
+  if(!cpack_apple_cert_app.empty())
+    {
+    std::string bundle_path;
+    bundle_path = staging.str() + "/";
+    bundle_path += this->GetOption("CPACK_BUNDLE_NAME");
+    bundle_path += ".app";
+
+    std::vector<std::string> relFiles;
+
+    cmSystemTools::ExpandListArgument(sign_files, relFiles);
+
+    //sign the files supplied by the user, ie. frameworks.
+    for(std::vector<std::string>::iterator it = relFiles.begin();
+      it != relFiles.end(); ++it)
+      {
+      cmOStringStream temp_sign_file_cmd;
+      temp_sign_file_cmd << this->GetOption("CPACK_COMMAND_CODESIGN");
+      temp_sign_file_cmd << " --deep -f -s \"" << cpack_apple_cert_app;
+      temp_sign_file_cmd << "\" -i ";
+      temp_sign_file_cmd << this->GetOption("CPACK_APPLE_BUNDLE_ID");
+      temp_sign_file_cmd << " \"";
+      temp_sign_file_cmd << bundle_path;
+      temp_sign_file_cmd << it->c_str() << "\"";
+
+      if(!this->RunCommand(temp_sign_file_cmd))
+        {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+          "Error signing file:"
+          << bundle_path << it->c_str() << std::endl);
+
+        return 0;
+        }
+      }
+
+    //sign main binary
+    cmOStringStream temp_sign_binary_cmd;
+    temp_sign_binary_cmd << this->GetOption("CPACK_COMMAND_CODESIGN");
+    temp_sign_binary_cmd << " --deep -f -s \"" << cpack_apple_cert_app;
+    temp_sign_binary_cmd << "\" \"" << bundle_path << "\"";
+
+    if(!this->RunCommand(temp_sign_binary_cmd))
+      {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+        "Error signing the application binary."
+        << std::endl);
+
+      return 0;
+      }
+
+    //sign app bundle
+    cmOStringStream temp_codesign_cmd;
+    temp_codesign_cmd << this->GetOption("CPACK_COMMAND_CODESIGN");
+    temp_codesign_cmd << " --deep -f -s \"" << cpack_apple_cert_app << "\"";
+    if(this->GetOption("CPACK_APPLE_ENTITLEMENTS"))
+      {
+      temp_codesign_cmd << " --entitlements ";
+      temp_codesign_cmd << this->GetOption("CPACK_APPLE_ENTITLEMENTS");
+      }
+    temp_codesign_cmd << " \"" << bundle_path << "\"";
+
+    if(!this->RunCommand(temp_codesign_cmd))
+      {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+        "Error signing the application package."
+        << std::endl);
+
+      return 0;
+      }
+
+    cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+      "- Application has been codesigned"
+      << std::endl);
+    cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+       (this->GetOption("CPACK_APPLE_ENTITLEMENTS")
+         ? "with entitlement sandboxing" : "without entitlement sandboxing")
+       << std::endl);
+  }
+
+  return 1;
+}
+
 //----------------------------------------------------------------------
 int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
                                          const std::string& output_file)
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index 808c618..b852422 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -39,6 +39,7 @@ protected:
   std::string
   GetComponentInstallDirNameSuffix(const std::string& componentName);
 
+  int SignPackage(const std::string& src_dir);
   int CreateDMG(const std::string& src_dir, const std::string& output_file);
 
   std::string InstallPrefix;
-- 
2.1.1

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers

Reply via email to