-
-
Notifications
You must be signed in to change notification settings - Fork 546
Add visibility symbols #134
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
Conversation
|
|
||
| if get_option('default_library') != 'static' | ||
| extra_args += '-DINI_SHARED_LIB' | ||
| endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only necessary on Windows, and I think only with MSVC?, and in that case you need a bit more complicated of a check:
- if default_library is shared, pass that arg
- if default_library is both, error out with the following message:
error('default_library=both is not supported with MSVC') - if default_library is static, skip
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem here is that with default_library=both you build both static and shared, but there is no option to define different defines for each. And my understanding is MSVC is so... interestingly designed... that it downright breaks your library if you add a sharedlib declspec when building statically. This is not a problem with GCC or clang.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only necessary on Windows, and I think only with MSVC?
This is necessary on Windows, but it's nice to have on other platforms too, as it makes .so files cleaner and lighter.
Also, I'm not sure that erroring out is necessary, as you can actually build both libraries without issues even on Windows.
I check for != 'static' instead of == 'shared' because while you can compile the static library when -DINI_SHARED_LIB is defined, you can't compile the shared one when the macro is absent.
Edit: and also because you can't consume the shared library when INI_SHARED_LIB is not defined
Edit2: so, as a BothLibraries object in Meson behaves like a SharedLibrary when used, defining INI_SHARED_LIB when the lib type is both or shared seems reasonable to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is necessary on Windows, but it's nice to have on other platforms too, as it makes .so files cleaner and lighter.
No, I mean the -D define is unnecessary on other platforms, because on __GNUC__ (gcc/clang) you just unconditionally --without checking for INI_SHARED_LIB -- define an __attribute__ ((visibility ("default"))).
And thus, even without the define, your .so files are always cleaner and lighter. Because sane compiler.
Edit2: so, as a
BothLibrariesobject in Meson behaves like aSharedLibrarywhen used, definingINI_SHARED_LIBwhen the lib type isbothorsharedseems reasonable to me.
The issue is that it will also install a StaticLibrary, and then attempting to use that from other build systems which are configured to search for and prefer static libraries, may produce broken results.
(I am no expert on Windows or MSVC. But I've been told that it "does" produce broken results -- you end up building both a dll and a static library, and the dll works, and the static library doesn't.)
Given that the default is shared, and defining both is something you'd need to opt into, the default behavior is fine anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I mean the -D define is unnecessary on other platforms, because on
__GNUC__(gcc/clang) you just unconditionally --without checking forINI_SHARED_LIB-- define an__attribute__ ((visibility ("default"))).
Oh, you're right, I copied the various #ifs from another project of mine and didn't noticed that this was the case 😅️
The issue is that it will also install a
StaticLibrary, and then attempting to use that from other build systems which are configured to search for and prefer static libraries, may produce broken results.
Yep, calling error() on Windows might be the only solution.
(I am no expert on Windows or MSVC. But I've been told that it "does" produce broken results -- you end up building both a dll and a static library, and the dll works, and the static library doesn't.)
Awesome.
meson.build
Outdated
| ['ini.c'], | ||
| include_directories : inc_inih, | ||
| c_args : arg_static, | ||
| c_args : [arg_static, extra_args, '-DINI_SHARED_LIB_BUILDING'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This option is not needed except on Windows / MSVC, anyway you can "probably" use add_project_arguments() for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way I noticed that you can pass [arg_static, extra_args] to library.c_args but not declare_dependency.compile_args (it works with arg_static + extra_args though) - "List item must be one of <class 'str'>, not <class 'list'>"
Not sure if this is a Meson bug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some places do implicit flattening at time of use, some do not. Personally I find implicit flattening makes me nervous.
| pkg.generate(lib_inih, | ||
| name : 'inih', | ||
| description : 'simple .INI file parser', | ||
| extra_cflags : extra_args, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By only adding that value on MSVC, not on Linux, you can reduce unneeded arguments included in pkg-config files on Linux.
|
Thanks for the submission. Hmm, I don't mind messy build files, but I'm not a fan of polluting the Interested in others' thoughts too. |
|
The thing is that some of this "mess" is needed anyway. You want to unconditionally define it to It's a one-line define on GCC/clang, plus adding the macro in front of each public symbol. The problem is of course the MSVC compiler, which has... "interesting" design and requires a complex maze of conditions to determine whether or not to pass MSVC's competing attribute, declspec. And also, which value to use for the MSVC attribute. MSVC also has the concept of .def files, which can be passed in meson using Of course, you want to use GCC symbol visibility regardless of what you do with MSVC. (Technically, GCC can do like the .def file too. GCC calls it an ld version script, and it uses a totally different format, but again, it's a list of public symbols marked as global, and a wildcard on all remaining local symbols. Use of an ld version script does NOT enable GCC to perform compiler optimizations on symbols that aren't public, because it doesn't know until link time that they aren't public. At link time, the private symbols still exist, they just get hidden.) |
I know, it sucks, but the other options are even worse in my opinion (as Eli says, you'd have to maintain some files that would need to be (manually?) updated every time you modify your symbols). I don't know exactly how painful they are to adopt because I've never bothered to look into the alternatives, but having that set of |
They are required to properly build DLLs on Windows, and improve the quality of shared objects on Linux. See https://gcc.gnu.org/wiki/Visibility for details. This issue was first discovered here: mesonbuild/wrapdb#340 (comment)
|
Okay, thanks. I'll go ahead and merge this, given that it seems there aren't good workarounds. @stephanlachnit Could I please get your thumbs-up first? |
|
Looks fine to me. In theorey we could also disable shared libraries on Windows and set the default to static there, as it seems quite unlikely to me that anyone would actually use that. PS: oh and it would be nice if you could tag r54 if merged. |
|
Thanks for the contribution, @Tachi107! |
|
@stephanlachnit r54 tagged and released: https://github.com/benhoyt/inih/releases/tag/r54 |
|
Thanks, inih is now updated on the WrapDB with passing CI for Windows/macOS/Linux. :) |
|
Thanks for merging! |
They are required to properly build DLLs on Windows, and improve the quality of shared objects on Linux. See https://gcc.gnu.org/wiki/Visibility for details.
This issue was first discovered here: mesonbuild/wrapdb#340 (comment)
CC @stephanlachnit and @eli-schwartz