Skip to content

Commit

Permalink
MacPlatform: use install_name_tool to add /usr/local/lib and /opt/hom…
Browse files Browse the repository at this point in the history
…brew/lib to rpath of lime.ndll

Previously, we added these rpaths to lime.ndll when it was built in commits c70ec9f and 333d093, but it's actually necessary only for Neko, so now I made it happen specfically after calling `nekotools boot` to create the Neko executable.

I've tested cpp and hl, and I've confirmed that the executables still launch successfully when these rpaths are omitted. It's better for their security to use fewer rpaths.

As noted commit c70ec9f, adding these rpaths is necessary due to a change in Xcode 15 where /usr/local/lib used to be available on the rpath automatically, but now it isn't, which affects the executable's ability to find the libneko dylib.
  • Loading branch information
joshtynjala committed Jun 19, 2024
1 parent 4485246 commit 4793649
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 7 deletions.
7 changes: 0 additions & 7 deletions project/Build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -442,13 +442,6 @@
</section>

<section if="mac">
<!--
starting in xcode 15, rpath doesn't automatically include
/usr/local/lib, but we need it for neko
-->
<vflag name="-rpath" value="/usr/local/lib" />
<vflag name="-rpath" value="/opt/homebrew/lib" if="HXCPP_ARM64"/>

<vflag name="-l" value="iconv" />
<vflag name="-framework" value="IOKit" />
<vflag name="-framework" value="Foundation" />
Expand Down
12 changes: 12 additions & 0 deletions tools/platforms/MacPlatform.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package;

import lime.tools.HashlinkHelper;
import hxp.Haxelib;
import hxp.HostArchitecture;
import hxp.HXML;
import hxp.Log;
import hxp.Path;
Expand Down Expand Up @@ -188,6 +189,17 @@ class MacPlatform extends PlatformTarget

NekoHelper.createExecutable(project.templatePaths, "mac" + dirSuffix.toLowerCase(), targetDirectory + "/obj/ApplicationMain.n", executablePath);
NekoHelper.copyLibraries(project.templatePaths, "mac" + dirSuffix.toLowerCase(), executableDirectory);

// starting in xcode 15, rpath doesn't automatically include
// /usr/local/lib, but we need it for libneko dylib
System.runCommand("", "install_name_tool", ["-add_rpath", "/usr/local/lib", Path.join([executableDirectory, "lime.ndll"])]);
if (System.hostArchitecture == HostArchitecture.ARM64)
{
// on Apple Silicon, the user may have installed Neko with
// Homebrew, which has a different path. however, if the
// Homebrew path doesn't exist, that's okay.
System.runCommand("", "install_name_tool", ["-add_rpath", "/opt/homebrew/lib", Path.join([executableDirectory, "lime.ndll"])]);
}
}
else if (targetType == "hl")
{
Expand Down

7 comments on commit 4793649

@tobil4sk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this not break lime tools?

@joshtynjala
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tobil4sk I didn't have any issues running Lime tools after this change (and I definitely had to rebuild Lime tools to try it). As I understand it, Lime tools runs on the system neko executable, which wouldn't work for non-Lime projects either, if it couldn't find libneko. But Lime projects built for Neko use nekotools boot, which is where the rpath issue comes in.

@tobil4sk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I originally ran into this error in #1750, lime tools didn't work at all without the rpath set for lime.ndll. I'm not sure if this has changed, I'm not able to test this currently.

@joshtynjala
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's strange. It kind of sounds like Homebrew isn't building Neko properly.

@tobil4sk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joshtynjala Does the executable itself not load libneko as well? The binary built with nekotools boot should have the same rpath as the neko binary. In that case maybe we shouldn't need the rpath on lime.ndll for neko builds either?

@joshtynjala
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tobil4sk If I run otool -L /usr/local/lib/neko/neko, @rpath/libneko.2.dylib is listed. It's the same for a nekotools boot executable.

If I run otool -lV /usr/local/lib/neko/neko | grep -B 1 -A 2 LC_RPATH, the LC_RPATH value is @executable_path/. Again, same for a nekotools boot executable.

Having used the official Haxe installer for macOS, neko and libneko are in the same directory (in this case, /usr/local/lib/neko), so it seems to be using @executable_path/ there.

I don't have a Homebrew version of Neko installed at this time to test the results of otool -L and otool -l, and I don't particularly feel like going through that effort today.

For a Lime-built Neko executable, we aren't copying libneko to go with nekotools boot, so we have been relying on rpath to find libneko. Before Xcode 15, apparently /usr/local/lib was implicitly on the rpath, and there's a linked libneko in that directory too. Starting with Xcode 15, /usr/local/lib is no longer implicitly on the rpath, for whatever reason Apple decided on. This made our Lime neko builds break. Oddly, the rpath of lime.ndll seems to be affecting the Neko executable. Or maybe nekotools boot is using Xcode somehow. Regardless, we're now adding /usr/local/lib explicitly to the rpath to restore the old behavior before Xcode 15 stopped adding that directory implicitly to the rpath.

I am still considering the possibility of copying libneko into our .app bundle, and it will kill two birds with one stone. 1) We won't need to mess with the rpath. 2) the .app bundle will work without the user having to install Neko.

@tobil4sk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joshtynjala The difference could be that the installer build might have been built with a version of xcode older than 15, but the homebrew builds are probably built using the newer version of xcode.

Please sign in to comment.