SpockFan02 wrote: ↑2019-10-13, 07:38
Built Pale Moon from
your repo without problems and it works fine on Mac.
Thank you, SpockFan02! I appreciate you testing that for me.
Anyway, the last wrinkle that I've been trying to solve is finding a way to avoid relying on LD_LIBRARY_PATH in some script in the final package, which I know is generally a bad practice. So far to get ./mach run to actually run, I've had to type something along the lines of:
Code: Select all
export LD_LIBRARY_PATH="/usr/gcc/7/lib/amd64:/export/home/athenian/UXP/obj-release/dist/bin"
So the first thing I figured out was how to insert $ORIGIN into the runpath. It turns out it's insanely hard to do, and that I also didn't need to do it because at some point the runtime linker started searching there automatically without needing that compiled into the path. But if you ever need to do it for some reason, you have to do it like this:
You have to put the whole thing in quotes, use two $ symbols to avoid having it picked up by gmake as a script variable, and use backslash to escape each $ symbol so the shell doesn't interpret it as a shell variable when it hits the command line. That's what you have to do to get $ORIGIN compiled into the runpath, otherwise it will be mangled beyond recognition and yield something totally wrong.
But it turns out that I needn't have worried, everyone else was having the same problem and in later versions of Solaris they pretty much just made the runtime linker search $ORIGIN by default so people don't have to deal with this. They had a lot of fun with this a while back, though...
https://bugzilla.mozilla.org/show_bug.cgi?id=259945
It turns out though, that you need LD_LIBRARY_PATH to make ./mach run work, but not in a packaged version. The reason is because of how symlink resolution is handled. The $ORIGIN flag uses the actual location of all the libraries, not the location of the symlink, therefore all the symlinks in dist/bin won't work unless you assert an LD_LIBRARY_PATH. However, this won't matter in the packaged version because you'll have the actual .so files there instead of symlinks. So that has to be kept in mind.
The other wrinkle that's interesting is that it turns out /usr/gcc/7/lib/amd64 is correctly inserted into the runpath of every shared library already, and I shouldn't need to add that to my runpath at all. The reason I've been needing to add it is because of the runpath of libxul.so having a silly problem. By typing:
Code: Select all
elfedit -r -e 'dyn:value runpath' libxul.so
You can see that /usr/lib/amd64 is ahead of /usr/gcc/7/lib/amd64 in the runpath. Why is that a problem? Well, the output of ldd reveals why. It looks like this at a key point:
Code: Select all
libstdc++.so.6 => /usr/lib/amd64/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.21) => (version not found)
So it's picking up the wrong libstdc++.so.6 from /usr/lib/amd64, and that's why LD_LIBRARY_PATH being set to /usr/gcc/7/lib/amd64 fixes it. However, libxul.so is the only shared object that appears to have this problem with its runpath, all the others seem fine. Aside from LD_LIBRARY_PATH, I could also use a feature in crle, which is the Solaris equivalent of ldconfig. It works like this:
Code: Select all
crle -64 -a /usr/lib/amd64/libstdc++.so.6 -o /usr/gcc/7/lib/amd64
It basically tells the linker to look in /usr/gcc/7/lib for an alternative object anytime something asks for /usr/lib/amd64/libstdc++.so.6, which has the advantage of not altering the search path for any other file. But it's still a system-wide setting and really not a lot better than using LD_LIBRARY_PATH, though at least it's more targeted. In theory, you could actually compile the application to use a custom ld.config that you bundle with the application by using the -c option to the Solaris linker, but in practice it would be really hard to figure out a reliable path for that config file to compile into the binaries (probably it would end up having to be placed in somewhere like $HOME/.moonchild productions), and make sure the flag wasn't used along with several incompatible flags in the makefiles at various points. This setup would probably still require a first-time run script just like an LD_LIBRARY_PATH script would though, but with the advantage that it would only have to be run once and from then on you could just run the palemoon executable directly.
But by far the best solution I've been able to come up with, is this one.
Code: Select all
elfedit -e 'dyn:runpath /usr/gcc/7/lib/amd64:/usr/lib/amd64' libxul.so
https://blogs.oracle.com/solaris/changi ... ncluded-v2
From this article, I found out that Solaris actually went ahead and allocated extra space in the dynamic string tables of their ELF files so that people could edit the runpaths of them without recompiling, so this is actually fairly safe and effective. What this does is put /usr/gcc/7/lib/amd64 ahead of /usr/lib/amd64 in the search path, so that libxul.so no longer picks up the wrong version of libstdc++.so.6, and therefore after extracting the the package created with ./mach package to your home directory...
You will finally be able to just run ./palemoon and have everything work without any initial setup script, just like it does on other operating systems. Sure, this isn't quite as good as actually finding a way to compile libxul.so so it doesn't have the wrong search path in the first place (which I should really do), but the elfedit technique makes the issue only a concern for the person packaging a program for Solaris. It makes the search path issue in the code end up being more or less invisible to the end user and doesn't require them to use any scripts on their end as a workaround.
"The Athenians, however, represent the unity of these opposites; in them, mind or spirit has emerged from the Theban subjectivity without losing itself in the Spartan objectivity of ethical life. With the Athenians, the rights of the State and of the individual found as perfect a union as was possible at all at the level of the Greek spirit." -- Hegel's philosophy of Mind