How can I force Visual Studio to use dependency library names I want it to? - c++

I've created a static c++ library in Visual Studio (2013) called "mylib.lib". It is multi-threaded (/MT) and I specify the "output file" under Librarian/General to be "$(OutDir)$(TargetName)$(TargetExt)" so I can name it without the "mt" Visual Studio wants to force onto the end of the file name just because I used '/MT'.
This project also links in several other dependencies so they're all in one giant "mylib.lib" file for consumption by using applications. These other librarys are "A.lib", "B.lib", and "C.lib". They are also built specifying the output name so as not to have "mt" on the end of their file names.
Now I want to consume "mylib.lib" in a C++ application that also uses '/MT' to build. The application links with that library and calls a single function within it. The application fails to link because it "cannot open file 'Amt.lib' LNK1104".
The application doesn't have a direct dependency on "A.lib" and that dependency is already contained in "mylib.lib" which it DOESN'T try to link as "mylibmt.lib". The seemingly arbitrary decision to apply the "mt" suffix in one case and not another is confusing.
What is going on inside Visual Studio's mind here? And is there a way I can tell it to NOT append "mt" onto certain libraries?

One way to accomplish this is to set "No default libraries" in the consuming application and then manually add every "additional" dependency in the Linker section. This requires tracing all the way down the dependency tree, but it does work.
The easier way to do it is add the desired libraries to the "Ignore specific default libraries" field under Linker|Input. For example, I added "Amt.lib", "Bmt.lib", and "Cmt.lib" to that field -- then added "A.lib", "B.lib", and "C.lib" to the "Additional Dependencies" field (also under Linker|Input).

Related

Libraries VS2015

Good evening
I'm trying to set up a development environment on my newly Boot-Camped Windows 10.
I know how to link the include/lib in VS. On my Mac all my external libraries and include files are at either:
/use/local/ or /opt/local/
I'm wondering whether there is an easy way to do this on windows, or are there a way to force VS to always look in a particular dir?
Cheers
VS has the concept of property sheets which basically are a predefined set of properties for your project. Every C++ project includes by default few property sheets and there's even a special property sheet called Microsoft.Cpp.[Platform].user where [Platform] is either Win32 or x64. By editing the contents of this file you can set the paths for all your projects (or other arbitrary values such as macros).
To edit these files do either of the following:
Make a new CPP project in VS. Go to View->Other Windows->Property Manager. This will show a new pane in the current window and from there you can find the property sheet and edit as you see fit. This approach has the benefit of being more user-friendly as VS provides some nice GUI. Here's one tutorial
Find the files themselves (they are located in %LOCALAPPDATA%\Microsoft\MSBuild\v4.0), open them using your favourite text editor and do your magic. The files are XML-based so it's not awfully difficult.

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.)

basic instructions on how to create a .sln with simple C++ library (no .net use) and C++ project using that library?

I am C++ beginner. I have a simple console project. with class files inside that use boost (.libs) and openCV (dlls). I want to put all my existing classes into some namespace and into seperate projects. So I need a tutorial on how to separate my application project and code library in visual studio enviroment inside one sln?
First you create a new W32 Project (and solution) for your new executable (exe or dll).
Choose save all (or else if something goes wrong, you'll lose everything).
After this you go to the solution explorer (in the right margin) and right-click on the solution-name (not the project). In the popup-menu choose Add->new Project.
Now you create a new w32 project (for a new library). In the Dialog that comes up you choose next and in the following page you choose static library (and some other options if want to). Now choose Finish and the new project will be added to the solution. Now choose save all.
Repeat these steps for all the libraries you want to create (and don't forget to save things).
You could build the solution now so that things exists.
Next you must add the libraries to your executable-project.
Go to the properties of that project and select All Configurations in the combobox in the left-upper corner.
Now select the linker option and in there choose the input option. Now choose the additional libraries option in the property-page and in there choose edit. In the dialog that pops up you can add all libraries-names you just created.
If you were to build now the linker will complain that it cannot find those libraries, so one more step is required.
In linker-options choose General and in the property-page there is a property Additional Library Paths. Here you must supply the path to all those libraries by choosing edit.
In the dialog that pops up there is a button Macros that supplies a large list of macros that you can use for specifing paths (like $(SolutionDir) and $(Configuration)).
expample : $(SolutionDir)\lib1\$(Configuration)
You could build the solution now and no errors of not finding libraries should come up.
EDIT ,NB: if there is no source compiled in the library the build will be successfull but no library will be made, so you need some code in it. Otherwise the library will still not be found.
Now there's one more step to take.
Your Libraries should supply header-files to use the libs but if you include them in your source the compiler cannot find them.
You need to add additional include directories to your executable-projects properties.
Go to the C/C++ option in the executable-projects properties and there you'll find the additional include directories and there you choose edit and supply the dirs containing the header-files you need.
expample : $(SolutionDir)\lib1
Now you're ready to go.
By the way, try one library at a time so you go through the process a few times, learning and getting experienced with it.
Hope this will suffice.

Building both DLL and static libs from the same project

I have a number of native C++ libraries (Win32, without MFC) compiling under Visual Studio 2005, and used in a number of solutions.
I'd like to be able to choose to compile and link them as either static libraries or DLLs, depending on the needs of the particular solution in which I'm using them.
What's the best way to do this? I've considered these approaches:
1. Multiple project files
Example: "foo_static.vcproj" vs "foo_dll.vcproj"
Pro: easy to generate for new libraries, not too much manual vcproj munging.
Con: settings, file lists, etc. in two places get out of sync too easily.
2. Single project file, multiple configurations
Example: "Debug | Win32" vs "Debug DLL | Win32", etc.
Pro: file lists are easier to keep in sync; compilation options are somewhat easier to keep in sync
Con: I build for both Win32 and Smart Device targets, so I already have multiple configurations; I don't want to make my combinatorial explosion worse ("Static library for FooPhone | WinMobile 6", "Dynamic library for FooPhone | WinMobile 6", "Static library for BarPda | WinMobile 6", etc.
Worse Con: VS 2005 has a bad habit of assuming that if you have a configuration defined for platform "Foo", then you really need it for all other platforms in your solution, and haphazardly inserts all permutations of configuration/platform configurations all over the affected vcproj files, whether valid or not. (Bug filed with MS; closed as WONTFIX.)
3. Single project file, selecting static or dynamic via vsprops files
Example: store the appropriate vcproj fragments in property sheet files, then apply the "FooApp Static Library" property sheet to config/platform combinations when you want static libs, and apply the "FooApp DLL" property sheet when you want DLLs.
Pros: This is what I really want to do!
Cons: It doesn't seem possible. It seems that the .vcproj attribute that switches between static and dynamic libraries (the ConfigurationType attribute of the Configuration element) isn't overrideable by the .vsprops file. Microsoft's published schema for these files lists only <Tool> and <UserMacro> elements.
EDIT: In case someone suggests it, I've also tried a more "clever" version of #3, in which I define a .vsprops containing a UserMacro called "ModuleConfigurationType" with a value of either "2" (DLL) or "4" (static library), and changed the configuration in the .vcproj to have ConfigurationType="$(ModuleConfigurationType)". Visual Studio silently and without warning removes the attribute and replaces it with ConfigurationType="1". So helpful!
Am I missing a better solution?
I may have missed something, but why can't you define the DLL project with no files, and just have it link the lib created by the other project?
And, with respect to settings, you can factor them out in vsprop files...
There is an easy way to create both static and dll lib versions in one project.
Create your dll project. Then do the following to it:
Simply create an nmake makefile or .bat file that runs the lib tool.
Basically, this is just this:
lib /NOLOGO /OUT:<your_lib_pathname> #<<
<list_all_of_your_obj_paths_here>
<<
Then, in your project, add a Post Build Event where the command just runs the .bat file (or nmake or perl). Then, you will always get both a dll and a static lib.
I'll refrain from denigrating visual studio for not allowing the tool for this to exist in a project just before Linker (in the tool flow).
I think the typical way this is done is choice 2 above. It is what I use and what I have seen done by a number of libraries and companies.
If you find it does not work for you then by all means use something else.
Good luck.
I prefer 2 configurations way.
Setup all common settings via 'All configurations' item in a project properties windows. After it separated settings. And it's done. Let's go coding.
Also there is very good feature named 'Batch build', which builds specified configurations by turn.
Multiple projects are the best way to go - this is the configuration i have most widely seen in umpteen no of projects that i have come across.
That said, it might be also possible to implement the third option by modifying your vcproj files on the fly from external tools(like a custom vbscript), that you could invoke from a make file. You can use shell variables to control the behavior of the tool.
Note that you should still use use visual studio to make the build, the makefile should only launch your external tool if required to make the mods and then follow that by the actual build command
I use Visual Studio 6.0 (Still) due to issues that are preventing us from Migrating to VS2005 or newer. Rebuilding causes severe issues (everything breaks)... so many of us are considering lobbying a migration to GnuC++ moving forward in a structured way to eventually get us off of licensed Visual Studio products and onto Eclipse and Linux.
In Unix/Linux it is easy to build for all configurations.. so I can't believe what a time and productivity sink it is to try and accomplish the same task in Visual Studio. For VS6.0 I have so far found that only having two separate projects seems to be workable. I haven't yet tried the multiple configuration technique, but will see if it works in the older VS6.0.
Why not go for version 1 and generate the second set of project files from the first using a script or something. That way you know that the differences are JUST the pieces required to build a dll or static lib.

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.