Compiling Bullet physics and Boost together as static libraries - visual-studio-2010

I develop addons for a space flight simulator called Orbiter: http://orbit.medphys.ucl.ac.uk/
It accepts plugins as dll files. I recently made a plugin which uses the Bullet physics library as well. Its statically linked to the dll, so the bullet library is itself not a dll but compiled right into the plugin. Bullet is compiled with Multi-threaded (/MT) option for the release and Multi-threaded Debug (/MTd) for debug
Now I want to use threads from Boost. So I installed the static Boost libraries by choosing the 2 static options from the Boost Pro installer. I was able to successfully create a Win 32 application with these static libraries. The application used Multi-threaded (/MT) as well. So I know that there is no mismatch on the flags.
Yet, when I add Boost to my Orbiter dll plugin project, which also has Bullet, I get a link error :
1>------ Build started: Project: Bump, Configuration: Release Win32 ------
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(990,5): warning MSB8012: TargetPath(F:\Orbiter\Orbitersdk\samples\BumpThreaded\Release\Bump.dll) does not match the Linker's OutputFile property value (F:\Orbiter\Modules\Plugin\Bump.dll). This may cause your project to build incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Link.OutputFile).
1>MSVCRT.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info##AAE#ABV0##Z) already defined in LIBCMT.lib(typinfo.obj)
1>MSVCRT.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info##AAEAAV0#ABV0##Z) already defined in LIBCMT.lib(typinfo.obj)
1> Creating library F:\Orbiter\Orbitersdk\samples\BumpThreaded\Release\Bump.lib and object F:\Orbiter\Orbitersdk\samples\BumpThreaded\Release\Bump.exp
1>LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>......\Modules\Plugin\Bump.dll : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 3 up-to-date, 0 skipped ==========
From what I read on other questions, this can be due to mismatched flags for 2 libraries being used within an application. But thats not the case here. Both Bullet and Boost are compiled with /MT.
Also boost works ok with a normal win 32 application, so why the problem when linking it statically to output a dll ?
I use visual studio 2010 express and have a windows 7 64 bit system.
Thanks for any help in advance :)

If you're only using Boost and Bullet, and these are both definitely compiled with /MT, then it must be your Bump dll itself which is using /MD.

Related

How to figure out where linking to static library of Boost's thread component is postulated when building Field3D?

I am building Field3D which links to Boost's thread library. The building environment is listed as follows:
Windows 10 version 1803 64bit
Visual Studio 2015 Update 3
CMake 3.11.4
Release x64 DLL mode in VS
Field3D source package is downloaded from master branch of https://github.com/imageworks/Field3D
Boost is pre-compiled binary of version 1.67.0 for VS2015 (v14.0) 64bit, downloaded from https://sourceforge.net/projects/boost/files/boost-binaries and installed under C:\local\boost_1_67_0 directory.
Doxygen and HDF5 installed properly.
The CMake command line to set up VS2015 is:
cmake -DCMAKE_CONFIGURATION_TYPES=Release -DBUILD_SHARED_LIBS=ON
-DCMAKE_INSTALL_PREFIX=C:...\Field3D-master\install -DDOXYGEN_EXECUTABLE="C:\Program Files\doxygen\bin\doxygen.exe" -DHDF5_ROOT="C:\Program Files\HDF_Group\HDF5\1.10.2" -DBOOST_ROOT=C:\local\boost_1_67_0 -DBOOST_INCLUDEDIR=C:\local\boost_1_67_0\boost -DBOOST_LIBRARYDIR=C:\local\boost_1_67_0\lib64-msvc-14.0 -DIlmbase_Base_Dir=C:...\openexr-develop\IlmBase\install_ -G"Visual Studio 14 2015 Win64" ..
Then I open the generated field3d.sln in VS2015 and try to build Field3D project. Errors are reported as below:
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 of these errors, as far as I can see, is that the line 46 of Field3D's CMakeLists.txt
FIND_PACKAGE (Boost COMPONENTS regex thread)
specifies linking boost's thread component, which in turn leads to linking import library C:\local\boost_1_67_0\lib64-msvc-14.0\boost_thread-vc140-mt-x64-1_67.lib, as can be checked in Project Properties -> Linker -> Input -> Additional Dependencies in VS. But somehow Field3D insists on additionally linking to the static library of Boost's thread component which is libboost_thread-vc140-mt-x64-1_67.lib (you can see it in the error messages), thus causing name conflicts. If I temporarily remove "thread" from the FIND_PACKAGE's COMPONENTS list to let Field3D link to the static library as it insists, the Field3D project can build correctly.
Because I wanna build Field3D based on the dynamic DLL of Boost library, my question is: Why does Field3D insist on linking to the static boost library "libboost_thread-vc140-mt-x64-1_67.lib"? Where is this rule introduced? How to suppress linking static thread library of Boost? I have checked CMakeLists.txt, and variables like Boost_LIBRARY_DIRS, Boost_LIBRARIES and Field3D_BIN_Libraries therein but they do not contain static library filename libboost_thread-vc140-mt-x64-1_67.lib. I know that #pragma comment (linker, ...) can also require linking to some user-defined library, but there is no such directive in Field3D source package whatsoever. So I am at my wit's end and post this question here in hope that someone can help me figure out where on earth the linking postulation to the static library of Boost's thread component comes from. Some minor modification may be needed to reproduce the issue but I think the information provided above should cover most of the build for a veteran. If you need any other info to troubleshoot this problem please let me know. Thank you.
After another bunch of hours to check Field3D's building process, I believe the problem is Field3D's failure to make use of Boost's mechanism to disable automatic linking and to enable dynamic linking on Windows. An issue ticket is submitted in hope that the developers of Field3D can fix it in future: https://github.com/imageworks/Field3D/issues/96. Briefly, add the following two commands to copy INTERFACE_COMPILE_DEFINITIONS property of Boost::disable_autolinking and Boost::dynamic_linking import targets to Field3D project
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> )
after line 189 of CMakeLists.txt.
Please point out if I have made any mistake.

How can I find out which library is including libcmt?

I'm trying to link a Windows executable that depends on a several static libraries (some of which I have built, some of which I have not). When I do the link, I get a flock of errors like:
LIBCMT.lib(mlock.obj) : error LNK2005: _unlock already defined in MSVCRT.lib(MSVCR100.dll)
which is the classic /MD vs. /MT problem (whether the C runtime is statically or dynamically linked). I tried the easy solution first, adding the linker flags
/nodefaultlib:libcmt /nodefaultlib:libcpmt
but that just gave different errors:
msvcprt.lib(MSVCP100.dll) : error LNK2005: "public: __cdecl std::_Locinfo::~_Locinfo(void)" (??1_Locinfo#std##QEAA#XZ) already defined in gtest.lib(gtest-all.cc.obj)
gtest.lib(gtest-all.cc.obj) : error LNK2001: unresolved external symbol "private: static int std::locale::id::_Id_cnt" (?_Id_cnt#id#locale#std##0HA)
I've gone through the libraries I'm building, and as far as I can tell I'm building them all /MD. I say "as far as I can tell" because some of them are third-party libraries that come with their own makefiles so I don't have complete control over the build process..
I don't think "depends" works on libraries (only EXEs and DLLs), is there a tool that would let me look at the various libraries I'm linking in, and see which one is bringing in libcmt when I want to be using msvcrt instead?
I have had the same problem and I used dumpbin ( http://msdn.microsoft.com/en-us/library/z66yd3h6.aspx ) with /DIRECTIVES options on the libs. It will show a number of /DEFAULTLIB sections, each one is another lib that your lib try to use. Dumpbin needs to run from the Visual Studio command promt.
dumpbin /DIRECTIVES liblua52.lib
I had 100+ libs with all the solution configurations and platforms so I made a python 2.7 script (crtdisplay.py) to do it for me. It can be found on my bitbucket repository at https://bitbucket.org/vimarina/ctrlcv/src/57b7ddca15b5c7fefddcf20ffcea0633223a4bd6/crtdisplay . Put it in the root directory of your libs. Not much error checking in that code so do not be surprised if it fails :). I used Visual Studio 2010 so might fail on other versions of Visual Studio.
crtdisplay.py > info.txt

boost.log errors linking statically

I'm getting the following (and many more) errors when attempting to link my project statically with boost.log on MSVC 10.0:
1>libboost_log-vc100-mt-gd-1_53.lib(attribute_name.obj) : error
LNK2001: unresolved external symbol "**__declspec(dllimport)** public:
__thiscall std::_Container_base::~_Container_base(void)" (__imp_??1_Container_base#std##QAE#XZ)
1>libboost_log-vc100-mt-gd-1_53.lib(text_file_backend.obj) : error
LNK2001: unresolved external symbol "**__declspec(dllimport)** public:
__thiscall std::_Container_base::~_Container_base(void)" (__imp_??1_Container_base#std##QAE#XZ)
Note that the project is linking also to boost system, filesystem, and thread libraries.
1> Searching ../lib/\libboost_system-vc100-mt-gd-1_53.lib:
1> Searching ../lib/\libboost_date_time-vc100-mt-gd-1_53.lib:
1> Searching ../lib/\libboost_regex-vc100-mt-gd-1_53.lib:
1> Searching ../lib/\libboost_thread-vc100-mt-gd-1_53.lib:
1> Searching ../lib/\libboost_chrono-vc100-mt-gd-1_53.lib:
1> Searching ../lib/\libboost_log-vc100-mt-gd-1_53.lib:
1> Searching ../lib/\libboost_filesystem-vc100-mt-gd-1_53.lib:
My project does not define the BOOST_ALL_DYN_LINK or BOOST_LOG_DYN_LINK macros, so I was not expecting to see the __declspec signatures, which I am thinking is the ultimate problem. Am I missing something required to properly link this library statically?
Update
I removed precompiled headers on my project and performed a "clean", and everything linked fine. Is it possible that precompiled headers were somehow causing the project to link statically to CRT?
You may need link log_setup firstly and then log before filesystem and so on, this was boost link code in my CMakeLists.txt:
set(USED_BOOST_LIBS ${Boost_LOG_SETUP_LIBRARY} ${Boost_LOG_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY} ${Boost_DATE_TIME_LIBRARY}
${Boost_THREAD_LIBRARY} ${Boost_REGEX_LIBRARY}
)
...
target_link_libraries(myexe ${USED_BOOST_LIBS})
It works fine with me both on MSVC 14.0 and gcc 4.8.You can try it.

Linking googleTest in VS2010 results in LNK2005 because of other dependent libraries

I have a large and complicated project that is finally getting unit tests. I've built googleTest 1.6.0 locally with Visual Studio 2010, the project files built with cmake as the README specifies.
This project has many dependent libraries that are statically and dynamically linked. Many of them proprietary. All attempts to link generate 220 such errors. Here is a sampling:
msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: void __cdecl std::_Container_base12::_Orphan_all(void)" (?_Orphan_all#_Container_base12#std##QEAAXXZ) already defined in gtest.lib(gtest-all.obj)
libcpmtd.lib(cerr.obj) : error LNK2005: "protected: char * __cdecl std::basic_streambuf >::_Gndec(void)" (?_Gndec#?$basic_streambuf#DU?$char_traits#D#std###std##IEAAPEADXZ) already defined in msvcprtd.lib(MSVCP100D.dll)
LIBCMTD.lib(setlocal.obj) : error LNK2005: _configthreadlocale already defined in MSVCRTD.lib(MSVCR100D.dll)
LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
fatal error LNK1169: one or more multiply defined symbols found
I've tried the /NODEFAULTLIB flag, and I've tried to ignore just msvcprtd.lib, MSVCRTD.lib, and LIBCMTD.lib, as suggested, but then I suffer from unresolved symbols...
Both the project and googleTest are compiled with x64, /MP, /MDd, and no /clr.
I've been playing around with compiler flags, wondering if there's some sort of version mismatch. Dumpbin, to the extent with which I understand it, hasn't hinted anything I might understand. I was hoping for an er
It looks like your question is answered in Google Talk's FAQ. Make sure all your libraries use the /MD(d) setting.
You may get a number of the following linker error or warnings if you attempt to link your test project with the Google Test library when your project and the are not built using the same compiler settings.
LNK2005: symbol already defined in object
LNK4217: locally defined symbol 'symbol' imported in function 'function'
LNK4049: locally defined symbol 'symbol' imported
The Google Test project (gtest.vcproj) has the Runtime Library option set to /MT (use multi-threaded static libraries, /MTd for debug). If your project uses something else, for example /MD (use multi-threaded DLLs, /MDd for debug), you need to change the setting in the Google Test project to match your project's.
To update this setting open the project properties in the Visual Studio IDE then select the branch Configuration Properties | C/C++ | Code Generation and change the option "Runtime Library". You may also try using gtest-md.vcproj instead of gtest.vcproj.

linking with boost unresolved extern link error

Visual Studio 2005
I am linking with boost libraries release 1_33_1.
I keep getting this link error.
libboost_thread-vc80-mt-sgd-1_33_1.lib(once.obj) :error LNK2001: unresolved external symbol "public: void __thiscall std::_String_base::_Xran(void)const " (?_Xran#_String_base#std##QBEXXZ)
Does anyone have any suggestions?
Many thanks,
Edit ======
After recompiling the boost libraries using these switches:
C:\boost_1_42_0>bjam --build-dir=d:\boost_1_42 --build-type-complete --toolset=msvc-8.0 address-model=32 architecture=x86
I am getting some of the following errors:
1>msvcrtd.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info##AAEAAV0#ABV0##Z) already defined in LIBCMTD.lib(typinfo.obj)
1>msvcrtd.lib(MSVCR80D.dll) : error LNK2005: __wassert already defined in LIBCMTD.lib(wassert.obj)
Anyone have any ideas?
Many thanks,
First of all you don't have to set address-model and architecture explicitly if building 32 bit. Also your call has an error: --build-type-complete should be --build-type=complete. If I'm not wrong your call builds absolutely all libs, including filesystem, regex etc.
Obviously you need boost::thread only, so I would recommend to try this call:
C:\boost_1_42_0>bjam --build-dir=d:\boost_1_42 --build-type=complete --toolset=msvc-8.0 --with-thread
But I don't think that will solve your prob but you could give it a try.
My guess is that you somehow mixed /MD and /MT in the project settings.
See these links: First, second
What is probably happening is that your project is linking to the static debug version of the C++ runtime, which causes the static debug boost thread library to be linked and is also linking to another static library which was dynamically linked to the C++ runtime.
The sgd tag in libboost_thread-vc80-mt-sgd-1_33_1.lib means that the boost thread library you're linking with was built against the static debug version of the C++ runtime.

Resources