Strange problem with C preprocessor include file searching (Mac, llvm 10)

I have some more clues here. I can reproduce this strange behavior with just bash, no python needed.

$ oslc -IincA -IincB blah.osl
adding 'incA' <-- my debug, shows that the '-IincA' was parsed on the command line
adding 'incB' <-- my debug, shows that the '-IincB' was parsed on the command line
#include "..." search starts here:
#include <...> search starts here:
incA <-- LLVM diagnostics, shows I passed incA in includedirs list
incB <-- LLVM diagnostics, shows I passed incB in includedirs list
End of search list.
Compiled blah.osl -> blah.oso

Works fine. Now what if I pass the same commands to 'bash -c':

$ /bin/bash -c "oslc -IincA -IincB blah.osl"
adding 'incA'
adding 'incB'
#include "..." search starts here:
#include <...> search starts here:
incA
incB
End of search list.
error: blah.osl:3:10: fatal error: cannot open file 'incA/b.h': No such file or directory
#include "b.h"
         ^
FAILED blah.osl

But this ONLY fails if I'm using llvm 10. If I rebuild my app with llvm@9 from homebrew instead of llvm (which is llvm 10):

$ /bin/bash -c "oslc -IincA -IincB blah.osl"
adding 'incA'
adding 'incB'
#include "..." search starts here:
#include <...> search starts here:
incA
incB
End of search list.
Compiled blah.osl -> blah.oso

Works fine again. I don't have a working theory for what's going on here.

So I know the -I commands are making it to my program, and I know I'm passing those paths to libclang, because its own diagnostics list those directories. But it nonetheless fails to find headers that aren't in the very first included searchpath -- ONLY for llvm 10, ONLY on Mac, ONLY if I'm doing it through a second spawned shell (works fine when I directly type the command).

Any guesses?

So I was able to also reproduce simply as this:

works: oslc -IincA -IincB blah.osl
broken: DYLD_LIBRARY_PATH= oslc -IincA -IincB blah.osl

The only thing in my DYLD_LIBRARY_PATH was /usr/local/opt/llvm

It seems that what was happening was that in cases where I didn’t have /usr/local/opt/llvm/lib in my DYLD_LIBRARY_PATH (as was the case when I ran my compiler from a subshell), it was ending up linking TWO copies of libc++.1.so, one that was build with LLVM, and one system version in /usr/lib, and somehow that led to this weird behavior.

There is apparently some known linkage problems related to this, with the homebrew build of llvm when on Mojave. From what I understand, Catalina’s support for a newer xcode apparently also fixes, but neither specific xcode version nor having DYLD_LIBRARY_PATH set a particular way is an assumption I can make with respect to my users.

I also noticed that this isn’t a problem when I statically link llvm and clang libraries to my app, so my solution for now is to just force my app’s build system to use the static llvm+clang libs rather than dynamic when on OSX and the llvm version is >= 10.

– lg