How to manage C++ dependencies - c++

I am fairly new to the C++ dependency management through libraries and dlls.
I fully understand the difference between static and dynamic linking(I guess) which is why I am asking this, as common answers usually relate to issues with not understanding the difference.
I'm using visual studio and my current project is set up like this:
Bridge project: this is a dll project that exports a few classes. This serves as a shared library for bridge between networking code and application code.
Naturally, it has its own dependencies (ZMQ network library, MsgPack serialization, ...) which are statically linked (using .lib files). My .dll is generated normally and it's exported .lib file too. (Before I switched to dll project I kept compiling it as .exe to test the code as I coded...)
App project: This project is an application project and would like to use the bridge to gain full access to networking functionality via bridge. So I add the .lib dependency to it and I know I will have to supply the .dll to the .exe
However my problem is, that the application will not compile, because it is missing header files from ZMQ(which are a bridge .dll dependencies, and not relevant to the app at all, since only bridge internal BL uses them).
Is there any way I can "bake"/include all my required dependencies to the bridge dll (ZMQ, MsgPack, Log4cpp ....) and provided -just- the bridge.dll to the app (ofc, with bridge.lib as a library input)?
Am I misunderstanding something obvious here and am going at this completely the wrong way?
Thanks for help, greatly appreciated :)

I solved the issue so I am gonna write up an answer to my problem.
Many thanks to all that helped, especially #Öö Tiib, #Joachim Pileborg.
The problem was that I included "private" libraries in my public bridge library. (I included "zmq.h" in bridge.h).
Since my header file does not contain anything from that library I have moved the "zmq.h" include to the bridge.cpp file.

Related

How do you add a C++ project reference in Visual Studio?

In C# it's pretty simple to add a project reference that will build the dependency, put the resulting assembly in the original's Debug/ directory and properly compile against that assembly.
So at the moment, I have a project with the Main() and a static library project in one solution. However, when I compile the Main() project and I look in the bin/Debug/ directory I don't find either the Static.lib file or the .obj files, which I think would need to be there, or something... I'm getting linker errors.
I think maybe I have to Configure the project to find the .obj and the .lib file produced by the static library project (which compiles fine, and actually produces those files.)
I'm missing something, and I'm not very well versed in Visual Studio with C++.
How do I add the reference in the Main project to use the library produced by the static library project?
The first thing you'll have to unterstand is, that static libraries are nothing like .NET assemblies. They are linked into the .exe and are not distributed as separate entity.
Your linker errors are most likely a result of you not linking to the library.
There are several ways to define libraries that have to be linked.
One is int the project settings under linker -> input -> additional dependencies,
the other would be the cheap route via #pragma comment(lib, "path to library")
You can add the name of the .lib files you need by going in project property->Linker->Input->Additional Dependencies
Then you will have to give the folder where your library is in VC++ Directories->Library Directerories.
Here is a very comprehensive answer: visual c++: #include files from other projects in the same solution
It describes the settings for the linker but also other essentials when referencing another C++ project. (especially when coming from C# but not being too versed in C++)
In .NET, one of design goals was due make this process a lot easier and automatic. Mission accomplished there.
In the native C++ world, the process is much more manual. Here is roughly my process for hooking up different modules together.
Include all relevant modules in the solution.
Set the output
directory of each project to the same directory. Either Right click
on each project, choose properties and in general, set the output
directory to: $(SolutionDir)\Bin\$(Configuration)\$(PlatformTarget).
For reduced headaches, Set this for all configurations and platforms.
Then all the files will be placed in somewhere like
\your-solution\bin\Debug\x64.
Set the project dependencies - Right click on each project that will be linking to another -> Choose Build Dependencies and select the referenced projects.
Set up the linking process, by Right clicking on the calling project and choosing
properties. Go to linker -> Input and add: $(SolutionDir)\Bin\$(Configuration)\$(PlatformTarget)\MyLibrary.lib
For the actual functions that are going to linked to, I set the
function declarations to something like (There are a lot of variations on the function declaration, a bit outside of the scope here):
#define DllExport __declspec( dllexport )
extern "C" void DllExport WINAPI` Testing();
In actual cpp file of the calling function, I add something like the following:
#include "..\MyLibrary\mylibrary.h"
Then in the actual calling function. simply add called function:
Testing();
If you are building multiple projects in the same solution, use a project reference to automatically link your libraries and executables together:
https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-items?view=vs-2019#projectreference
which is explained pretty well here:
https://milania.de/blog/Project_references_in_Visual_Studio_and_C%2B%2B
The advantage to this approach, is that the build order will be correct. Using Additional Dependencies, as suggested in the other answers, will not maintain the proper build order.

.lib linking other .libs

Currently my visual studio is basically generating Engine.dll and Game.exe
Engine.dll links to some other basic libraries like:
d3dx9d.lib
ComCtl32.lib
WinMM.lib
WSock32.lib
etc.
I also wanted to try to create an Engine.lib, but I get some really nice warnings now: Symbol x has been defined already. These libraries define the same symbols.
So I read somewhere that I must force my user (Game.exe) to link to the libs instead. But this is just really inconvenient I think, especially if I have many games and I decide to add another library to my engine. It's just maintenance for something so simple.
Should I stick to the .dll, or is there some way to fix this beauty up?
Thanks a lot,
Antoon
You need to make up your mind whether the want the DLL or the static link library. Advantage of a DLL is that the build times can be quicker if you make local changes. Advantage of a .lib is that you'll end up with only one deployable file.
Getting it linked (either the static .lib or the dll's import .lib) is otherwise automatic. You want to make sure that the library is built first, can't link the .exe without it. Right-click the exe project in the Solution Explorer window, Project Dependencies, tick the library project. That automatically adds the .lib to the exe project's additional dependencies.
Using #pragma comment(lib, "engine.lib") in the engine's header file is another way. Repeat for other dependencies like the OS import libraries. Getting the library path right is a // todo item.
Did you create a different namespace to avoid naming clashes?
EDIT -- seems like there is some confusion as to what you're asking, because you are asking a couple of questions.
To me, it sounds like you want to take a stab at implementing your own Engine class. However, you've got naming issues. I am treating this as more of an architectural question now. If you write your Game to an interface, then the problem goes away. For example, if your Engine is using different algorithms, then if you had written an EngineInterface that the current Engine and YourEngine implemented, then you could easily use Strategy to flip between the different implementations on the fly. This is nice because you'll be able to see the differences in-game if you wire the preferences into the app.
If the symbols are not supposed to be the same, use diferent names or control how they are exposed. Another option is the usage of namespaces to avoid naming conflicts.
If the symbols are supposed to be the same thing, you need to define those only once in one of the libs.

C++, Qt - How do I get rid of dll dependencies?

I have compiled my Qt application and now have the following question - now my built project requires QtCore4.dll and QtGui4.dll to be located at the same folder where the .exe file is. (I built my project using MSVS2008 with Qt addon)
Q:
Is there any way to combine my final application with these .dll files so that they make one large .exe-file? (I simply don't want to have another bunch of dll files with my release - app)
Thank you.
You need to build and link to Qt statically.
Edit: Here's an updated link to at least similar information.
Bundle them into a self-extracting .exe (e.g. using 7zip) which extracts all files to a temporary directory, runs the program, then deletes the files after the program exits.
This will be easier, less time consuming and less legally constraining than statically linking Qt as previously suggested.
Of course you could statically link someway. But the point of using DLL should be to make program smaller (both on disk and in memory, if other apps are using Qt libs of course)... DLL such as those should be systemwide so that other apps needing them can use them. Basically you have to say to people wanting your program to work, to install the Qt framework.
Deploying the other way is explained here, read the part related to Static Linking.

Visual Studio: Link executable

Lets say I have:
a static library project called "LIB"
a application project called "LIBAPP"
a application project called "APP"
a application project called "APPTEST"
When i add "LIB" to LIBAPP Project Dependencies, Visual Studio automatically links "LIBAPP" against LIB.
But when i add APP to APPTEST Project Dependencies, it doesnt.
Since i am doing unit tests of APP's classes in APPTEST, i have to link against APP, therefore i am currently manually linking against all *.obj files of APP (hundreds...)
Since i have to change the link targets of APPTEST everytime i add or remove a *.cpp file from APP, this isnt a nice solution.
So is there a way to force Visual Studio to do this for me automatically, like it does when adding a static library Project Dependency ?
You can't "link against APP", as you've discovered.
One solution is to put all of APP's code into its own library, leaving APP as single source file that runs a function in that library. The you can make APPTEST another single source file that links against the new APP library.
Making an application depend on another is useful for causing both apps to both be build (if necessary) when you hit Compile. If you have enough code in APP that you feel that you need to write unit tests for them, I think it would be best to break this code out into another library, and call it something like "LIBAPPUTIL" or some-such which depends on LIB, and APP will have to depend on both LIB and LIBAPPUTIL.
You have noble intentions. By putting the parts of LIBAPP into a separate library, you get a bunch of benefits:
You can build variations of LIBAPP that have different void main()s
You can build several LIBAPPUTILs, each of which test usage of different sets of dependent code.
You can have alternate implementations of LIBAPPUTIL that do not depend on LIB. If you're smart with how you use interface types (either C++ virtuals or C structures full of function poointers) you can completely abstract away APP's dependency on LIB.

How to link a .DLL statically?

We have a (pure native C++) .DLL that is build by VS. As clients we have some native C++ applications and a .Net-Wrapper around this DLL written in C++/CLI. Finally there are some client applications for the .Net-Wrapper written in C#.
My problem is that the native.dll must be distributed in a different way than the .Net world works and the VS does not keeps track of that DLL.
So to let all my C# Apps work correctly I have to copy it to each executable directory or put it somwhere in %PATH% (which I would avoid on developer computers since they may want to start different apps with different versions of the DLL).
Even bigger problems occur if there are UserControls that reference the Wrapper-DLL: You have to copy the DLL to VS's directory or again to %PATH%.
But the worst case occurs with our Translator tool. This tool keeps track of .Net-Assemblies and packs them into Translator-packages that can be send to an external translator. As far as I know there is no way to put the native .DLL into that package!
So I plan to link the native DLL statically into the .Net-Wrapper which would solve my problems.
But for our Native applications this native DLL must still be a DLL.
So I have two options:
Make two projects of that (one that generates a static library; and one that creates a dynamic one => I try to avoid this)
Find a solution to link DLLs statically
Find a way to let VS generate two outputs from one project
In the C++ project file for the dll, create two configurations, one that generates a DLL and one that generates a .lib. Two projects are not necessary, since any .NET/C++ project can support multiple build configurations (this is how Release and Debug versions build differently).
Another option is to have two projects, one project will output a .lib which can be statically linked, and a second project which will output a .dll and will have your .lib as dependency, you should add .def to your .dll with the symbols that you are planning to export, or else it will be empty.
Pick up a copy of DLL to Lib (Edit: If you can't find a cheaper option)
You can generate a dll and export the entry point to a lib using dllexport, this is explained here
http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx