Open ghost opened 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 .
Sure, I'd be glad to do it, together with some other issues on Windows.
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 .
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 librarylibboost_thread-vc140-mt-x64-1_67.lib
of Boost's thread component. But at the same time, line 46 of CMakeLists.txtFIND_PACKAGE (Boost COMPONENTS regex thread)
tries to direct the generated VS project to link import library of the dynamic DLLboost_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: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
andBoost::dynamic_linking
import targets. CMake addsBOOST_ALL_NO_LIB
andBOOST_ALL_DYN_LINK
preprocessor definitions into theINTERFACE_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 theCOMPILE_DEFINITIONS
property of the Field3D target. This can be done using the following CMake command with the aid of generator expressions: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.