Tessil / robin-map

C++ implementation of a fast hash map and hash set using robin hood hashing
MIT License
1.26k stars 115 forks source link

1.0.0 fails to build with GCC 12 on Fedora #50

Closed hobbes1069 closed 2 years ago

hobbes1069 commented 2 years ago

Kind of a strange error to me but here it is:

[100%] Linking CXX executable tsl_robin_map_tests
/usr/bin/cmake -E cmake_link_script CMakeFiles/tsl_robin_map_tests.dir/link.txt --verbose=1
/usr/bin/g++ -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/robin-map-1.0.0/.package_note-robin-map-1.0.0-1.fc37.x86_64.ld CMakeFiles/tsl_robin_map_tests.dir/main.cpp.o CMakeFiles/tsl_robin_map_tests.dir/custom_allocator_tests.cpp.o CMakeFiles/tsl_robin_map_tests.dir/policy_tests.cpp.o CMakeFiles/tsl_robin_map_tests.dir/robin_map_tests.cpp.o CMakeFiles/tsl_robin_map_tests.dir/robin_set_tests.cpp.o -o tsl_robin_map_tests  /usr/lib64/libboost_unit_test_framework.so
/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/Scrt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'
Tessil commented 2 years ago

Hi,

Thank you for the report. It's strange as the CI is passing (https://github.com/Tessil/robin-map/actions/runs/2042774915). I also tested locally with g++-12, Boost 1.74 and CMake 3.22.1 with similar compilation flags as the ones in your output and the linking goes well.

For the 1.0.0 release I changed the Boost.Test linking from dynamic to static (https://github.com/Tessil/robin-map/commit/38ace2fcd9c0b2a27580da9480ed50d475b06f04) which could be the cause but BOOST_TEST_MODULE is properly defined.

Which version of Boost and CMake are you using?

hobbes1069 commented 2 years ago

CMake 3.23.0 Boost 1.76

hobbes1069 commented 2 years ago

So on a whim I tried building for all supported versions of Fedora since they will have different version of CMake and Boost but they still all failed. I haven't yet verified if it's for the same reason or not but that seems likely.

https://copr.fedorainfracloud.org/coprs/hobbes1069/testing/build/3877927/

Feel free to poke around, especially the builder-live.log.gz links.

Maybe the problem is some compile / linker flags that are embedded in the spec files? When everything works I like that it condenses the log a bit, but when there are non-obvious failures it makes troubleshooting more difficult.

hobbes1069 commented 2 years ago

For posterity here's the contents on my Fedora 35 system:

$ cat /usr/lib/rpm/redhat/redhat-hardened-cc1 
*cc1_options:
+ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fPIE}}}}}}

$ cat /usr/lib/rpm/redhat/redhat-hardened-ld 
*self_spec:
+ %{!static:%{!shared:%{!r:-pie}}}

Only appears to add stuff around PIC/PIE.

Tessil commented 2 years ago

Thank you for the information, I'll try to reproduce it on Fedora when I have some time.

In the meantime it could be interesting to test a small independent example to check if the problem could come from Boost and the chosen flags. Something like the following files.

main.cpp:

#define BOOST_TEST_MODULE debug_tests

#include <boost/test/unit_test.hpp>

test.cpp:

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(test) {
  BOOST_CHECK(true);
}

CMakeLists.txt:

project(debug_tests)

add_executable(debug_tests "main.cpp" "test.cpp")

target_compile_features(debug_tests PRIVATE cxx_std_11)

# Boost::unit_test_framework
find_package(Boost 1.54.0 REQUIRED COMPONENTS unit_test_framework)
target_link_libraries(debug_tests PRIVATE Boost::unit_test_framework)   
Tessil commented 2 years ago

I tried to build the tests in Fedora 35 and I was able to reproduce the error.

It seems that in the end I need to set Boost_USE_STATIC_LIBS to ON in the CMakeLists.txt to ensure that the static Boost library is used on all platforms (Debian and Ubuntu didn't require it so I completely missed it).

e5775ad98be9f88fa7887504ca3ce850f0265fd8 should resolve the problem, if you could confirm it works on your side I'll then create a 1.0.1 release.

hobbes1069 commented 2 years ago

That indeed did fix the problem.

Tessil commented 2 years ago

Thank you for the confirmation, I created the v1.0.1 release with the change.

nieder commented 10 months ago

For the record, building on macOS against boost_1.78 with Apple-clang, I was still getting undefined _main()

[100%] Linking CXX executable tsl_robin_map_tests
/sw/bin/cmake -E cmake_link_script CMakeFiles/tsl_robin_map_tests.dir/link.txt --verbose=1
/sw/var/lib/fink/path-prefix-clang/c++ -O3 -DNDEBUG -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -mmacosx-version-min=10.14 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/sw/lib CMakeFiles/tsl_robin_map_tests.dir/main.cpp.o CMakeFiles/tsl_robin_map_tests.dir/custom_allocator_tests.cpp.o CMakeFiles/tsl_robin_map_tests.dir/policy_tests.cpp.o CMakeFiles/tsl_robin_map_tests.dir/robin_map_tests.cpp.o CMakeFiles/tsl_robin_map_tests.dir/robin_set_tests.cpp.o -o tsl_robin_map_tests  /sw/opt/boost-1_78/lib/libboost_unit_test_framework.dylib 
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable

I tried setting -DBoost_USE_STATIC_LIBS=ON during the configure step, but that didn't fix it.

nieder commented 4 months ago

I still see this problem with robin-map 1.3.0, as well as with the test program from @Tessil listed above:

[100%] Linking CXX executable debug_tests
/sw/bin/cmake -E cmake_link_script CMakeFiles/debug_tests.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -mmacosx-version-min=10.14 -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/debug_tests.dir/main.o CMakeFiles/debug_tests.dir/test.o -o debug_tests  /sw/opt/boost-1_78/lib/libboost_unit_test_framework.dylib 
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64

If I add int main() {} to main.cpp, then the debug_tests sample build finishes.