Visual Studio tries to link against nested library dependency of static library - c++

I have a executable project, Game.exe, which is linking against a library Engine.lib. I want to link another internal library, Video.lib, into Engine.lib, so that Game.exe can simply link against Engine.lib and not worry about the symbols provided by Video.lib. This sort of linking setup makes the most sense for my current solution.
In the librarian tab of Engine.lib, I have included the path of Video.lib as well as the file "Video.lib" in the input section. This works perfectly and I have access to the Video.lib symbols.
My issue is when trying to link against Engine.lib from Game.exe. I am not sure if I changed some sort of setting in the Game.exe project, but when I try build Game.exe, I get a linking error that Video.lib cannot be found. How is this possible, when I do not have "Video.lib" under the inputs of Game.exe?
Adding the path of the Video.lib file (simply the path, not the file itself) to the Game.exe project solves this, but obviously the whole point of this setup is that Video.lib should be merged into Engine.lib so that I only have to link Game.exe against Engine.lib.
Is there a setting in Engine.lib I have to set that specifies all Video.lib symbols should be pulled into Engine.lib, instead of making it a dependency for future projects that link against Engine.lib? Or have I set something incorrectly in the Game.exe project?
I do not want to use Visual Studio's "project dependencies" or "references" system.
Thanks!
Edit: This post here (Linking static libraries to other static libraries) does not answer my question, as it is both outdated (doesn't really contain information about the new VS interface) and doesn't answer the issue I am having (why is Game.exe trying to link against Video.lib). Since my question is about this problem and the other question is simply a "how to" I therefore do not believe my question is a duplicate.
Edit 2: I am certain that Video.lib IS being linked into Engine.lib due to the noticeable increase in file size. What I don't understand is why Game.exe still complains about not being able to find Video.lib

The issue turned out to be with the library I was using specifically, which is wxWidgets (I simplified the example above in order to avoid complications).
wxWidgets uses #pragma comments to link specific libraries in. In this case, wxWidgets ("Video.lib") was causing Game.exe to "see" these pragma comments and ultimately attempt to link in the libraries.
Adding all the wxWidgets libraries ("Video.lib") to "Ignore Specific Default Libraries" under Linker -> Input in Game.exe solved the problem to me, as this ultimately overrode the pragma directives.

Related

Visual Studio "object file does not define any previously undefined symbols"

While using C++ in Visual Studio 2013, I've come across a really weird warning/bug thing.
I have a static library and a console application.
Static library imports 4 3rd party .lib files, and their headers.
Console application imports the static library and the headers of the original 4 .lib files, so that I can use the code from the original 4 .libs and my .lib.
(I think this is the right setup in this situation, if there is a better way, do tell!)
However, when I build the static library, I get a warning: "LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library" for each .lib imported.
But where is it getting the code if not from the libraries? If I remove the .libs from being imported, the build fails stating that it needs them! I don't know what to do in a situation like this. I would be happy enough to just leave the .libs being imported as is and ignore the warnings, but when I try to disable them (Under disable specific warning, "4221", in the compiler options), the warnings are not disabled!
Edit: The 4 3rd party .libs are standalone - they do not use each other's code so I do need to import all of them.
I am truly at a loss - any advice would be much appreciated.
I found a way of disabling the warnings using /ignore: on the linker command line, but I'm still confused as to why the linker gave the warnings in the first place, when removing the library as input caused multiple "unresolved external symbol" errors.
Oh well, problem (sorta) solved.

Issues with linking library C++

My problem is I am not able to include a library into my current project. [The way to include a library in netbeans into a project is to link it via linker to the project]. However, in my current project(which is written by another programmer who left the organization) the option of linker is not appearing. I have attached a screenshot. I am faced with the issue that the option of linking the library via linker to my current project is not appearing in IDE. Can someone please please help me out. I'll be highly thankful to you for the same.
Please guide me as to how should I link the library to my project. I have really spent a lot of days doing it but I did not succeed.
Assuming you are only interesting in libspatialindex:
Make sure you have the appropriate files installed: try a locate libspatialindex and see where it is installed. You could have a *.a, *.so or similar extension. Note the path.
Go into your project root directory, i.e: /home/keira/netbeans/projects/myproject
Try: gcc -i main.cpp -L/usr/lib/ -lspatialindex -o myfile
Replace the -L/usr/lib with the actual location where you know the library is at.
The cxx link flag is usually the name of the library with an -l prefix. If for example the name found in the system is libspatialindex.so then its a good bet to try with -lspatialindex.
There is a way to find the actual flags on Debian & Ubuntu systems but I cannot atm remember it. Alternatively you can always look on google or read the library documentation.
When you usually see linker errors with undefined functions, etc, it means you're not linking, provided you have included the headers and they are found.
Now for Netbeans, I assume there is the option of passing extra arguments to the compiler. In this case, all you need is the -lspatialindex flag, provided Netbeans knows where to find the library and the headers. That is how it works in KDevelop and other IDE's I have used.
Alternatively if you want more control and more automation, you may want use a tool like cmake.

VS2010 static linking issue

my company has recently upgraded from VS2005 to VS2010. We have a huge project which uses a lot of modules which are being linked statically into the exe. But there seem to be some issues with linking in VS2010.
To explain our problem, we've built a minimal example project which is composed as shown on this graphic:
There is an application using one function from library A. Library A calls one function of each library B and library C. Those two libraries call a function provided by library D.
For Exe 1 under Framework and References we set everything to false except for Link Library Dependencies which is set to true. The only reference added is linking to library A. For each of the libraries all the settings are set to false. Library A gets references to only B and C, as well as those two getting references to D only. Library D has no references.
When building the application it works without problems. The application notices that library A is using library B and C which are using library D, so it knows it has to link those libraries, too. The libs are linked into the exe without problems.
Now we change something in, let's say, library D. Just a little difference, only one letter. Now we try to build the application again, it notices the change and re-compiles library D, but: It doesn't link to it anymore. The result are linking errors in library B and C, because they use library D. We have to run Rebuild first, in order to force the complete building and then everything is linked again.
This happens for both the minimal example as well as for our main project. Of course, we can add each of the libraries as additional dependency for the exe but it would be nice if it would work just like it does when building the project for the first time and continue to work after changes in the code. We noticed that when setting Use Library Dependency Inputs to true, that it works again, but then it doesn't link the *.lib files but the *.obj files which is not what we want of course.
Has anyone made similar experiences or has anyone a solution for this issue? Is this a buggy behavior of VS2010?
TIA.
p.s.: All libraries and executables are native C++.
Edit: (Workaround taken from this site)
In the file %ProgramsFile%\MSBuild\Microsoft.cpp\v4.0\Microsoft.CPPBuild.Targets there is a line
<Target Name="GetResolvedLinkLibs" Returns="#(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets)">
If you change that line to
<Target Name="GetResolvedLinkLibs" Returns="#(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets);ResolvedLinkLib">
the linking works properly and all needed libs are linked to implicitly. The linker output not only shows lib_a.lib but also all other chained libs, lib_b, lib_c, lib_d without having them added manually as dependencies to the exe.
This seems to be more a workaround then a solution, maybe there is a proper way to achieve implicit linking.
Have a look at following links:
Visual Studio 2010 not autolinking static libraries from projects that are dependencies as it should be supposed to
Behavior of Link Library Dependencies in 2010
Unresolved Externals When Build a VC++ Project with Chained Static Lib Dependencies
Flexible Project-to-Project References
I only know that I had such similar situations because of wrong using of Libraries with same name but with different architecture. lets say, I have an Dll (lets call it mydll.dll) for x86 and will import it into my project it will work. If I will do the same with x64 dll (same name mydll.dll) it will work.
But if I want to include both libraries it is not allowed to only rename it into mydllx86.dll / mydllx64.dll. I CAN include now both libraries into Visual Studio. But when compiling it or restarting visual studio, one of both libraries will be unaccessable anymore.
In this case I perhaps it helps to have a look into library architecture and used namespaces / Api names.
Regards
You are pretty lost in that dialog if you are tinkering with Framework and References, those are settings that only apply to managed code. The term "reference" only applies to .NET assemblies. The linker doesn't support storing compiled managed code in a .lib. I'll work from the assumption that you actually are changing linker settings. If you make a change in library D then you also have to change its header file. Which in itself will be enough to get B and C rebuilt since one or more of their source code files should #include that header.
The only thing that Link Library Dependencies does is automatically make a .lib a dependency, same thing as Linker + Input, Additional Dependency setting. That however requires you to explicitly set the project dependencies. Right-click the B project, click Project Dependencies and tick D. Repeat for C. Repeat for A and tick B and C. Repeat for EXE and tick A.
This is rarely what you want, it makes the D library embedded into the B and C libraries. And B and C get embedded in A. The EXE now only has a dependency on A. It works, but it makes the .lib files unnecessarily beefy. And you have the problem you describe if you don't set the project dependencies properly, a rebuild of D doesn't cause it B and C to be relinked.
What you should do is not set dependencies between the .libs, they don't have any. Each can be built without the other .libs being present. A .lib is nothing but a bag of .obj files. All that's required is that you make all 4 .lib projects dependencies of the EXE project. That makes sure that they are built before the linker tries to link the EXE.
We starting seeing this issue again after moving to Visual Studio 2015 (and also in VS2017). The problem only seems to exist in the following configuration:
Project (EXE)
--> Static Library A (Reference)
--> Static Library B (Specified in Linker->Additional Dependencies)
--> Static Library C (Not in solution, specified in Linker->Additional Dependencies)
There are several other projects in the solution that use A and B. When something in project B or C changes, many of these projects give LNK4099 warnings.
In our case, the solution is to use the following:
Code Generation > Output Files > Program Database File Name: $(TargetDir)$(TargetName).pdb
Librarian > General > Output File: $(TargetDir)$(TargetName)$(TargetExt)
$(TargetDir) uses an absolute path versus the default $(OutDir) which in our case was relative. It seems that the correct path gets lost with multiple levels of indirection.
One interesting thing is if you switch the number of compile threads to 1, it doesn't appear to happen (maybe some kind of race condition within Visual Studio?).

MSVC - boost::python static linking to .dll (.pyd)

I got a VS10 project. I want to build some C++ code so I can use it in python. I followed the boost tutorial and got it working. However VS keeps to link boost-python-vc100-mt-gd-1_44.lib but it's just a wrapper which calls boost-python-vc100-mt-gd-1_44.dll. That's why I need to copy the .dll with my .dll(.pyd) file. So I want to link boost:python statically to that .dll(.pyd) file. But I just can't find any configuration option in VS or in the compiler and linker manual. The weirdest thing is I've got one older project using boost::filesystem with the very same config but that project links against libboost-filesystem-*.lib which is static lib so it's ok. I've been googling for couple of hours without any success and it drivers me crazy.
Thanks for any help or suggestion.
You probably don't want to do that. Statically linked Boost python has a number of problems and quirks when there are more then one boost python based library imported. "But I only have one" you say. Can you guarantee that your users won't have another? That you might want to use another in the future? Stick with the DLL. Distributing another DLL is really not that big a deal. Just put it side-by-side in the same directory.
What libraries are linked depends on the settings of your project. There are two possibilities: You can build against
statically
dynamically
linked versions of the c-runtime libs. Depending on which option is selected, the boost sends a proper #pragma to the linker. These options need to be set consistently in all projects which constitute your program. So go to "properties -> c++ -> code generation" (or similar, I am just guessing, don't have VS up and running right now) and be sure that the right option is set (consistently). Of course, you must have compiled boost libraries in required format before...

How do I find the dependencies on a dll :: GLUT specifically

I have been learning opengl for about 4-5 months now.
I am ready to stop using glut(a helper library that obfuscates many difficult / tedious aspects of opengl programming )
Problem is, I feel I have removed all refrences to glut.h, as well as all function calls within glut, but when I run my application it is still trying to link to glut32.dll.
Generally so I and others can learn for later,
How can I tell which libraries an excutable/source-code need and why(function/header wise), either before or after compile?
I am using VS2010 but cross compiling this on a linux box with g++
In this specific instance I don't have the dll listed as an additional dependency . But I do see glut.h in the extrenal dependencies folder...i just cant remove it
Thank you
Dependency Walker is your friend for examining the dll dependencies of compiled binaries.
The principal problem is of course, you have added glut.lib or glut32.lib to your project someplace. Its probably in the Project Properties > Linker Settings > Additional Libraries, or some source file contains a #pragma something like this :-
#pragma comment(lib, "glut32.lib")
Look at the linker properties for you project(s). The dll, or rather, the corresponding .lib should be listed there under "additional dependencies".
Edit:
By the way, including a header and linking a library (or a dll) are two different things. You may be including a header somewhere, but not linking to the corresponding library. In that case, the linker will give you an error. On the other hand, you may not be including the header, and not using the library at all, but you may still be linking to it.
In this case it seems like we have both. If glut.h is in the external dependencies folder then you must be including it somewhere in your code. Try using find-in-files to look for it. Or delete it from your system altogether and try to compile.
Every exe/dll has something called an Import Address Table (IAT) which is information stored in the PE (Portable Executable: window's executable file format) file's header about what dlls the loader needs to load when the module in question is loaded. You can use tools like PE Viewer or PE Explorer to view this information or write your own (this is more difficult). What you will see are libraries that are statically linked to your executable. If you don't see glut32.dll in any of those files, it is possible that it is loaded dynamically through LoadLibrary api in some other openGL library. I am not very familiar with openGL binaries, so I cannot confirm this for you.
If you have problems to find where glut.lib is hidden in the visual studio project options, open the .vcproj in a standard text editor and make a full text search.