-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mac - problem using static libs installed by Homebrew #11237
Comments
It might be a better idea to use Note that the issues with iconv_close vs libiconv_close sound like you have compiled with a different iconv.h header than the library you are linking to. GNU libiconv uses a header macro to redefine the symbol so that code written for |
You are correct it would be better to use dependency() instead of find_library(), but I'm not in charge of the meson.build file I'm dealing with, which contains several calls to find_library(). I was hoping I could just use the '-Dprefer_static=true' option when calling 'meson setup...' to use static libraries but that does not seem to be possible. I will have to try to get changes made to that meson.build file. Using iconv in my example was a red herring, including the path to the homebrew iconv in CFLAGS and LDFLAGS takes care of the link error. Whatever, I think there is a problem with find_library(), it treats static libs and dylibs differently. Using gtk3 as a better example - |
The find_library method is a compiler object method, and like all other compiler methods, it uses the compiler itself to handle this. No pkg-config. I'm not sure why it would find a shared library but not a static one, however.
This error is probably a bit confusing, the error string you encountered is only generated deep inside target generation when you attempt to |
My example had a typo, should be 'gtk-3'. Another weirdness - dependency('gtk-3') fails, it has to be dependency('gtk+-3.0'). Must be because of pkg-config. Which works correctly and I see '/usr/local/Cellar/gtk+3/3.24.34/lib/libgtk-3.dylib' in the linker args. And '-I/usr/local/Cellar/gtk+3/3.24.34/include/gtk-3.0' in the compiler args. But c_compiler.find_library('gtk-3'), which succeeds in the meson config, just puts '-lgtk-3' in the linker args, and adds no '-I/...', so the build fails to find the header files, and the link would fail to find 'libgtk-3.dylib'. c_compiler.find_library('gtk-3', '/usr/local/opt/gtk+3/lib') succeeds in the meson config, and puts '/usr/local/opt/gtk+3/lib/libgtk-3.dylib' in the linker args. And '-Ifreeciv-gtk3.22.p' in the compiler args. But at build time there's nothing in 'freeciv-gtk3.22.p' and the build fails to find the header files. My theory now is that c_compiler.find_library('gtk-3'), without additional search dirs, is actually not finding anything, and should be reporting an error. It only adds '-lgtk-3' to the linker args, which is not enough for the build to succeed. |
Right, because
... which makes sense, because find_library and has_header ask it to find a library / header file on the current set of default -L and -I directories, that's all.
When you don't specify a preference for static/shared, it's possible for Meson to detect that compiling a test file and linking it with But it should definitely be finding something -- check out the file builddir/meson-logs/meson-log.txt (and maybe post it here for analysis), this file contains information about the inner state of build checks.
That include path is irrelevant. It exists for the project's own use, to create generated headers and use them. Not all projects do. |
What I have finally figured out by looking at meson-log.txt is that '/usr/local/lib' is a search path for libraries. Here's what I see -
This is apparently not documented anywhere, including "man clang". The meson manual says "By default the library is searched for in the system library directory (e.g. /usr/lib). Specifying more directories here, causes Meson to search in those directories as well as the system directories.", which is misleading/incorrect. I suggest improving that part of the manual to say what actually happens on the Mac. |
What is misleading/incorrect? Whether clang documents it or not, if clang itself will find libraries there, so will Meson. |
Note also the big note at the top of the page:
This is a pretty big indicator that if variables which the compiler itself respects will change the search paths, then in general, whatever the compiler claims to search is also what Meson will search. |
What's incorrect is where it says "e.g. /usr/lib" when it's actually "/usr/local/lib" on the Mac. Where it's misleading is where it says "the system directories" without saying what those are or how to find out what they are. On my Mac the environment vars are CPPFLAGS and LDFLAGS. When I enter "echo $CPPFLAGS" or "echo $LDFLAGS" on the terminal command line I get nothing. |
"e.g." -- "for example". If it is "actually something else on the Mac" then, well, examples are by definition neither incorrect (they never promised to be correct) nor correct (they will fail to match on other systems). "The system directories" is not misleading. It may fail to be as helpful as it could be, but failing to state what it's talking about doesn't trick one into selecting a wrong choice or believing false information, or... whatever. I would be happy to explain what's going on here in a support ticket, and I would be happy to help improve the documentation for clarity, but I don't really think that it's fair to say the current documentation is telling falsehoods.
Those are optional user-defined variables which don't have to exist, but if they do then Makefiles, autotools, cmake, meson, and most other build systems read them. (But compilers do not.) |
Anyway, it seems the original problem was being unable to find libraries without specifying |
Sorry to be so annoying, I do appreciate your helpful answers. The short answer to your last question is - yes, sorta. Have now learned that "man ld" gives the info missing from "man clang" - it says
I saw -print-search-dirs in a meson-log.txt, and "man clang" says
But when I try that it does not print /usr/lib nor /usr/local/lib - maybe I should file a bug report with Apple about that? Anyway - my gtk-3 example is also bad because it turns out homebrew does not supply a static lib for gtk-3. So, trying again with this meson.build file -
I see this in the meson-log.txt
cc -Wl,-v just tells the linker to print version, but it actually prints that list of "Library search paths:", which, again, is not correct - it's missing /usr/lib. Maybe I should file a bug report with Apple about that? So now I'm thinking meson is doing the best it can given the limitations of Apple's stuff. I now know the linker could find "/usr/local/lib/libSDL2.a" with no -L path help, but how could meson's 'c_compiler.find_library('sdl2', static: true)' know that, unless it runs 'cc -Wl,-v' and stashes the results so it can search those paths. And even then it would miss '/usr/lib'. I think you're right that the manual is not misleading, just not as helpful as it could be. What would be nice is to add an enhancement to the compiler methods - compiler.print_search_dirs(). But implementing it correctly on the Mac would require knowing what 'man ld' says and not just relying on calls to cc. If that were done, that could also be used internally by meson so 'c_compiler.find_library('sdl2', static: true)' would work. Another suggestion - add something in the manual compiler.find_library() static section to say
|
Trying to use the find_library('..., static: true) option and/or the "-Dprefer_static=true" options.
This line -
iconv_lib_dep = c_compiler.find_library('iconv', dirs: cross_lib_path, static: true)
gives "ERROR: C static library 'libiconv' not found", even though libiconv.a is sitting next to libiconv.dylib in the same folder, and it finds libiconv.dylib just fine without the "static: true". Another thing I tried got me this msg - "ERROR: '/usr/local/opt/libiconv/lib/libiconv.a' is not a static library." Are Homebrew installed .a files not static libraries? They look like it to me.
This line -
iconv_lib_dep = c_compiler.find_library('/usr/local/opt/libiconv/lib/libiconv', static: true)
gives no error, but then building gets Undefined symbols link errors for, e.g. "_iconv_close". Using hex editor, I see neither libiconv.dylib nor libiconv.a contain string "_iconv_close", but both contain "_libiconv_close".
MacOS 11.7.2
meson 0.64.1
Python 2.7.16
ninja 1.11.1
The text was updated successfully, but these errors were encountered: