summaryrefslogtreecommitdiff
path: root/src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp')
-rw-r--r--src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp b/src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp
new file mode 100644
index 0000000000..d4de5c764e
--- /dev/null
+++ b/src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp
@@ -0,0 +1,90 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more 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);
+}