[visibility][test][osx] visibility warnings with 1.70beta
Hi, I have a side project that requires boost.test and I thought it is the right time to use the beta build of 1.70. At link time for my project (in this case a simple boost.test module), I have tons of warnings like the following: ld: warning: direct access in function 'boost::unit_test::decorator::depends_on::apply(boost::unit_test::test_unit&)' from file '/Users/raffi/from-big-laptop/code/software_workshop/sw_thirdparties/osx/boost_1_70_0_b1/lib/libboost_unit_test_framework-xgcc42-mt-x64-1_70.a(decorator.o)' to global weak symbol 'boost::unit_test::basic_cstring<char const>::null_str()::null' from file '/Users/raffi/code/mpi/mpi_kmeans/build/MPI-Kmeans.build/Debug/test_mpi_kmeans.build/Objects-normal/x86_64/test_cls_and_func_impl.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings. running Xcode 10.1 on 10.14/mojave. I am building boost like this: ./b2 \ cflags="-mmacosx-version-min=10.10" \ cxxflags="-std=c++11 -stdlib=libc++ -mmacosx-version-min=10.10" \ mflags="-mmacosx-version-min=10.10" \ mmflags="-mmacosx-version-min=10.10" \ linkflags="-stdlib=libc++ -mmacosx-version-min=10.10" \ --prefix=`pwd`/../${build_folder} \ --without-log \ --layout=versioned \ install Each of the files that are being built in my project and that are raising the warning have a compilation command like this: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DBOOST_ALL_NO_LIB -DKMEANS_VERBOSE=0 -I/Users/raffi/code/mpi/mpi_kmeans/include -I/Users/raffi/code/mpi/mpi_kmeans/applications/include -isystem /Users/raffi/from-big-laptop/code/software_workshop/sw_thirdparties/osx/boost_1_70_0_b1/include/boost-1_70 -O3 -DNDEBUG -std=gnu++11 -o CMakeFiles/test_mpi_kmeans.dir/test/test_kmeans.cpp.o -c /Users/raffi/code/mpi/mpi_kmeans/test/test_kmeans.cpp which is pretty much what I had so far and before 1.70. Boost.test is using BOOST_SYMBOL_VISIBLE to make a symbol public, including the static build variant. Why does the linker say """ This was likely caused by different translation units being compiled with different visibility settings. """ is completely unclear to me. How can I inspect what b2 emits as compilation command line for further debugging? All those visibility issues are causing me a lot of headache :) Thanks! Raffi
Raffi Enficiaud wrote:
Hi,
I have a side project that requires boost.test and I thought it is the right time to use the beta build of 1.70. At link time for my project (in this case a simple boost.test module), I have tons of warnings like the following:
ld: warning: direct access in function 'boost::unit_test::decorator::depends_on::apply(boost::unit_test::test_unit&)' from file '/Users/raffi/from-big-laptop/code/software_workshop/sw_thirdparties/osx/boost_1_70_0_b1/lib/libboost_unit_test_framework-xgcc42-mt-x64-1_70.a(decorator.o)' to global weak symbol 'boost::unit_test::basic_cstring<char const>::null_str()::null' from file '/Users/raffi/code/mpi/mpi_kmeans/build/MPI-Kmeans.build/Debug/test_mpi_kmeans.build/Objects-normal/x86_64/test_cls_and_func_impl.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
Looking at https://github.com/boostorg/test/blob/develop/include/boost/test/utils/basic... template<typename CharT> inline typename basic_cstring<CharT>::pointer basic_cstring<CharT>::null_str() { static CharT null = 0; return &null; } there's no BOOST_SYMBOL_VISIBLE there, so `null` is indeed different in the library (with hidden visibility) and in the application (with default visibility). Perhaps that's what the linker complains about. I'm not sure what the right fix here is though.
On 27.03.19 20:35, Peter Dimov via Boost wrote:
Raffi Enficiaud wrote:
[snip]
Looking at
https://github.com/boostorg/test/blob/develop/include/boost/test/utils/basic...
template<typename CharT> inline typename basic_cstring<CharT>::pointer basic_cstring<CharT>::null_str() { static CharT null = 0; return &null; }
there's no BOOST_SYMBOL_VISIBLE there, so `null` is indeed different in the library (with hidden visibility) and in the application (with default visibility). Perhaps that's what the linker complains about.
I'm not sure what the right fix here is though.
Oh right, that should be that and there were other symbols like this that I had to fix. I'll give it a shot tonight. Thanks! Raffi
On 3/27/19 10:16 PM, Raffi Enficiaud via Boost wrote:
Hi,
I have a side project that requires boost.test and I thought it is the right time to use the beta build of 1.70. At link time for my project (in this case a simple boost.test module), I have tons of warnings like the following:
ld: warning: direct access in function 'boost::unit_test::decorator::depends_on::apply(boost::unit_test::test_unit&)' from file '/Users/raffi/from-big-laptop/code/software_workshop/sw_thirdparties/osx/boost_1_70_0_b1/lib/libboost_unit_test_framework-xgcc42-mt-x64-1_70.a(decorator.o)' to global weak symbol 'boost::unit_test::basic_cstring<char const>::null_str()::null' from file '/Users/raffi/code/mpi/mpi_kmeans/build/MPI-Kmeans.build/Debug/test_mpi_kmeans.build/Objects-normal/x86_64/test_cls_and_func_impl.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
running Xcode 10.1 on 10.14/mojave.
I am building boost like this:
./b2 \ cflags="-mmacosx-version-min=10.10" \ cxxflags="-std=c++11 -stdlib=libc++ -mmacosx-version-min=10.10" \ mflags="-mmacosx-version-min=10.10" \ mmflags="-mmacosx-version-min=10.10" \ linkflags="-stdlib=libc++ -mmacosx-version-min=10.10" \ --prefix=`pwd`/../${build_folder} \ --without-log \ --layout=versioned \ install
Each of the files that are being built in my project and that are raising the warning have a compilation command like this:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DBOOST_ALL_NO_LIB -DKMEANS_VERBOSE=0 -I/Users/raffi/code/mpi/mpi_kmeans/include -I/Users/raffi/code/mpi/mpi_kmeans/applications/include -isystem /Users/raffi/from-big-laptop/code/software_workshop/sw_thirdparties/osx/boost_1_70_0_b1/include/boost-1_70 -O3 -DNDEBUG -std=gnu++11 -o CMakeFiles/test_mpi_kmeans.dir/test/test_kmeans.cpp.o -c /Users/raffi/code/mpi/mpi_kmeans/test/test_kmeans.cpp
which is pretty much what I had so far and before 1.70.
Boost.test is using BOOST_SYMBOL_VISIBLE to make a symbol public, including the static build variant. Why does the linker say
""" This was likely caused by different translation units being compiled with different visibility settings. """
is completely unclear to me. How can I inspect what b2 emits as compilation command line for further debugging?
You can add -d+2 to the b2 command line to see the commands it is using while building Boost. I'm guessing that the compiler is correct in that different visibility modes are used for different TUs, since I don't see visibility flags in your project's command line and visibility is likely set to hidden when building Boost. The particular complaint in the warnings you quoted is about the function-local static `null` in `basic_cstring<CharT>::null_str()`, which is not explicitly marked as visible and therefore has different visibility when it is compiled in Boost and your project. I suggest changing the code so that `null` is instead a static class member of `basic_cstring` and mark it with `BOOST_SYMBOL_VISIBLE`. Also, it might make sense to make it a const array instead of a single character, and change `null_str` to return a const pointer instead of a mutable one.
On 27.03.19 20:38, Andrey Semashev via Boost wrote:
On 3/27/19 10:16 PM, Raffi Enficiaud via Boost wrote:
[snip]
You can add -d+2 to the b2 command line to see the commands it is using while building Boost.
I'm guessing that the compiler is correct in that different visibility modes are used for different TUs, since I don't see visibility flags in your project's command line and visibility is likely set to hidden when building Boost. The particular complaint in the warnings you quoted is about the function-local static `null` in `basic_cstring<CharT>::null_str()`, which is not explicitly marked as visible and therefore has different visibility when it is compiled in Boost and your project.
I suggest changing the code so that `null` is instead a static class member of `basic_cstring` and mark it with `BOOST_SYMBOL_VISIBLE`. Also, it might make sense to make it a const array instead of a single character, and change `null_str` to return a const pointer instead of a mutable one.
I am not doing any change to the code that is not related to the warning. To follow up: https://github.com/boostorg/test/commit/04006ad5bdab92ad3f0eb23fb264a9141731... Lessons learned: * template classes should have their forward declaration with visibility settings * local visibility does not work (I do not know if this is the language or a compiler limitation), so the static variables need to get out. For instance: static lazy_ostream& instance() { BOOST_SYMBOL_VISIBLE static lazy_ostream inst; return inst; } is not setting the visibility of the static variable. I guess all those things are compiler specific, and not at all indicated in the standard? Thanks for the quick help, Tests are running, I will need to get this in the next release, Raffi
participants (3)
-
Andrey Semashev
-
Peter Dimov
-
Raffi Enficiaud