llvm-mingw icon indicating copy to clipboard operation
llvm-mingw copied to clipboard

i686, aarch64, and armv7 Toolchains Can't Read "LIBRARY_PATH" Environment Variable

Open falhumai96 opened this issue 5 years ago • 9 comments

Tested on LLVM/Clang toolchains v9 and v10 in Ubuntu 18.04 x86_64 and Windows 10 x86_64 while compiling a library that depends on zlib (other libraries don't seem to work either, so it is not specific to the library I am building). While x86_64 (CC=x86_64-w64-mingw32-cc and CXX=x86_64-w64-mingw32-c++) does read the LIBRARY_PATH environment variable, I can't see to do so with i686 (CC=i686-w64-mingw32-cc and CXX=i686-w64-mingw32-c++), armv7 (CC=armv7-w64-mingw32-cc and CXX=armv7-w64-mingw32-c++), and aarch64 (CC=aarch64-w64-mingw32-cc and CXX=aarch64-w64-mingw32-c++) toolchains.

Running $CC/%CC% -v (or $CXX/%CXX% -v) doesn't show my library paths have been added to the search path while testing in either of aarch64, armv7, or i686, while the search paths get updated with x86_64 target.

falhumai96 avatar May 02 '20 00:05 falhumai96

Can you give a proper way of reproducing exactly what you are trying to do and what you expect to see as result?

mstorsjo avatar May 02 '20 20:05 mstorsjo

Try creating an example shared library, set the LIBRARY_PATH variable to point to the location where the import library is made (in my example it was libzlib.dll.a), and then try to build an application that links to the library (again, in my example, it was -lzlib). The expectation is that the clang driver would read the LIBRARY_PATH paths, and append -L arguments with the read paths to the final command. The x86_64 driver was able to read this environment variable, but not the other targets (e.g. i686). I have not seen this issue with the gcc retrieved from MSYS2 while building for both x86_64 or i686 targets, but I have seen it in LLVM MinGW, which can be either a bug in the wrappers of LLVM MinGW or a bug in the LLVM project.

falhumai96 avatar May 02 '20 21:05 falhumai96

So an x86_64 build of llvm-mingw, invoking i686-w64-mingw32-clang (or -gcc)?

mstorsjo avatar May 02 '20 21:05 mstorsjo

Yes, or just -cc (or -c++ for C++).

falhumai96 avatar May 02 '20 21:05 falhumai96

It looks like this is intentional behaviour: https://github.com/llvm/llvm-project/commit/5828d7b93606087875c61ed2fdb816e03c2a18ce

mstorsjo avatar May 03 '20 17:05 mstorsjo

But, in that case even x86_64 target shouldn't work either in Linux cross-compiling to Windows🤷‍♂️? Also, when running your toolchain on Windows natively, at least both x86_64 and i686 should work just fine (the latter didn't work) since they are both native to Windows (I haven't seen this problem in toolchains obtained from MSYS2, for example).

I honestly don't understand why would LLVM disable such an essential feature for cross compiling (GCC didn't do that for cross-compilation as far as I am concerned). This should be an essential feature to add libraries built and installed not globally for the sake of usage within cross-compilation projects (same as PYTHONPATH environment variable in Python for non-default libraries), especially that you are not going to install these libraries on the default install location for that OS as they are intended for cross-compilation.

falhumai96 avatar May 03 '20 18:05 falhumai96

In the meantime in the project I am building, I have made a Python wrapper that would read and parse the LIBRARY_PATH and CPATH environment variables, and add the appropriate -L and -I, respectively, and call that Python script in another shell/batch script (depending on the OS I am running) and set it as the CC/CXX variable instead. The Python script would then call the actual Clang driver from this toolchain.

falhumai96 avatar May 03 '20 18:05 falhumai96

If you have a look at the commit I linked to you, apparently it just checks whether the target architecture is different, so it doesn't think x86_64 linux -> x86_64 windows is cross compiling. That's clearly a bug though so you shouldn't count on it.

Clang probably disables it when cross compiling, because if you have a (seemingly) globally set LIBRARY_PATH set, it thinks that this contains libraries used for native building, and won't look into it for anything else. I don't think they'll consider this a bug.

FWIW, I had never even heard of the feature LIBRARY_PATH before this issue.

And I guess GCC always looks in it, regardless of whether it's cross compiling or not. The big philosophical difference here is that every build of GCC only targets one environment, while every instance of Clang always supports multiple targets, so Clang has more logic for handling both native and cross compilation roles at the same time.

mstorsjo avatar May 03 '20 18:05 mstorsjo

Oh, I see. Now I get the intention behind the disabling of LIBRARY_PATH environment variable. I guess I have to file a bug ticket to LLVM then 😀🤷‍♂️.

falhumai96 avatar May 03 '20 19:05 falhumai96