I'm trying to create a program (C++) that can read multiple file formats, on Windows (VS2015).
In order to do that, I created a solution with a Project for MyProgram (which is the main program), and a project for MyLibrary (which contains several parser for different file formats).
In MyProgram I create some parser objects based on the program input.
Everything was working well.
However, I tried to create a new file format parser (NiftiParser) that uses an external library, nifticlib, that I downloaded and compiled (as static library).
So I created my NiftiParser class, that implement some methods, and internally, it calls nifticlib.
I added the include dir and library dir in the project properties, and it compiled without errors.
I then got a Parser.lib that has been created.
However, when I tried to compile MyProgram, I got an error about some functions of nifticlib library not being resolved:
1>------ Build started: Project: Parser, Configuration: Debug x64 ------
1> Parser.vcxproj -> C:\Users\Laurent\Documents\C++-build\Projects\Parser\Debug\Parser.lib
2>------ Build started: Project: MyProgram, Configuration: Debug x64 ------
2>Parser.lib(nifti_parser.obj) : error LNK2019: unresolved external symbol nifti_image_read referenced in function "public: __cdecl NiftiParser::NiftiParser(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0NiftiParser@@QEAA@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
2>C:\Users\Laurent\Documents\C++-build\Projects\Debug\MyProgram.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 1 succeeded, 1 failed, 3 up-to-date, 0 skipped ==========
The compilation/linking of Visual Studio does not differ much from what is happening in Linux toolchains. When you are making a binary (an executable or a dynamic library) all external symbols must be resolved. In GCC you must indicate the libraries to your linker. The command line option
-lmath will tell linker to load libmath.a from one of the paths set for library search and use it when building your executable image.
Similarly, in VS you need not only to set the path to library directories, but to explicitly indicate the library file as well. This is usually done on project properties -> Linker -> Input -> Additional dependencies. Note that in Windows you just put in the full library name (MyLib.lib), not the part between lib and .a
Also note that in Windows you cannot link to the binary of a dynamic library (.dll). You will need an import library (.lib) for it.
When you are creating a static library, the toolchain does not resolve the external references. That is why you .lib compiled fine without referencing the nifticlib.
As for where you should link the nifticlib, it depends on the circumstances. If only your MyLibrary will ever be using the functions of nifticlib, it is wise to link it with your static library. However, if someday you'll wish to use some function from nifticlib directly in MyProgram, there may be a conflict at link time. In this case you will need to link the nifticlib only when building the MyProgram.
A rule of the thumb can be formulated like this:
This is not a strict description, and there are more complicated cases, but the basics are like this.
And no, you don't need the cpp files used when building your static library, when you are linking to that library from a different project. The contents of the library .cpp's is already included into static lib file in the form of object code.
Edit: If you do wish to link you static library with the externals from another static library, you need to go to project properties -> Librarian -> General -> Additional dependencies and put the external .lib there