imageworks / Field3D

[NO LONGER MAINTAINED] A library for storing voxel data on disk and in memory.
https://github.com/imageworks/Field3D/wiki/Field3D-Home
BSD 3-Clause "New" or "Revised" License
305 stars 72 forks source link

Missing BOOST_ALL_NO_LIB and BOOST_ALL_DYN_LINK on Windows, causing automatic linking and duplicated symbols #96

Open ghost opened 6 years ago

ghost commented 6 years ago

My environment:

According to documentation of CMake's FindBoost module, automatic linking is default on Windows on which Boost_USE_STATIC_LIBS sometimes does not take effect, e.g., for thread component. In this case, Field3D would attempt to link static library libboost_thread-vc140-mt-x64-1_67.lib of Boost's thread component. But at the same time, line 46 of CMakeLists.txt FIND_PACKAGE (Boost COMPONENTS regex thread) tries to direct the generated VS project to link import library of the dynamic DLL boost_thread-vc140-mt-x64-1_67.lib. Since both static and dynamic library files contain the same symbols, errors like below would result when building Field3D project:

1>------ Build started: Project: Field3D, Configuration: Release x64 ------
1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "public: virtual __cdecl boost::detail::thread_data_base::~thread_data_base(void)" (??1thread_data_base@detail@boost@@UEAA@XZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll)
1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "public: void __cdecl boost::thread::detach(void)" (?detach@thread@boost@@QEAAXXZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll)
1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "class boost::thread::id __cdecl boost::this_thread::get_id(void)" (?get_id@this_thread@boost@@YA?AVid@thread@2@XZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll)
1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "public: class boost::thread::id __cdecl boost::thread::get_id(void)const " (?get_id@thread@boost@@QEBA?AVid@12@XZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll)
1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "bool __cdecl boost::this_thread::interruptible_wait(void *,struct boost::detail::mono_platform_timepoint const &)" (?interruptible_wait@this_thread@boost@@YA_NPEAXAEBUmono_platform_timepoint@detail@2@@Z) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll)
1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "private: bool __cdecl boost::thread::join_noexcept(void)" (?join_noexcept@thread@boost@@AEAA_NXZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll)
1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "public: bool __cdecl boost::thread::joinable(void)const " (?joinable@thread@boost@@QEBA_NXZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll)
1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "private: bool __cdecl boost::thread::start_thread_noexcept(void)" (?start_thread_noexcept@thread@boost@@AEAA_NXZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll)
1>     Creating library C:/.../Field3D-master/build/Release/Field3D.lib and object C:/.../Field3D-master/build/Release/Field3D.exp
1>C:\...\3rd-parties\Field3D-master\build\Release\Field3D.dll : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

The cause is that Field3D fails to disable the automatic linking in Boost. On the other hand, Boost provides mechanism for users to disable automatic linking and to link dynamic Boost libraries only. CMake also exposes the mechanism. But unfortunately, Field3D fails to use it and therefore leads to the above building errors on Windows.

Boost introduces Boost::disable_autolinking and Boost::dynamic_linking import targets. CMake adds BOOST_ALL_NO_LIB and BOOST_ALL_DYN_LINK preprocessor definitions into the INTERFACE_COMPILE_DEFINITIONS property of them, respectively; see line 1166 to 1169 of FindBoost.cmake. As a result, I request Field3D could make use of them to avoid automatic linking and to link dynamic libraries. To this end, we need to copy them to the COMPILE_DEFINITIONS property of the Field3D target. This can be done using the following CMake command with the aid of generator expressions:

TARGET_COMPILE_DEFINITIONS( Field3D PRIVATE $<TARGET_PROPERTY:Boost::disable_autolinking, INTERFACE_COMPILE_DEFINITIONS> )
TARGET_COMPILE_DEFINITIONS( Field3D PRIVATE $<TARGET_PROPERTY:Boost::dynamic_linking, INTERFACE_COMPILE_DEFINITIONS> )

Because line 191 resets the COMPILE_DEFINITIONS property, the above two lines should be placed after it, i.e., line 192-193 of CMakeLists.txt.

Please kindly point out any mistake I have made. If no mistake, I I hope Field3D can be modified as explained above to improve its portability on Windows. Thanks.

magnusw commented 6 years ago

Could you test this out and create a pull request? We don't build Windows internally, the CMake setup has been externally provided so it's difficult for us to test.

Thanks, Magnus

On Fri, Jul 13, 2018 at 2:59 AM zhou-heng notifications@github.com wrote:

According to documentation of CMake's FindBoost module, automatic linking is default on Windows on which Boost_USE_STATIC_LIBS sometimes does not take effect, e.g., for thread component. In this case, Field3D would attempt to link static library libboost_thread-vc140-mt-x64-1_67.lib of Boost's thread component. But at the same time, line 46 of CMakeLists.txt FIND_PACKAGE (Boost COMPONENTS regex thread) tries to direct the generated VS project to link import library of the dynamic DLL boost_thread-vc140-mt-x64-1_67.lib. Since both static and dynamic library files contain the same symbols, errors like below would result when building Field3D project:

1>------ Build started: Project: Field3D, Configuration: Release x64 ------ 1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "public: virtual cdecl boost::detail::thread_data_base::~thread_data_base(void)" (??1thread_data_base@detail@boost@@UEAA@XZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll) 1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "public: void cdecl boost::thread::detach(void)" (?detach@thread@boost@@QEAAXXZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll) 1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "class boost::thread::id cdecl boost::this_thread::get_id(void)" (?get_id@this_thread@boost@@YA?AVid@thread@2@XZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll) 1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "public: class boost::thread::id cdecl boost::thread::get_id(void)const " (?get_id@thread@boost@@QEBA?AVid@12@XZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll) 1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "bool cdecl boost::this_thread::interruptible_wait(void *,struct boost::detail::mono_platform_timepoint const &)" (?interruptible_wait@this_thread@boost@@YA_NPEAXAEBUmono_platform_timepoint@detail@2@@Z) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll) 1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "private: bool __cdecl boost::thread::join_noexcept(void)" (?join_noexcept@thread@boost@@AEAA_NXZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll) 1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "public: bool cdecl boost::thread::joinable(void)const " (?joinable@thread@boost@@QEBA_NXZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll) 1>libboost_thread-vc140-mt-x64-1_67.lib(thread.obj) : error LNK2005: "private: bool __cdecl boost::thread::start_thread_noexcept(void)" (?start_thread_noexcept@thread@boost@@AEAA_NXZ) already defined in boost_thread-vc140-mt-x64-1_67.lib(boost_thread-vc140-mt-x64-1_67.dll) 1> Creating library C:/.../Field3D-master/build/Release/Field3D.lib and object C:/.../Field3D-master/build/Release/Field3D.exp 1>C:...\3rd-parties\Field3D-master\build\Release\Field3D.dll : fatal error LNK1169: one or more multiply defined symbols found ========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

The cause is that Field3D fails to disable the automatic linking in Boost. On the other hand, Boost provides mechanism for users to disable automatic linking and to link dynamic Boost libraries only. CMake also exposes the mechanism. But unfortunately, Field3D fails to use it and therefore leads to the above building errors on Windows.

Boost introduces Boost::disable_autolinking and Boost::dynamic_linking import targets. CMake adds BOOST_ALL_NO_LIB and BOOST_ALL_DYN_LINK preprocessor definitions into the INTERFACE_COMPILE_DEFINITIONS property of them, respectively; see line 1166 to 1169 of FindBoost.cmake. As a result, I request Field3D could make use of them to avoid automatic linking and to link dynamic libraries. To this end, we need to copy them to the COMPILE_DEFINITIONS property of the Field3D target. This can be done using the following CMake command with the aid of generator expressions:

TARGET_COMPILE_DEFINITIONS( Field3D PRIVATE $<TARGET_PROPERTY:Boost::disable_autolinking, INTERFACE_COMPILE_DEFINITIONS> ) TARGET_COMPILE_DEFINITIONS( Field3D PRIVATE $<TARGET_PROPERTY:Boost::dynamic_linking, INTERFACE_COMPILE_DEFINITIONS> )

Because line 191 resets the COMPILE_DEFINITIONS property, the above two lines should be placed after it, i.e., line 192-193 of CMakeLists.txt.

Please kindly point out any mistake I have made. If no mistake, I I hope Field3D can be modified as explained above to improve its portability on Windows. Thanks.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/imageworks/Field3D/issues/96, or mute the thread https://github.com/notifications/unsubscribe-auth/AAdXS-iKvO-DqG0icvcnDk0SWW6MgxM_ks5uGG9ygaJpZM4VOoFh .

ghost commented 6 years ago

Sure, I'd be glad to do it, together with some other issues on Windows.

magnusw commented 6 years ago

Thanks, much appreciated!

On Sun, Jul 15, 2018 at 12:25 PM zhou-heng notifications@github.com wrote:

Sure, I'd be glad to do it, together with some other issues on Windows.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/imageworks/Field3D/issues/96#issuecomment-405112321, or mute the thread https://github.com/notifications/unsubscribe-auth/AAdXS1cGb_Vq6SzQz_ii9YDvHh29bq3Kks5uG5c-gaJpZM4VOoFh .