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 >::version() const':
main.cpp:(.text._ZNK5boost7archive6detail11iserializerINS0_13text_iarchiveE6MyTypeIdLm2EEE7versionEv[_ZNK5boost7archive6detail11iserializerINS0_13text_iarchiveE6MyTypeIdLm2EEE7versionEv]+0x15):
undefined reference to `boost::serialization::version >::value'
----
nm -C shows that the symbol
'boost::serialization::version >::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 :(