On 2/2/21 5:06 PM, Alexander Grund via Boost wrote:
This means that BOOST_PROGRAM_OPTIONS_DECL is incorrectly defined.
<snip>
So, the bottom line, BOOST_PROGRAM_OPTIONS_DECL must be defined to:
- BOOST_SYMBOL_EXPORT - on Windows, when the library is being built; - BOOST_SYMBOL_IMPORT - on Windows, when the library is being consumed by user; - BOOST_SYMBOL_VISIBLE - in any other case.
Then you can use BOOST_PROGRAM_OPTIONS_DECL to mark methods and classes that you want to be exported/imported from the library. If a particular type does not need to be exported/imported, but whose RTTI must still be accessible across library boundaries, mark that type with BOOST_SYMBOL_VISIBLE, not BOOST_PROGRAM_OPTIONS_DECL. You can still use BOOST_PROGRAM_OPTIONS_DECL to export/import select methods of that type, if needed.
PS: I remember someone saying that on recent Windows dllexport/dllimport attributes are no longer necessary. I don't quite know how that works, but for backward compatibility we should probably keep using BOOST_SYMBOL_EXPORT/BOOST_SYMBOL_IMPORT as described above.
I thought that BOOST_SYMBOL_EXPORT and BOOST_SYMBOL_IMPORT are exactly for this: You define *_DECL to *_EXPORT when building the library and *_IMPORT otherwise (and <empty> for static linking)
You may want to use BOOST_SYMBOL_VISIBLE for static linking. You definitely want to use BOOST_SYMBOL_VISIBLE to export RTTI, even for static linking.
Why do individual libraries now have to deal with the Windows vs non-Windows case? Is there ANY Boost library which does this?
Turns out, libraries don't need to distinguish Windows from non-Windows. As pointed out by Peter, BOOST_SYMBOL_EXPORT already expands to BOOST_SYMBOL_VISIBLE on non-Windows.
From the BOOST_SYMBOL_VISIBLE description: "Needed for classes that are not otherwise exported, but are used by RTTI". This sounds to me like either a BOOST_SYMBOL_EXPORT or BOOST_SYMBOL_IMPORT should work. Now I'm left to wonder why individual libraries must now distinguish between OSes additionally to their *_DYN_LINK.
And if Boost.Config is correct: What does BOOST_SYMBOL_IMPORT (on non-Windows) mean then? If the default visibility is set to hidden (-fvisibility=hidden), then this macro will NOT import an exported symbol, it will create a new, private one. This doesn't sound intentional.
BOOST_SYMBOL_IMPORT doesn't need to expand to BOOST_SYMBOL_VISIBLE when the marked symbols are only defined in the library, which is the case normally. When the user consumes the library, no markup is needed as the compiler will simply leave unresolved references to those symbols, to be resolved by the linker. Basically, BOOST_SYMBOL_IMPORT is only there for compatibility with Windows. When you want to export an exception, my suggestion would be to mark the exception class with BOOST_SYMBOL_VISIBLE and mark individual methods you want to export with BOOST_*_DECL. As I said before, marking the whole class with BOOST_*_DECL provides no benefits and can cause problems.