Darwin targets do not have a protected
visibility function attribute, see LLVM explanation. This means that the AX_GCC_FUNC_ATTRIBUTE
check for visibility
fails:
0configure:24513: checking for __attribute__((visibility))
1configure:24537: g++ -std=c++11 -o conftest -g -O2 -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -DMAC_OSX -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -Wl,-headerpad_max_install_names conftest.cpp >&5
2conftest.cpp:35:56: warning: target does not support 'protected' visibility; using 'default' [-Wunsupported-visibility]
3 int foo_pro( void ) __attribute__((visibility("protected")));
4 ^
51 warning generated.
6configure:24537: $? = 0
7configure:24550: result: no
This leads to EXPORT_SYMBOL
being defined to nothing, as HAVE_FUNC_ATTRIBUTE_VISIBILITY
is not defined, and when building with reduced exports, you end up with a libbitcoinconsensus.dylib that doesn’t export any _bitcoinconsensus_*
symbols.
0➜ git:(master) nm -C src/.libs/libbitcoinconsensus.dylib | rg _bitcoinconsensus_
1➜ git:(master)
We do have a second check for the visibility
attribute, which works for Darwin as it’s only testing for default visibility, however the result of this check isn’t used at all. It was added in #4725, along with the --enable-reduce-exports
option, however when libbitcoinconsensus was added in #5235, it used the results of the added AX_GCC_FUNC_ATTRIBUTE
calls.
This PR removes our usage of the AX_GCC_FUNC_ATTRIBUTE macro entirely, in favour of our own checks in configure. This meant adding a check for dllexport
, which I’ve tested as working with both GCC and Clang when building for Windows. I haven’t added an equivalent check for dllimport
, as we weren’t actually using the result of that check, we’re just testing that MSC_VER
was defined before using.
With these changes building a libbitcoinconsensus with reduced exports, when targeting Darwin, works as expected:
0./autogen.sh
1./configure --disable-tests --disable-bench --with-utils=no --with-daemon=no --with-gui=no --disable-wallet --with-libs=yes --enable-reduce-exports
2make -j8
3...
4nm -C src/.libs/libbitcoinconsensus.dylib | rg _bitcoinconsensus_
5000000000000a340 T _bitcoinconsensus_verify_script
600000000000097e0 T _bitcoinconsensus_verify_script_with_amount
7000000000000a3c0 T _bitcoinconsensus_version
0>>> import ctypes
1>>> consensus = ctypes.CDLL("src/.libs/libbitcoinconsensus.dylib")
2>>> print(consensus.bitcoinconsensus_version())
31
4>>> exit()
TODO: Modify a CI job to compile with –enable-reduce-exports and check for symbols in shared lib?