To simplify, suppose I have a situation where I have written two libraries, Lib1 and Lib2. Each library has one configuration: static (.lib) release Win32 (/MD). Each library has a property sheet (include_lib1.props and include_lib2.props, respectively). The property sheet for a given library:
Exports the path to the generated .lib under Library Directories
Exports the path to the library's source under Include Directories
Adds the name of the generated .lib to the linker's input requirements.
Dependencies:
Lib1 has no dependencies (i.e., it just includes Microsoft.Cpp.Win32.user).
Lib2 has one dependency: Lib1 (i.e., Lib2 includes both Microsoft.Cpp.Win32.user and include_lib1.props).
Now I want to write an application. Ostensibly, it depends only on Lib2--but since Lib2 was built using Lib1, the application wants both Lib1.props and Lib2.props* (i.e., it tries to link with Lib1.lib, and fails since Lib1's property sheet isn't there to say where to find it).
My question is: is there a way to make it so that when I include include_lib2.props, it automatically also includes include_lib1.props--or do something equivalent?
*This by itself is curious--the libraries are built with /MD, so could that be it?
The answer seems to be to just add one property sheet into another. Right-clicking on the property sheet allows you to add an existing one.
This very nicely solves the problem in a modular, clean fashion. The altered property sheet can be used in multiple places. Adding it to a new project recursively adds the depending property sheets, which can be viewed in the property pages.
Related
I do not understand how Xcode knows which headers should be included into which target? For example if I add a new File to my Xcode Project it adds the .m File to the compile sources of the selected targets but what about the .h files? How does my target know which header files should be used?
Only .m files and resource files are part of the targets, not .h. Headers only need to be copied for a framework target, and only because they are part of the framework release (they allow users to know how to use the framework). Apps don't need the headers because they're compiled stand alone entities. The headers (and the pch file) are used during compilation but aren't required at runtime.
You want files to be members of your target when they:
Form part of the executable (e.g. implementation (.m) files or libraries), or
Are included as files in the application bundle (e.g. images).
Just to give an example via screenshot, the way we control headers in Xcode for libraries is in build phase something like this:
You may further read out this Apple Documentation for setting the visibility of header files in Xcode.
I need to link library from one project into another, and it looks there are 2 ways, can you tell what is the difference and what is the consequence of having "true" in one setting and "false" in another (the same) setting?:
and another one:
What is the difference, and do I need both setting set to "yes" or just one and if so which one?
A one-line explanation would probably be that the second option specifies something about how the first one works.
Link Library Dependencies set to Yes: if the solution is set up so that the current project has a dependency on another project that produces a .lib file, then that file will be linked in automatically.
Use Library Dependency Inputs set to Yes: useful mostly in Debug builds, when Incremental Linking is enabled. Normally, if a .lib generated by another project changes, and the current project depends on it, the linker can no longer link the current project incrementally (it's difficult for it to know how exactly the .lib changed). If you set this option to Yes, then the linker doesn't use the .lib file generated for the other project, but rather the individual .obj files that were used by the librarian to generate that .lib (as if the .lib didn't exist, and every object file from the other project were given to the linker individually, alongside the .obj files from the current project). This enables it to continue linking incrementally.
As far as I can tell, Use Library Dependency Inputs only makes sense if Link Library Dependencies and Enable Incremental Linking are both also set to Yes, and the current project depends on another project that generates a .lib file that changes often during development.
Additional information here and reference docs here.
UPDATE based on the comment from the OP:
As far as I can tell, the property entry under Project Reference Properties specifies the setting individually for each referenced project (whether to use the .lib from that specific project or not), while the one under Linker - General is the default setting for referenced projects.
For example, if you set the one under Linker - General to No and add a new referenced project, then, for that project, the setting under Project Reference Properties will default to False. However, the settings for referenced projects that were added before keep their individual setting.
I expect the individual setting under Project Reference Properties to override the default from Linker - General, but I haven't actually tested this bit.
I'm using the boost library in several projects in my Visual C++ 2010 solution. What I'm currently doing is modifying each project's properties by setting:
Properties->Configuration Properties->C/C++->General->Additional Include Directories to include the boost directory C:\boost\boost_1_47
Properties->Configuration Properties->Linker->General->Additional Library Directories to include the boost lib directory C:\boost\boost_1_47\lib
Now that I'm upgrading my boost version to 1.51 I realize I'm violating DRY by specifying this information more than once (i.e., once for each project). I want to define the boost info in a single place.
After researching it seems like Property Sheets are a good solution. I've read about property sheet inheritance but I don't see how that's useful because it seems that if you want to add a project-specific include directory then you will have to set the Additional Include Directories in the properties for that specific project which will then override the inherited property sheet which defines the boost include directory. If I am wrong about this please correct me.
So my next thought is to create a single property sheet called GlobalMacros.prop and define a user macro something like $(BoostDir) and then add this property sheet to each project. Then I can use the macro in each project's properties when I'm defining include directories and library directories. However, when creating a macro there is an option "set this macro as an environment variable in the build environment" and I am not sure what that does or if I should set it.
Overall I want to know what is the best way to reduce repeated configuration definitions for common settings?
I'm actually the developer that originally implemented property sheets in Visual C++ back in VS 2005 (although I'm not responsible for the mess that is the VC++ project properties dialog). Caveat: I stopped working on VC++ after 2005, so below may not be entirely accurate for your version.
In the Property Manager, you should be able to multiselect all of your project configurations in all projects and add a new property sheet. This will automatically inherit those project configurations from the same property sheet. In that property sheet, set the boost include and library directories directly or use a macro for BoostVersion and BoostDir and use those macros in the property sheet's properties.
Provided that the project configurations have "inherit from parent or project defaults" checked (this controls inserting $(Inherit) vs $(NoInherit) in 2005/2008 and %(<propertyname>) in 2010/2012) for those properties, you should see any project-specific properties set in the project configurations prepended, by default, to the values in the property sheet.
You can confirm this by going to a project and checking the compiler's "Command Line" tab to see if the switches are what you expect.
Edit: note that there are two types of properties in VC++: "single-value" and "multi-value". An example of a single-value property is the compiler's warning level. The value on the command line for a single-value property comes from the first place in the property inheritance chain that specifies it, starting with the project configuration, then the property sheets, then the built-in default in the project system. An example of a multi-value property is the compiler's include directories. Multi-value properties get concatenated with their parent property sheets unless $(NoInherit) is specified (2005/2008) or %(<propertyname>) is not specified (2010/2012). Thus, by default, you should see the boost paths showing up in your project settings provided they have intentionally not inherited the property from the property sheet.
I am just approaching C++ development (from a C# background), and i am wondering what is the difference between Library Directories in C++ project settings (in Visual Studio):
and the Linker "Inputs" where i can also supply libraries:
Is there any fundamental difference between these?
This setting got fumbled a bit in VS2010, it was much clearer in previous versions. Where the settings you show in your screenshot were present in Tools + Options. Which shows the core intent, they contain directories that are determined by the setup for Visual Studio and its components. The locations of the CRT, MFC, ATL and SDK libraries.
The Linker + Input + Additional Dependencies setting is the important one, there you say exactly what .lib files the linker should link. You can specify the path of a .lib file and be done. But it is not uncommon that you only specify the name of the .lib file, then edit Additional Library Directories to tell the linker where to search for those .lib files. Which is handy if the install location for, say, Boost isn't always the same or you want to switch from one version of Boost to another.
So in summary:
Linker + Input + Additional Dependencies: add the .lib files you need to link
Linker + General + Additional Library Directories: only use if you didn't specify the path of .libs
VC++ directories: don't mess with it
Do note that the last two bullets only specify directories, not .lib files that the linker should link. The first bullet specifies actual .lib files. What is invariably confusing to starting MSVC programmers is that the linker magically knows how to find important .lib files without specifying them explicitly in the Additional Dependencies setting.
That's unfortunately the non-visual part of Visual C++. There are two distinct ways in which a project can specify .lib files that the linker should link without using the setting. The first one is the project template you selected to get the project started. It uses project property sheets, files that specify default settings for a project. You see them with View = Other Windows + Property Manager. An important one is "Core Windows Libraries", it sets the Additional Dependencies setting to link the essential Windows .lib files, the ones you always need like kernel32.lib and user32.lib. Those settings are "inherited" by your project. Otherwise giving meaning to "NoInherit" if you ever run into it.
The second important way is the #pragma comment directive. Which is used in source code, it injects a linker directive. The "lib" variety is important, that tells the linker to link a .lib file. In addition to what you explicitly specify in the linker's Additional Dependencies setting. A very good example of that one is vc/atlmfc/include/afx.h. Search for "#pragma comment". Note the macro soup that selects the proper mfc .lib file, depending on compiler specific settings. And the bunch of extra Windows .lib files an MFC needs to link.
The C++ build model is filled with a maze of twisty little passages. The IDE tries to make you fall in the pit of success but in the process hides what's important to get to the next level of understanding. It isn't different in C#, to know how to make the Reverse() extension method not consume O(n) storage requires digging in.
Most (not all) libraries come with two sets of files:
Header files are #included in the source code that's using the libraries, to provide declarations for functions, classes, constants or whatever else might be needed
Library files are binary code that contains the code of the library. These are used by the linker when it assembles the final executable
I'm working on a object-oriented Windows API wrapper library, written in C++, and I have two projects inside the solution:
The actual library project;
A "test" project, where I write code that uses the library for testing purposes.
My goal is to be able to include and use the library header files on the test project, as if it was an actual project that uses the library.
I solved the file inclusion problem by adding "$(SolutionDir)" to the test project's additional include directories (is there a cleaner way?), but I'm struggling to get the test project to link. I get unreferenced externals errors, which I assume is because the linker can't find the DLL.
I'm completely lost here. I have set up project-to-project references, so that the test project is dependent on the library project, but that did not solve the linking problem. I couldn't find any option in either project's properties that seemed to be relevant to my problem.
Is there a way I can simply hit "Build Solution" and then run the executable?
In your project's properties > Linker > Input, there's a bunch of settings you can specify for the linker, such as, for instance, additionnal dependencies to link with (put the .lib generated by your other project there) and which paths to look for said libraries.