Is there a method for a process (without root) to hide or mount over a path of the filesystem for itself? It shouldn't affect the actual filesystem, only the process itself and perhaps its children?

Bit of an odd use case, but I need to build something on an OSX build server as if it were a vanilla OSX machine. However unfortunately there are a few libs installed in /usr/local/{include,lib} which mess up the build and I don't have root on the machine. So I would like to temporary hide /usr/local while running configure and make.

I do not have write access to /usr/local so I cannot actually modify it.

  • AFAIK, it's not possible to do this. It would be easier to tell configure to look in the correct places. – Kusalananda Aug 9 '16 at 8:56
  • The problem is mostly preventing make from linking to libs in /usr/local/lib. – Jeroen Aug 9 '16 at 8:56

No, there's no direct way to do this. You can use chflags hidden to hide things from the Finder, but that doesn't affect the command-line.

The solution would depend on the configure script. It may simply look along PATH to notice the /usr/local, but more likely it will have a hardcoded list of directories to look at — including /usr/local. To work around the former (PATH-based), you could adjust your path. For the latter, the only thing that works is to modify the configure script.

The reason why you'll see hardcoded lists is that add-ons may not use the same search paths as the rest of the system. For instance, the various BSD ports may use /usr/pkg, /usr/local, etc., and partly rely upon the packagers to set these pathnames in their build-scripts. But programs that are not built as part of the ports system have to look for things in those places, to build with little user attention.

If you want to override the default search path for OSX, start with the ld manual page, which says

Search paths
ld maintains a list of directories to search for a library or framework to use. The default library search path is /usr/lib then /usr/local/lib. The -L option will add a new library search path. The default framework search path is /Library/Frameworks then /System/Library/Frameworks. (Note: previously, /Network/Library/Frameworks was at the end of the default path. If you need that functionality, you need to explicitly add -F/Network/Library/Frameworks). The -F option will add a new framework search path. The -Z option will remove the standard search paths. The -syslibroot option will prepend a prefix to all search paths.

and you can pass options to ld by prefixing them with -Wl (and using a comma where a space is needed). For your purpose, you would write a script which

  • uses -Z to remove the search paths, and
  • add back the parts you need using -L

The clang option -v shows the details of the compiler front-end, and passing -v to ld, e.g., using -Wl,-v shows the linker's details.

Something like this, for example:

clang -Wl,-Z -L/usr/lib -F/Library/Frameworks -F/System/Library/Frameworks "$@"

It is not documented in the clang manual, but a quick check shows that it would pass a plain -Z option to the linker. On the other hand, clang does document options (mainly for gcc-compatibility) which suppress its searches of different categories of include-directories:

          Do not  search  the  standard  system  directories  or  compiler
          builtin directories for include files.

          Do not search the standard system directories for include files,
          but do search compiler builtin include directories.

          Do not search clang's builtin directory for include files.

It does not have an option for showing the search-path for include files, but you can infer that by running the preprocessor.

Once you've gotten the script working, then running the configure script, you would set CC to that script's name, e.g.,

./configure CC=cc-system

I've been doing this a while, but haven't needed this particular combination (see Compiler wrappers).

  • Maybe LDFLAGS="-Z -L/usr/lib -F/Library/Frameworks -F/System/Library/Frameworks" will work... – Jeroen Aug 9 '16 at 21:45
  • What would be the equivalent of -Z to make clang remove -I/usr/local/include ? – Jeroen Aug 10 '16 at 9:35

Assuming that the processes are cooperating (i.e. they don't deliberately try to work around the hiding) and that they're dynamically linked executable, you can use DYLD_PRELOAD (that's the OSX name, most other Unix variants call it LD_PRELOAD) to load a library that wraps around file lookup functions and fakes some results.

Here is a code example that does approximately what you want. Depending on how the programs you run access the files you don't want them to see, you may have to override other functions, possibly open or access.

  • The only libraries I have in /usr/local/lib are static. – Thomas Dickey Aug 9 '16 at 23:08
  • @ThomasDickey I don't see how that's relevant. – Gilles Aug 9 '16 at 23:10
  • Your suggestion wouldn't work on my OSX machine. – Thomas Dickey Aug 9 '16 at 23:12
  • @ThomasDickey I don't see why not. The point is to prevent the build system from seeing the libraries in /usr/local/lib. It doesn't matter what type of files these are. – Gilles Aug 9 '16 at 23:18

So you don't want to actually hide certain directories, you just want to make sure your configure script doesn't find certain files in that directory.

The easiest way to accomplish that is probably to open configure.ac in an editor and edit it so that it doesn't search for include files or libraries in /usr/local, and then regenerate the configure script. Alternatively, you could also edit configure directly, since it's just a shell script after all. However, that will be somewhat more complicated, since the script is generated.

  • The configure step actually succeeds, the problem is when make invokes the linker. clang always seems to prefer whatever is in /usr/local/lib even if you give it another -L/some/path. – Jeroen Aug 9 '16 at 10:28
  • @Jeroen Yes, I got that. But the configure script configures the build, and it is then based upon that configuration that make decides what to do. So if you tell configure not to look at certain directories, then make should ignore them. Of course, it all depends on what software you're actually trying to build... – Wouter Verhelst Aug 9 '16 at 12:05

Depending on what library the build is picking up and how the configure script is set up, you might be able to disable its use by telling configure not to use that "external package" that provided the library, or to look for it at another path.

The way to do that with configure is usually to say either

$ ./configure --without-PACKAGE

to disable the use of the package, or,

$ ./configure --with-PACKAGE=PATH

to point to another path where it's installed, where PACKAGE is the "external package" that provides the library, and PATH is the prefix path where the package was installed.

Another solution would be to set up a virtual machine with the same configuration as the target machine and build there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.