Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
530 views
in Technique[技术] by (71.8m points)

c - Can Mac OS X El Capitan run software compiled for Yosemite that expects libraries in /usr/gnu64/lib?

Sorry, there's a bit of background necessary — you could try skipping to the Question heading.

Since time immemorial (somewhere in the previous millennium, anyway), I've created directories such as /usr/gnu and /usr/gcc to hold custom-compiled GNU software, separate from anything in the system directories. This has worked well for me, on a wide variety of Unix-based systems, including Mac OS X since 2002 (Jaguar, 10.2). (One reason for not using /usr/local was that the IT management maintained it, and it always contained archaic code — it had Perl 4 available until about 5 years ago, for example. Using other names avoided run-ins with them.)

With Mac OS X 10.11 El Capitan, Apple has introduced the SIP (System Integrity Protection) system (described at What is the "rootless" feature of El Capitan, really? on 'Ask Different'). It means that I can no longer create directories such as /usr/gnu or /usr/gcc, even though they're disjoint from anything that Apple has.

I found that the software previously in those directories had been quarantined in directories like these (where the UUIDs will be different on your machine, and I probably have two because getting El Capitan onto this machine was a multi-step operation — a separate long and boring story):

$ ls -1 /Library/SystemMigration/History/
Migration-7D74B534-AA54-4A4A-8DCC-A5C2F28E1A39
Migration-9C0FE7A4-3445-4BD6-A512-35464EECCBC3
$

and then in sub-directories under QuarantineRoot:

$ ls /Library/SystemMigration/History/Migration-9C0FE7A4-3445-4BD6-A512-35464EECCBC3/QuarantineRoot/usr:
gcc      gnu32    gnu64
$

However, the binaries were compiled with GCC and various libraries, so they don't run at the moment. For example:

$ otool -L bison
bison:
    /usr/gnu64/lib/libintl.8.dylib (compatibility version 10.0.0, current version 10.1.0)
    /usr/gnu64/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 744.18.0)
    /usr/gcc/v4.7.1/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
$ ./bison
dyld: Library not loaded: /usr/gnu64/lib/libintl.8.dylib
  Referenced from: /Library/SystemMigration/History/Migration-9C0FE7A4-3445-4BD6-A512-35464EECCBC3/QuarantineRoot/usr/gnu64/bin/./bison
  Reason: image not found
Trace/BPT trap: 5
$

AFAIK, I can't even create symlinks in /usr such that gcc or gnu64 points somewhere else (not even running with root privileges). That's one of the techniques I've used to create software on MachineA with spare space in /work1 for use on another MachineB with spare space in /work5; a symlink in /usr allows the code to sit in /work1/gcc or /work5/gcc and it works correctly as long as /usr/gcc points to where the files are actually installed. So, this SIP system seems to kill all the mechanisms used successfully for a couple of decades which are predicated on being able to create at least some sort of directory entry in /usr.

Question

  • Is there a sensible way to get the old binaries to run without disabling SIP and without having to recompile everything immediately?

The fall-back position is "recompile the software — avoiding /usr as an install location". Over time, I plan to use /opt/gcc and /opt/gnu64 instead of the equivalents under /usr. I'm even contemplating using space under my home directory, even though I'd rather not; it is 'system' software.

However, I have quite a lot of software already compiled, including multiple versions of GCC (from 4.4.2 through 5.2.0), which it will be a nuisance to recompile. In fact, I'll have to abandon the old versions of GCC, which I don't use all that often, but which are useful when I do need them.


Oh, and I've got a problem with the configure script for GNU Tar (1.28 and 1.26). It tests how deep a directory tree it can create, and then is unable to clean-up. And neither rm nor rmdir can clean up either, even if I cd down the hierarchy to the bottom. It gets an 'out of disk space' error, even though there's lots of space left. I can use Finder to move the hierarchy to Trash. But Finder can't remove them either. Bash has a tizzy because it can't work out what the current directory is. It is all kinda painful! So recompiling and reinstalling some of the software is not going to be trivial. I may even end up using stuff compiled by other people (MacPorts, HomeBrew, etc), but I like to be able to compile my own. I get the error 'The operation can’t be completed because the item “confdir-14B---” is in use'; a reboot may be in order, but I'm not confident it will fix that problem.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Just for the sake of closure:

  • No; there doesn't seem to be a way to avoid recompiling code.

If you want to follow the chat link, by all means do so, but it ends up at the same conclusion.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...