osxbundlerun - corerun for use in OS-X app packages
authorBrad Robinson <contact@toptensoftware.com>
Sat, 9 May 2015 03:50:16 +0000 (13:50 +1000)
committerBrad Robinson <contact@toptensoftware.com>
Sat, 9 May 2015 03:50:16 +0000 (13:50 +1000)
CMakeLists.txt
src/coreclr/hosts/osxbundlerun/.gitmirrorall [new file with mode: 0644]
src/coreclr/hosts/osxbundlerun/CMakeLists.txt [new file with mode: 0644]
src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp [new file with mode: 0644]

index ac78eb1..70c5f82 100644 (file)
@@ -161,6 +161,11 @@ if(CLR_CMAKE_PLATFORM_UNIX)
     add_subdirectory(src/coreclr/hosts/unixcoreconsole)
 endif(CLR_CMAKE_PLATFORM_UNIX)
 
+if(CLR_CMAKE_PLATFORM_DARWIN)
+    add_subdirectory(src/coreclr/hosts/osxbundlerun)
+endif(CLR_CMAKE_PLATFORM_DARWIN)
+
+
 # Add this subdir. We install the headers for the jit.
 
 add_subdirectory(src/pal/prebuilt/inc)
diff --git a/src/coreclr/hosts/osxbundlerun/.gitmirrorall b/src/coreclr/hosts/osxbundlerun/.gitmirrorall
new file mode 100644 (file)
index 0000000..9ee5c57
--- /dev/null
@@ -0,0 +1 @@
+This folder will be mirrored by the Git-TFS Mirror recursively.
\ No newline at end of file
diff --git a/src/coreclr/hosts/osxbundlerun/CMakeLists.txt b/src/coreclr/hosts/osxbundlerun/CMakeLists.txt
new file mode 100644 (file)
index 0000000..31ed570
--- /dev/null
@@ -0,0 +1,22 @@
+project(osxbundlerun)
+
+include_directories(../unixcoreruncommon)
+
+set(CORERUN_SOURCES 
+    ../unixcoreruncommon/coreruncommon.cpp
+    osxbundlerun.cpp 
+)
+
+add_executable(osxbundlerun
+    ${CORERUN_SOURCES}
+)
+
+target_link_libraries(osxbundlerun 
+    dl
+)
+
+add_dependencies(osxbundlerun
+    coreclr
+)
+
+install (TARGETS osxbundlerun DESTINATION .)
diff --git a/src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp b/src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp
new file mode 100644 (file)
index 0000000..7706cca
--- /dev/null
@@ -0,0 +1,91 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
+//
+
+// CoreCLR boot loader for OSX app packages.
+//
+// Assumes the following app package structure
+//
+//   /Contents/MacOS/yourAppName    (osxbundlerun renamed to your app name)
+//   /Contents/CoreClrBundle/       The CoreCLR runtime, or a symlink to it if external
+//   /Contents/ManagedBundle/       Your managed assemblies, including yourAppName.exe
+//
+// Of course you can also include whatever else you might need in the app package
+// 
+// Symlinking the CoreClrBundle is handy for dev/debug builds. eg:
+//
+//   Contents> ln -s ~/dotnet/runtime/ CoreClrBundle
+//
+// All command line arguments are passed directly to the managed assembly's Main(args)
+// Note that args[0] will be /Contents/MacOS/yourAppName, not /Contents/ManagedBundle/yourAppName.exe
+
+
+#include <coreruncommon.h>
+#include <string>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+int corerun(const int argc, const char* argv[])
+{
+    // Make sure we have a full path for argv[0].
+    std::string argv0AbsolutePath;
+    if (!GetAbsolutePath(argv[0], argv0AbsolutePath))
+    {
+        perror("Could not get full path to current executable");
+        return -1;
+    }
+
+    // Get name of self and containing folder (typically the MacOS folder)
+    int lastSlashPos = argv0AbsolutePath.rfind('/');
+    std::string appName = argv0AbsolutePath.substr(lastSlashPos+1);
+    std::string appFolder = argv0AbsolutePath.substr(0, lastSlashPos);
+
+    // Strip off "MacOS" to get to the "Contents" folder
+    std::string contentsFolder;
+    if (!GetDirectory(appFolder.c_str(), contentsFolder))
+    {
+        perror("Could not get Contents folder");
+        return -1;
+    }
+
+    // Append standard locations
+    std::string clrFilesAbsolutePath = contentsFolder + "/CoreClrBundle";
+    std::string managedFolderAbsolutePath = contentsFolder + "/ManagedBundle/";
+    std::string managedAssemblyAbsolutePath = managedFolderAbsolutePath + appName + ".exe";
+
+    // Pass all command line arguments to managed executable
+    const char** managedAssemblyArgv = argv;
+    int managedAssemblyArgc = argc;
+
+    // Check if the specified managed assembly file exists
+    struct stat sb;
+    if (stat(managedAssemblyAbsolutePath.c_str(), &sb) == -1)
+    {
+        perror(managedAssemblyAbsolutePath.c_str());
+        return -1;
+    }
+
+    // Verify that the managed assembly path points to a file
+    if (!S_ISREG(sb.st_mode))
+    {
+        fprintf(stderr, "The specified managed assembly is not a file\n");
+        return -1;
+    }
+
+    // And go...
+    int exitCode = ExecuteManagedAssembly(
+                            argv0AbsolutePath.c_str(),
+                            clrFilesAbsolutePath.c_str(),
+                            managedAssemblyAbsolutePath.c_str(),
+                            managedAssemblyArgc,
+                            managedAssemblyArgv);
+
+    return exitCode;
+}
+
+int main(const int argc, const char* argv[])
+{
+    return corerun(argc, argv);
+}