Linking problems on windows (boost) - boost

I'm trying to compile boost and mongodb.
I want 64bit versions, shared libs and dynamic linking to the runtime.
Boost is compiled with link=shared, runtime-link=shared, threading=multi (and some others). The lib and dll files have names like: boost_*-vc90-mt-1_41.dll
Now mongodb has per default set: /MT (multithreaded static). The linker required boost libraries with libboost_*-vc90-mt-s-1_41.dll (notice the additional lib and -s). So I changed the option to /MD (multithreaded dll) and the -sdissapeared but the libstayed. I tried it with /DBOOST_THREAD_USE_DLL /DBOOST_ALL_DYN_LINK but it doesn't change. Does the linker still look for the static libs?
Please help :)

BOOST_ALL_DYN_LINK should have done the trick. Please make sure you rebuild your project from scratch, though.
If the problem still persist, I guess you need to tell what is hiding behind the asterisk -- maybe there's a bug with a specific library.

Related

CMake Imported Library Target giving undefined giving undefined symbols on Windows

I'm trying to import libuv into my CMake project so I can link it. I have libuv 1.12.0 installed from here and I placed it in C:\Program Files\libuv\.
project(tls-server LANGUAGES C)
set(LIBUV_ROOT_DIR "C:\\Program Files\\libuv")
add_library(libuv SHARED IMPORTED)
set_property(TARGET libuv PROPERTY IMPORTED_LOCATION "${LIBUV_ROOT_DIR}\\libuv.dll")
set_property(TARGET libuv PROPERTY IMPORTED_IMPLIB "${LIBUV_ROOT_DIR}\\libuv.lib")
add_executable(tls-server "${CMAKE_SOURCE_DIR}/src/main.c")
target_link_libraries(tls-server libuv)
However, given the above code I am still getting undefined symbol errors in Visual Studio:
How can I fix this? I believe the paths are all correct. I'm also using Windows 10.
Never hardcode library paths or names like this in CMake.
Instead use the find_library command, which does a decent job of notifying you early if something is wrong with the provided library.
On Windows in particular, since there are no default locations where libraries are located on the system (something like the /usr/local/lib on *nix systems), you may want to provide an additional customization point for the library's location. I personally like to use environment variables for this, but a normal CMake option will also do:
project(tls-server LANGUAGES C)
find_library(LIBUV_LIBRARIES NAMES uv libuv
HINTS $ENV{LIBUV_ROOT})
add_executable(tls-server ${PROJECT_SOURCE_DIR}/src/main.c)
target_link_libraries(tls-server ${LIBUV_LIBRARIES})
Note that CMake in general never takes care of copying runtime dependencies to the correct place! That is, if libuv was built as a .dll, you must ensure that that .dll is in the correct path when running the program.
You can of course manually insert a copy command in CMake for getting all the dlls into place, but that can be quite cumbersome. Unfortunately there is no more comfortable solution for this problem right now.
Using imported targets here is possible, but really only pays off if you need to pass on more complex properties to the depending target. In my experience, imported targets work best if the dependency provides a fully-fledged package config file. Writing imported targets manually is often not worth the trouble in terms of additional complexity.
I finally managed to solve the issue.
Firstly I reinstalled the binaries from the target library (libuv). Then, I made sure that my cmake was generating x64 project files by using cmake -G "Visual Studio 14 2015 Win64". That was sufficient to get rid of the undefined symbols error. Then all I needed to do was copy the libuv.dll file to the same directory as the executable file, and everything ran fine.
If anyone knows why this error occured, please comment so you can help out other people in the future target the cause of the error better.

Go code building linker error. Can I link manually?

I am building Go code that uses CGo heavily and this code must be compiled into a shared or static library (static is highly preferred). (code for reference)
It all works just fine on Linux and Mac, but on Windows it fails on linker stage either saying that all 4 modes (c-shared, shared, c-archive, archive) are not available or if invoke go tool link -shared manually complains about missing windows specific instructions.
My understanding is that all I need to build usable lib.a is to compile everything I will use into object files (*.o) and then put it through ar to produce usable static library.
Now the question is whether I can completely skip Go's linker and based on prepared .o files create .a manually?
How would I go about doing that if that is even possible?
Looks like gcc on windows is unable to automatically discover necessary shared libraries. The problem was caused by GCC and not by Go.
Although for compiling Go I had to use self-compiled master tip as current release (1.6.2) does not support shared/static libraries on windows/amd64.
Manually feeding gcc with each shared library (ntdll, winmm etc) in default location (C:\Windows\SysWOW64) has fixed the problem.

GCC "undefined reference to" but symbols exist

Can I use shared libraries created by different versions of GCC and how?
I have undefined reference to errors while linking. But these names exist in the so libraries. I figured out that libs were built with older GCC version (2.8), I'm using current GCC version (4.7) and thus it seems that names are mangled differently:
Built by GCC 2.8.1:
setInfo__10SS7_HeaderUl
Built by GCC 4.7.2:
_ZN10SS7_Header7setInfoEm
and can't be resolved (right?).
Is there any way to use old shared libraries without rebuilding them? (Maybe I can recompile existing code using some backward compatibility flags, etc, to suit old libraries)
Is there any way to use old shared libraries without rebuilding them?
No: gcc-2.x and 3.x are not ABI-compatible.
If you somehow managed to fix the mangling, you'd just get a crash because the object layout is completely different. The mangling was changed precisely to save you the trouble of debugging runtime crashes that would be very hard to understand.

Are all the boost dlls and .lib files needed for the boost compilation?

the total size of the boost dlls and .lib files is coming to around 3.6 gb.I may not use all the dlls and lib files. Assume that I'm only including the Boost/Date and time. Are all the other files needed for the boost compilation ? Are the dlls and the lib files specific to windows and linux ???
You don't need .dlls to compile something at all. Technically, you don't even need .libs to compile; only to link, but I'll assume you meant both. You need .dlls to run however, so I'm not sure what that buys you.
And yes, .dlls and .libs are specific to the platform. And in the case of .libs, the compiler.
the total size of the boost dlls and .lib files is coming to around 3.6 gb.
What configurations did you build for? You only need a debug and a release version. If you built a DLL version, then you don't need to also build a static library version (you'll still get .libs though).
My static-library-only variation takes up ~800MB, and I could probably chop that in half, since I see what appears to be duplication in there.

Cross compile Boost 1.40 for VxWorks 6.4

I'm trying to migrate a project which uses Boost (particularly boost::thread and boost::asio) to VxWorks.
I can't get boost to compile using the vxworks gnu compiler. I figured that this wasn't going to be an issue as I'd seen patches on the boost trac that purport to make this possible, and since the vxworks compiler is part of the gnu tool chain I should be able to follow the directions in the boost docs for cross compilation.
I'm building on windows for a ppc vxworks.
I changed the user-config.jam file as specified in the boost docs, and used the target-os=linux option to bjam, but bjam appears to hang before it can compile. Closer inspection of the commands issued by bjam (by invoking it using the -n option) reveal that it's trying to compile with boost::thread's win32 files. This can't be right, as vxworks uses pthreads.
My bjam command: .\bjam --with-thread toolset=gcc-ppc target-os=linux gcc-ppc is set in user-config to point to the g++ppc vxworks cross compiler.
What am I doing wrong? I believe I have followed the docs to the letter.
If it's #including win32 headers instead of the pthread ones, there could be a discrepancy between the set of macros your compiler is defining and the macros the boost headers are checking for. I had a problem like that with the smart pointer headers, which in an older version of boost would check for __ppc but my compiler defined __ppc__ (or vice versa, can't remember).
touch empty.cpp
ccppc -dD -E empty.cpp
That will show you what macros are predefined by your compiler.
I never tried to compile boost for VxWorks, since I only needed a few of the headers.
Try also adding
threadapi=pthread
The documentation you mention is for Boost.Build -- which is standalone build tool -- and the above flag is something specific to Boost.Thread library. What do you mean by "hang"? Because Boost libraries are huge, it sometimes take a lot of time to scan dependencies prior to build.
If it actually hangs, can you catch bjam in a debugger and produce a backtrace? Also, log of any output will help.

Resources