What does the VC++ "Exclude Directories" project setting actually do? - c++

I am attempting to use the new VS2015 precompiled header refactoring tool. When I launch it, it pops up a message saying:
To improve recommendations, add third party library paths to the
'Exclude Directories' property under VC++ Directories (in the Project
Properties dialog).
I'm not clear on precisely what a directory is being excluded from if I list it here. All the MSDN help text has to say about it is:
Directories not to search when checking for build dependencies
That helps a little, but I'm still not completely sure about what functionality I will gain/lose if I list something here. Something like, say, boost (which the message from the pch tool seems to be suggesting). Can anyone say exactly what this setting does?

The general idea is that every time you hit 'Build' the IDE (or msbuild more specifically) has to check all the dependencies to see which cpp files need to be rebuilt. If you have a large project and many headers (boost being a good example) then this may have to check for thousands of headers (because each header also needs to have its dependencies checked).
If you have a third party library such as boost which is only updated very rarely then you can add the path to the Exclude box so that the dependency checker won't bother checking any of those libraries. However, if you do update the library at some point, or make a small change to it then you will have to manually rebuild all projects that relied on it, because you have told the build system not to do it for you.
In practice I've never found it to be a problem, even with a few MLOC project and a boost installation, especially if you're building with an SSD. If you're on older hardware then it may be worth using, but I think it may cause problems when you inevitably forget to rebuild dependent projects.

Related

How to setup a GUI in C++

I'm a beginner when it comes to c++ and overall including libraries, so I spent the good part of my last 3 days trying to install various GUI libraries and trying to make them work with Visual Studio, but none of these tries were successful.
It comes down to the problem of having to include the files and link the libraries. It seems, at least to me, extremely tedious and time consuming having to copy paste everything in those boxes in Visual Studio.
I need a helping hand to figure out what I'm doing wrong, here is how I tried:
Visual Studio 2017 - gtkmm library with the windows installer
I download the required Gtk+ and install it successfully.
I open the properties of my project, go to the includes and paste the required paths. I go to the linker and proceed to paste those paths.
Accept,try to paste a hello world program with the includes -> everything is underlined with red.
And this isn't even the actual gtkmm implementation.
Now my question is, did I forget a step or is it just the basic snippet that doesn't work (I'll spare you from posting it).
What do I do, when the tutorial for the library tells me to include 2 or 3 files whilst I have like 20 in my folder?
Also, is it somehow bad practice to place the libraries onto a different drive?
Sorry if I sound lost, but that's pretty much how I feel in those tutorials..
Edit, just in case, this is the snippet I'm referring to:
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
g_printf("GTK+ version: %d.%d.%d\n", gtk_major_version,
gtk_minor_version, gtk_micro_version);
g_printf("Glib version: %d.%d.%d\n", glib_major_version,
glib_minor_version, glib_micro_version);
return 0;
}
g_printf, glib_major_version, glib_minor_version and glib_micro_version are red underlined, but not gtk_major_version
EDIT:
Thank you for the suggestions and the in-depth tutorial although questions like this don't fit stackoverflow.
Can you tell me how to include huge amounts of header and lib files when they are in many folders? Do you I need to access all folders manually and include them?
Yes, you undoubtedly missed a step in Visual Studio. No, its not bad to install it on another drive.
The general idea is:
1) Install the library somewhere on your machine. Doesn't really matter where. Take note of the "lib" directory and the "include" directory paths.
The include directory contains header files which allow your code to understand the forward declarations of the code your trying to use.
The lib directory contains the binaries (dll for dynamic linking, lib for static linking). Sometimes there are different binaries for release/debug. I'd link the debug library and worry about the release code when you get there
Note, sometimes they want you to compile the code yourself and create the binaries. They will include compile instructions. After you create the binaries you can go back to step 1 here and repeat the steps. This is because they either don't want to precompile binaries for your platform or their project philosophy is to do it yourself.
2) In Visual Studio you have to tell the compiler (separately) where the new additional include and library directories are. On 2017 that is...
Include Directory: Project > {Name} Properties > C/C++ > General > Additional Include Directories
Library Directory: Project > {Name} Properties > Linker > General > Additional Library Directories
3) Now include the libraries (binaries) themselves. On 2017 that is...
Library Binaries: Project > {Name} Properties > Linker > Input > Additional Dependencies
They should provide you a list of binaries to include in the project if there are external dependencies or they have broken their project up into multiple libraries for modularity.
If you want to program in C/C++, this is a process you're going to go through again and again. Its a bit arcane, but once you get it down, its not going to surprise you.
Edit:
Oh, and as an aside, people have mentioned Qt. This framework is a little different in regards to Visual Studio. Its very involved to set up the dependencies yourself because they have included language extensions and a tool for creating GUIs. For this reason, there is a tool (which is quite nice) for creating Qt projects from a template. This sets up all the compiler steps, includes, and linked libraries for you.
In my opinion its probably the best and most mature of the GUI libraries for C/C++ on Windows and is also cross platform.

How to obtain statically linked dll dependencies automatically

When creating new projects I've always stumbled upon the issue that my final executable or dll does not properly run because it is missing dependencies I was using.
In my live as a developer I've seen several approaches to handle that (of which I don't like any)
Set environment path to all those dependencies so that the OS can find them (bad, since very unportable, requires environment, won't work out of the box)
Copy every dependency of a potentially large package into the binary output directory (e.g. dozens of dlls regardless of need). For dependencies like OSG, Qt, etc this is quite odd as you typically won't link all dlls provided by larger packages and you may end up copying much more data than necessary.
Hand-Pick single dependencies (and optionally their pdbs) with a fine-grained xcopy/robocopy or whatever task. (Don't like that as it needs attention, I add a dependency in Visual Studio and then I need to adjust some script). There are tools like dependency walker which help this, but still, this might still be unportable because your include path in VS may have a version in it, if you change that, you need to change it also in the script, which is too much Department of Redundancy Department
In larger projects or companies I would expect this issue to be quite common. Is their nothing in Visual Studio or in Windows that aids that? I need to pick my include paths and import lib paths properly in order to compile a binary but then I need some other mechanism to actually make things work.
I am thinking about solving this problem in a more general way for more projects but really wonder if I am missing something.

What is a good way to set Preprocessor values for an imported library

I apologize if this is covered elsewhere, but I was unable to find the information readily. I am working with an extant library for my company that uses pre-processor directives to add and remove specialized capabilities. For example, we might have a IMPORT_OPENBLAS and IMPORT_SPEEX to indicate that the build needs to support use of the OpenBLAS and Speex libraries. We also have unit tests based off of the Google test framework, some of which need said pre-processor directives enabled to run, which statically link in our library. The two places where we typically run the unit tests are through Visual Studio (2008 if that makes a difference) and through Ant, which invokes vsbuild.exe to do the build.
So, long story short, I have been tasked with adding additional capabilities such as the above libraries. We have other projects that use our library and specifically don't want those capabilities turned on, in part due to issues with dependencies and in part because they don't want the additional complexity. My first impulse was to put the preprocessor directives into the unit test project, since it builds our library as a dependency anyhow, but that doesn't seem to work. Is there any way to flag things to indicate that a given pre-processor command needs to be turned on for compiling the dependent project?
Another alternative is to create new build targets for the unit tests which specifically set the right pre-processor flags, but I want to avoid that if possible because we already have 10 different build targets encompassing different linking methods, processor size, and debug versus release modes and one of my earlier tasks involved getting them all to work again since no one had compiled some of them for months since our primary release is based off of just two of those targets.
Thank you for any help you can provide.
You could simply have a header file that includes those defines and include it in all the files in the project through the project properties. See the project properties -> Configuration properties -> C/C++ -> Advanced -> Force Includes.
In other words, this file would be included in all the projects.

How can you Call a method from a diffrent Project, both in C++?

I'm normally working in c# so certain things in c++ keep confusing me alot (they seem so diffrent yet the names almost the same)
I created a Console project in which i want to run a diffrent project for testing purposes. i added the project as a reference to the console app, and then got kinda stuck.
there is no namespace in the projects, so i can't do a using and if i try to include the other file, it cannot find it (and i want to avoid being unable to debug through it all).
the code for the class can be found here(ignore the c# part), the console is just a standard console with nothing in it yet.
Yeah, C++ doesn't have the notion of assemblies that exists in C# and .NET. It makes tasks like this slightly more difficult, a virtue of the fact that C++ compiles directly to native code.
Instead, you'll generally #include the necessary header files (*.h) at the top of your code file, and instruct the linker to link to the appropriate .lib file(s). Do that by going to your project's Properties, selecting Linker -> Input, and adding the file to the "Additional Dependencies" section.
As an alternative to linking to the .lib file, you can use Visual Studio to add a reference to the other project, if it's part of the same solution. Microsoft has a walk-through on creating and using a dynamic link library in C++ that might be worth a read.
I'll assume you're using Visual Studios:-). You have to tell
the compiler where to look for its includes. Under Visual
Studios, open the properties page for the project, then go to
Configuration Properties->C/C++->General, and add the necessary
directories in the entry Additional Include Directories. (If
the other project is in the same solution, use a relative path.
But I think the dialog box that pops up when you click on the
button on the right does this automatically. I'm not a great
fan of all this GUI stuff in general, but Microsoft seems to
have done this particular part quite well.)
Once you've done this, you might have to go through a similar
process for linking: this time it's under Configuration
Properties->Linker->General, and the entry is called Additional
Library Directories, but the principle is the same. (This may
not be necessary, if you're putting all of the dll's and
executables in the project in the same directory.)

Complex builds in Visual Studio

I have a few things that I cannot find a good way to perform in Visual Studio:
Pre-build step invokes a code generator that generates some source files which are later compiled. This can be solved to a limited extent by adding blank files to the project (which are later replaced with real generated files), but it does not work if I don't know names and/or the number of auto-generated source files. I can easily solve it in GNU make using $(wildcard generated/*.c). How can I do something similar with Visual Studio?
Can I prevent pre-build/post-build event running if the files do not need to be modified ("make" behaviour)? The current workaround is to write a wrapper script that will check timestamps for me, which works, but is a bit clunky.
What is a good way to locate external libraries and headers installed outside of VS? In *nix case, they would normally be installed in the system paths, or located with autoconf. I suppose I can specify paths with user-defined macros in project settings, but where is a good place to put these macros so they can be easily found and adjusted?
Just to be clear, I am aware that better Windows build systems exist (CMake, SCons), but they usually generate VS project files themselves, and I need to integrate this project into existing VS build system, so it is desirable that I have just plain VS project files, not generated ones.
If you need make behavior and are used to it, you can create visual studio makefile projects and include them in your project.
If you want less clunky, you can write visual studio macros and custom build events and tie them to specific build callbacks / hooks.
You can try something like workspacewhiz which will let you setup environment variables for your project, in a file format that can be checked in. Then users can alter them locally.
I've gone through this exact problem and I did get it working using Custom Build Rules.
But it was always a pain and worked poorly. I abandoned visual studio and went with a Makefile system using cygwin. Much better now.
cl.exe is the name of the VS compiler.
Update: I recently switched to using cmake, which comes with its own problems, and cmake can generate a visual studio solution. This seems to work well.
Specifically for #3, I use property pages to designate 3rd party library location settings (include paths, link paths, etc.). You can use User Macros from a parent or higher level property sheet to designate the starting point for the libraries themselves (if they are in a common root location), and then define individual sheets for each library using the base path macro. It's not automatic, but it is easy to maintain, and every developer can have a different root directory if necessary (it is in our environment).
One downside of this approach is that the include paths constructed this way are not included in the search paths for Visual Studio (unless you duplicate the definitions in the Projects and Directories settings for VS). I spoke to some MS people at PDC08 about getting this fixed for VS2010, and improving the interface in general, but no solid promises from them.
(1). I don't know a simple answer to this, but there are workarounds:
1a. If content of generated files does not clash (i.e. there is no common static identifiers etc.), you can add to the project a single file, such as AllGeneratedFiles.c, and modify your generator to append a #include "generated/file.c" to this file when it produces generated/file.c.
1b. Or you can create a separate makefile-based project for generated files and build them using nmake.
(2). Use a custom build rule instead of post-build event. You can add a custom build rule by right-clicking on the project name in the Solution Explorer and selecting Custom Build Rules.
(3). There is no standard way of doing this; it has to be defined on a per-project basis. One approach is to use environment variables to locate external dependencies. You can then use those environment variables in project properties. Add a readme.txt describing required tools and libraries and corresponding environment variables which the user has to set, and it should be easy enough for anyone to set up.
Depending on exactly what you are trying to do, you can sometimes have some luck with using a custom build step and setting your dependencies properly. It may be helpful to put all the generated code into its own project and then have your main project depend on it.