1

I have an application project (MyGame) that want to access everything inside a static library (MyLib) in the same solution:-

MyVisualSolution
- MyLib (static library)  : 200  .h & .cpp
- MyGame (win32 app)      : 100  .h & .cpp

The steps to achieve the above requirement are :-

  1. set project property of MyGame > add additional include directory = .h folder in MyLib
  2. In Solution Explorer, click References of MyGame, then click the check-box MyLib.

I have to do both steps, and the settings are in very different places.
I think it is tedious, dirty, not intuitive, and error prone.

Is there any way to do it in a single place inside Visual Studio?
I expect to do just one thing that is similar to the second step.

(I feel that property sheet may be the closest answer, but it still can't solve.)

As far as I searched, there is none. (visual c++: #include files from other projects in the same solution)

Community
  • 1
  • 1
javaLover
  • 6,347
  • 2
  • 22
  • 67

2 Answers2

1

In general, that is normal. In C++ a "library" consists of a .lib/.dll and a .h./.hpp pair, and you need them both. Due to the fact that compiler and linker are in fact a different tools, you have different configuration settings for them.

Actually, to be able to use an external library, you need to configure not 2, but 4 things:

  • add an entry to include-search-paths and/or make sure that .h file is there (in project properties)
  • add an entry to library-search-paths and/or make sure that .lib file is there (in project properties)
  • include .lib file in linking by adding it to the linker options (in project properties)
  • include that .h with an #include with proper relative path (in code)

However, it is somewhat true that there is a way to provide something like one point of 'inclusion', so at least the last two can be merged.

There is a

#pragma comment(lib, "foobar.lib")

(What does "#pragma comment" mean?)

instruction that may be a hint to the toolset saying which .lib file to include. If you put that into the header (in this case, probably foobar.h), then just the fact that you #include that header, will make the build process pickup that lib and add it to linking phase..

..or so is the theory. As you may notice, that's a #pragma, and also a comment, so the process can simply ignore that or may simply not have that part implemented and that's 100% OK since it is not required by C++ standard. Fortunately, VisualStudio has support for this - actually iy understands that directive since a long time.

But! as I said, adding that directive is not enough. This directive only contains the filename, and it links the .h file with a .lib filename. You still need to ensure that the .lib is located somewhere in the library search paths, and that the .h file is somewhere in include search paths. If your linker settings point to some directories, you need to ensure that the lib file has been put in one of them, or else you will have to add the directory path to the settings, and similarly for .h/.hpp file.

That's relatively simple to overcome, just create an extra folder in your project, add that path to the search paths, and from now on, drop all additional .h/.lib files there.

If I may, I'd suggest something like ./3rdparty and subfolders for specific libraries, like ./3rdpart/xml', './3rdparty/zlib and so on. Add the `3rdparty' to both search paths and then, #include 'xml/tinyxml.h' etc. Otherwise you can get a filename clash. Of course, most of the libraries will actually not come with #pragma-comment-lib, so that part you will probably need to manually add.

Community
  • 1
  • 1
quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
  • That is not a good news - I have to maintain an annoying flag in my code + some limitation, but thank! – javaLover Mar 29 '17 at 07:26
  • 1
    @javaLover: yup, That's why that #pragma is not widely accepted. Microsoft added that only so that you can #included or #include etc and the toolset will link to the "standard" parts automatically.. it's not a replacement for standard .h/.lib/paths configuration – quetzalcoatl Mar 29 '17 at 07:30
1

This is maybe not a full answer but too long for a comment: we have multiple projects which each have with multiple static and dynamic library projects and multiple applications. To minimize configuration we settled for a having a clear project structure, a couple of conventions, and common property sheets for all projects which enforce said structure and conventions. It took a while to set this up but in the end it's worth it.

Project structure (simplified) is:

maindir \
        _bin \
        _lib \
        build \
               paths.props
               linker.props
               compiler.props
               default.props
               maindir.user.props
               autolink_template.h
        projectA \
                  projectA.h
                  autolink.h
        projectB \
                  tests \
                  projectB \
                           projectB.h
                           autolink.h

_bin is where all dlls/exes go. We might either use subdirectories per platform/configuration combo or else use postfixes on output names like projectA_x86d.exe for Debug|Win32 builds. This is all setup in property sheets (our projects basically never have any modifications to settings, they just contain the source/include files and import property sheets from the build directory)

_lib is where the import and static libraries go. Again, either with subdirectories or with postfixes on the names.

build has all common property sheets. A normal project just includes default.props which automatically figures out whether an exe/lib/dll is built based on $(ConfigurationType) and includes other property sheets according to that. There are property sheets for setting output paths to _lib and _bin, search paths so the _lib directory is found by linker, adding maindir to include search path, even things like setting file versions based on git hash etc, ... If a .user.props is found it is also imported, this allows custom settings related to maindir.

For the include files we always use #include instead of just . Imo this is clearer and reduces chances of name clashes. If a project has seperate tests/source directories like projectB, maindir.user.props is adjusted to add maindir/projectB to the include path so we can still just use #include

For setting up linking there's an autolink.h in each lib project which has a #pragma comment(lib, "projectA.lib") (created from a template in the build dir) so to link to that lib another project just has to #include .

Now this may be overkill for you but you might get some ideas which work well for your particular situation.

stijn
  • 34,664
  • 13
  • 111
  • 163
  • If I use `#include "MyLib\B.h"` instead of just `#include "B.h"`, how should I refactor if `B.h` is moved to some different directory? .... Do I have to edit a lot of code file that have that `#include`? I always avoid the problem using Property-Sheet + `#include "(.\)B.h"`. That requires me refactoring only Property-Sheet. Find-replace/Notepad++? – javaLover Mar 31 '17 at 02:14
  • Yes if you rename your project and move B.h you have to update includes using find/replace in your tool of choice. Just like when you rename B.h or move it to a different subdirectory. However: how many times do you rename a project? – stijn Mar 31 '17 at 07:31
  • The point is that it such a good *feeling* to know that I can rename project easily. By the way, I just notice that you had *effectively* solved this question long time ago. Thank! (.prop inside .prop + add reference inside .prop) – javaLover Mar 31 '17 at 12:29