Boost::serialize: im doing an Windows MSVC to Linux GCC port and i have a linker error (with a small example)
im doing an Linux/GCC port of an huge ~1Mio LOC/15 years grown Windows/MSVC project - my first step was switching over to CMake replacing the Studio-Solution file and in around 2.5 weeks i went from a hell lot of compile errors down to full compilation and nearly full linking - happy state so far :) but i stumbled over an linking problem using Boost::serialize with template types (in static libs and hundreds of them in this project) the code compiles and links with MSVC but not with GCC/Clang ld/lld/mold under Linux tested with Boost 1.84.0 - needs Boost::serialization ---- /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/linux_link_error_test.dir/main.cpp.o: in function `boost::archive::detail::iserializer<boost::archive::text_iarchive, MyType<double, 2ul> >::version() const': main.cpp:(.text._ZNK5boost7archive6detail11iserializerINS0_13text_iarchiveE6MyTypeIdLm2EEE7versionEv[_ZNK5boost7archive6detail11iserializerINS0_13text_iarchiveE6MyTypeIdLm2EEE7versionEv]+0x15): undefined reference to `boost::serialization::version<MyType<double, 2ul> >::value' ---- nm -C shows that the symbol 'boost::serialization::version<MyType<double, 2ul> >::value' is 'U' undefined in the the lib but i don't understand why the linker is looking for this header-only version function - and what MSVC is doing different to accept it as is i reduced the big scenario down to a more or less trivial sample to show the effect loading a dummy type "MyType" it compiles and links with MSVC but GCC gives me the linker error https://github.com/LowLevelMahn/linux_link_error | | build.txt | CMakeLists.txt | +---linux_link_error_lib <-- a static lib with the serializable 'MyType' | CMakeLists.txt | MyType.hpp <-- definition of the dummy type | serialize_MyType.hpp <-- definition of the boost serialization routines | test.cpp <-- dummy code for the static lib | \--linux_link_error_test <-- console app using MyType serialization CMakeLists.txt main.cpp the structure of the sample project, static-library, using different headers for type-definition and its serialize routines is intentionaly like in the original project - so i can maybe easily adapt a solution to my real project, i hope the sample is bare enough :) how to build: mkdir linux_link_error_dev cd linux_link_error_dev git clone https://github.com/LowLevelMahn/linux_link_error.git mkdir _build cd _build # Windows/MSVC cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_PREFIX_PATH=[boost-path]\lib\cmake ..\linux_link_error # Linux/gcc cmake -DCMAKE_PREFIX_PATH=[boost-path]/lib/cmake ../linux_link_error #or without prefix path if boost is installed as package in your distro cmake ../linux_link_error cmake --build . result: builds on windows on linux with gcc i get the linker error from above my system: recent Tumbleweed SUSE gcc 13.2.1 clang 18.1.1 ld: 2.42.0 lld: 18.1.1 mold: 2.30.0 my boost build: wget https://boostorg.jfrog.io/artifactory/main/release/1.84.0/source/boost_1_84_... tar -xf boost_1_84_0.tar.bz2 cd boost_1_84_0 ./bootstrap.sh --prefix=/home/testing/boost_1_84_0_install ./b2 install it could be that all the MSVC magic/micro compiler/linker differences i've learned in the last years don't let me see the truth :(
someone at reddit gave me at hint to use signed int for the version::value when i change the version routine in serialize_MyType.hpp to use int it links template <typename V, std::size_t D> struct version<MyType<V, D>> { // does not link // BOOST_STATIC_CONSTANT( unsigned int, value = 1 ); // links BOOST_STATIC_CONSTANT( int, value = 1 ); }; i don't understand why that is working and if that is intended - as the version seems to be given as unsigned int to the load/save routines
participants (1)
-
Dennis Luehring