Static linking not building needed Boost version in VS 2017?

#1

I have a recently-installed VS 2017 Community Edition, which seems to have been building and running my OF projects nicely.

I then tried to build statically-linked versions (both debug and release), by going into project settings both for my project and for OF and selecting non-DLL versions under C++/Code Generation/Runtime Library.

The result is one link error, where VS reports it cannot find a version of the Boost file system lib that has an extra ‘s’ in its filename compared to what I actually have. e.g.:

LNK1104 cannot open file ‘libboost_filesystem-vc-141-mt-sgd-1_64.lib’

and what I have in C:\OF0.10.1vs2017\libs\boost\lib\vs\x64 is:

libboost_filesystem-vc141-mt-1_64.lib
libboost_filesystem-vc141-mt-gd-1_64.lib
libboost_system-vc141-mt-1_64.lib
libboost_system-vc141-mt-gd-1_64.lib

So evidently I need to change some setting to get VS to either not look for the ‘s’ version, or to build the ‘s’ version, neither of which I see any clue as to what even the ‘s’ means or how to do either of those things.

In searching the web and StackExchange, the closest I found was a suggestion to build ALL possible configurations of boost, which I suppose would work, but they just gave a command-line to run, which doesn’t actually work unless you know some other context other than it goes in the x86 Native Native Tools Command prompt - I expect you need to aim it at some directory and/or target for it to know what to build?

openFrameworks static linking or memory management problem?
#2

I’ve looked further into this, and gather/remember that the ‘s’ in fact stands for “static”, so I gather the issue is that I need to somehow get static versions of the .lib files built, and just need to know how to do that…

Sadly, all the answers I’ve found on other sites online are incomplete and assume the asker knows or can deduce how to build Boost with different options, just giving a command line with no context for how exactly to get the computer or x86 Native Tools prompt to respond to it with other than:

C:\OF0.10.1vs2017\libs\boost>.\b2 --build-type=complete
‘.\b2’ is not recognized as an internal or external command,
operable program or batch file.

#3

I could download Boost and try building it myself and moving what I build into the OF boost lib folders, but I expect OF wants specific versions of Boost (which I don’t know which)?

#4

Does the “141” in the lib file name correspond to the “boost_1_64_0-msvc-14.1-64” versions on the Boost site? (I guess I’ll just try one until I learn better…)

#5

Ok, I managed to figure out my own problem, more or less.

For the benefit of others, since questions about this sort of thing seem much more numerous than answers, I’ll try to write some answers to my own questions now.

The ‘s’ in the library file name indeed stands for “static linking”. Other letters in Boost filenames in Windows are as listed here: https://www.boost.org/doc/libs/1_40_0/more/getting_started/windows.html#library-naming

In order to get the static versions of the Boost libs that were not in my OF folders, I downloaded compiled versions from the Source Forge Boost files section, where one could also get the full source and more info on how to build them, if desired.

Vaguely remembering some mentions that OF doesn’t always use the latest versions of things, I zeroed in on a version of Boost that I thought was probably compatible due to having matching filenames, and got myself the libboost_filesystem-vc-141-mt-s gd-1_64.lib requested, and others, and just copied the lib files into where VS was looking for them in the OF file tree.

Then I needed to make sure VS was trying to build the right Debug/Release version, and that the VS project settings for that matched in both my project and the OF subproject.

Then it just worked, and gave me a nice statically-linked EXE, that also seems to work.

Yay!

If anyone in the future is suffering with this, feel free to ask me to try to help.

1 Like
#6

Did you compile X86 (32bit version) or X64 (64bit)?
Didn’t you experience output such as this? (Looks like openFrameworksLib_debug.lib linked correctly, but my project generated via OF project generator got some 323 lines of unresolved external symbols…)

2>LINK : error LNK2001: unresolved external symbol __load_config_used
2>D:\Work\OpenFrameworks\of_v0.10.1_vs2017_release\libs\openFrameworksCompiled\project\vs\…\libs\boost\lib\vs\Win32\libboost_filesystem-vc141-mt-sgd-1_64.lib : warning LNK4272: library machine type ‘x64’ conflicts with target machine type ‘x86’
2>bin\imageTestSketch_debug.exe : fatal error LNK1120: 323 unresolved externals
2>Done building project “imageTestSketch.vcxproj” – FAILED.
========== Build: 1 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

#7

I compiled x86, though x64 just gives me "Error LNK1104 cannot open file ‘libboost_filesystem-vc141-mt-s-1_64.lib’ which I expect has the same solution (provide that lib file).

I don’t remember for sure, but I think at some point I did get a large number of unresolved external linker errors.

The error you are showing looks to me like just a settings mismatch. It seems to have found an x64 lib but something is set to build x86, so it can’t find x86 symbols. Visual Studio has a convoluted UI for managing the build settings, and it’s easy to get part of the project doing one thing somewhere and another things somewhere else, which then results in complex error messages and leaves the user to go hunting to figure out what it’s talking about and how to get it straight.

If you change the whole project to build x64, does it build?

#8

I tried and it gets similar output errors… this time it’s “only” 271 unresolved externals… :smiley:

Oddly enough though, it seems that the main module (openframeworksLib project of my vs solution) builds correctly, because whether the Target Machine is set to MachineX86 or MachineX64, it gives output of both projects built… 1> refers to openframeworksLib, and 2> to my generated project that inherits from it (imageTestSketch in my case)

> 1>------ Build started: Project: openframeworksLib, Configuration: Debug Win32 ------
> 1>openframeworksLib.vcxproj -> D:\Work\OpenFrameworks\of_v0.10.1_vs2017_release\libs\openFrameworksCompiled\project\vs\..\..\lib\vs\Win32\openframeworksLib_debug.lib
> 2>------ Build started: Project: imageTestSketch, Configuration: Debug Win32 ------
> 2>   Creating library bin\imageTestSketch_debug.lib and object bin\imageTestSketch_debug.exp
> 2>libconcrtd.lib(UMSFreeVirtualProcessorRoot.obj) : error LNK2001: unresolved external symbol __purecall
> 2>libconcrtd.lib(VirtualProcessorRoot.obj) : error LNK2001: unresolved external symbol __purecall

and so on… and so on… ending with

2>libcrypto.lib(ec_pmeth.obj) : error LNK2001: unresolved external symbol _atoi
2>libcrypto.lib(rsa_pmeth.obj) : error LNK2001: unresolved external symbol _atoi
2>libcrypto.lib(ui_openssl.obj) : error LNK2019: unresolved external symbol _signal referenced in function _popsig
2>LINK : error LNK2001: unresolved external symbol __load_config_used
2>D:\Work\OpenFrameworks\of_v0.10.1_vs2017_release\libs\openFrameworksCompiled\project\vs\\..\..\..\..\\libs\boost\lib\vs\Win32\libboost_filesystem-vc141-mt-sgd-1_64.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
2>bin\imageTestSketch_debug.exe : fatal error LNK1120: 323 unresolved externals
2>Done building project "imageTestSketch.vcxproj" -- FAILED.
========== Build: 1 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

1 build succeeded and 1 failed…
So it looks like openframeworks module is built correctly, but the child project (any new project we create using OF project generator) doesn’t recognize it, moreover, complains about mixing 32bit and 64bit… (Of course, I want to compile 32bit (x86) for more compatibility, just as you managed to :wink: )

Now that we mention it, it is really odd that boost libraries even in Win32 version in the OF folder OpenFrameworks\of_v0.10.1_vs2017_release\libs\boost\lib\vs\Win32
, they all use this 64 in their filenames…

libboost_filesystem-vc141-mt-1_64.lib
libboost_filesystem-vc141-mt-gd-1_64.lib
libboost_filesystem-vc141-mt-sgd-1_64.lib
libboost_filesystem-vc141-s-1_64.lib

and this was default even before we copied the Boost static libraries from the sourceForge… I mean, is there any difference between 32bit and 64bit version of Boost libraries? Cos there weren’t any in the download site you provided…
Wondering how can the linker complain about it if it’s the same and if our generated projects inherit every library from openframeworksLib parent project by default…

Is there something I am missing? Are there any files (like libs or something) that need to be copied to my generated project, like into /src folder, or into /obj or into /bin?

#9

In VS2017 Configuration Manager, when building for x86, do you have it set to be all x86?

e.g. I have:

Active solution configuration: Release
Active solution platform: x86

DrazinutsExcitingProject
Configuration: Release
Platform: Win32 (i.e. x86 not x64)
Build: checked

openFrameworksLib
Configuration: Release
Platform: Win32
Build: checked

#10

Well… I’m not sure I know all there is to know about this either.

I see what you mean that SourceForge only seems to have binaries named _64.

However I see that in my OF lib folders, I have two subfolders:

C:\OF0.10.1vs2017\libs\boost\lib\vs\x64
C:\OF0.10.1vs2017\libs\boost\lib\vs\Win32

And they have identically-named libboost… files, all ending in …_64.lib, but some of them have different file sizes… and some have the same file size… which gives me more questions than answers, but I expect you need to have the files it is looking for in your …libs\boost\lib\vs\Win32 folder if you are building for x86.

What I have in my x86 folder is (size in kb):

876 libboost_filesystem-vc141-mt-1_64.lib
600 libboost_system-vc141-mt-gd-1_64.lib
6480 libboost_filesystem-vc141-mt-gd-1_64.lib
84 libboost_system-vc141-mt-s-1_64.lib
952 libboost_filesystem-vc141-mt-s-1_64.lib
548 libboost_system-vc141-mt-sgd-1_64.lib
5728 libboost_filesystem-vc141-mt-sgd-1_64.lib
84 libboost_system-vc141-s-1_64.lib
68 libboost_system-vc141-mt-1_64.lib
548 libboost_system-vc141-sgd-1_64.lib

And it seems to build static x86 files. I haven’t tested whether it blows up when run on an x86 machine yet…

#11

If you right-click each project in VS 2017 Solution Explorer, and go to Linker/Advanced, as for all the other hundreds of project settings, there is a matrix of Configuration x Platform versions of the settings, each of which can be messed up. e.g. having the wrong value in Linker/Advanced/Target Machine for the current configuration would possibly also give you linker errors.

#12

Hmm…

yeah, I did this before… Target Machine has to be MachineX86 for both OFlib and my custom project…

but anyhow I try, still linker errors… as in Debug Win32, so in release, with different output (40 unresolved externals this time) and this stuff…

1>------ Build started: Project: imageTestSketch, Configuration: Release Win32 ------
1>libboost_system-vc141-mt-s-1_64.lib(error_code.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease' in main.obj
1>   Creating library bin\imageTestSketch.lib and object bin\imageTestSketch.exp

mismatch… pfff… i set everything in Win32 release into /MT (Multihreaded static) and in Win32 debug into /MTd (Multihreaded static debug), this isn’t right - it should be ok…
But if the boost lib files are not identical for x86 and x64? I just copied the newest (i think newest cos they had number 90 as the highest of the boost version 1.4.1) libs into both \boost\lib\vs\x64 folder and into \boost\lib\vs\Win32… I have them practically identical (those I downloaded from SourceForge and copied into these folders)

You know what… Could you make a .zip file with these two folders with all its contents as you have it on your disk and upload it here somehow? I’ll just copy them anew over mine, and test it…

#13

Yes, will do…

1 Like
#14

Thanks for everything. I managed to build the project using static boost library, though only in release… and it gave some kinda funny line in output which I can’t say I understand… :smiley:

  LINK : /LTCG specified but no code generation required; remove /LTCG from the link command line to improve linker performance

Debug version (of the generated project, not OF Lib) still throws unresolved external symbols, and this time there’s no reason why… no mismatch between the target machines or version of lib boost or anything.
But at least release version builds up correctly and generates .exe file…

If you or anyone is interested why is that so, here I upload my build .log file to see the errors - mostly the libraries OF incorporates (as you can read about them in the about section of the OF page) give unresolved external symbols for my generated project.
Can’t say I understand much… but if anyone does, here’s the file…

imageTestSketch-log.zip (35.9 KB)

1 Like
#15

The linker error feedback could be a lot more informative, huh? (I think that means again that something is trying to link with the wrong file due to some setting/config issue that it doesn’t give us a clear pointer to.)

I’m glad you got it to work for static release.

I assume it works in dynamic debug, so you probably don’t really need static debug?

#16

yeah, that’s the point… In case static linking is needed, I guess people can debug with Multi-threaded debug DLL /MDd and release with static Multi-threaded /MT…

#17

Yes. I checked and I get problems too if I try to build multi-threaded debug (non-DLL), although mine shows thousands of LNK2001 unresolved external errors, which I guess we’re supposed to be able to parse as not having a .lib file with whatever name it might be expecting (but doesn’t tell us) in our libboost folder?