0

Our product requires a static library (.lib) file to be linked as part of a Vendor's API.

I have a project defined for the API which supplies a number of functions & classes, and that generates a .lib file.

But for that .lib to link and be used by a client, it also needs to link against this static presupplied .lib from the Vendor.

So the dependency tree is:

My App -> API Wrapper Lib -> Static Lib

I can trivially tell VS that My App is dependent on API Wrapper Lib - and so My App will link against the .lib file produced by API Wrapper Lib. But it fails to link against the vendor's static lib file.

Under linker settings in My App, I can add "additional dependencies" and name "Static.lib" as a dependency - and then add "additional directories" and specify the folder where that static lib lives.

This works.

I can alternately use:

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

in the main header for API Wrapper Lib which is referenced by My App. This obviates the need for an "additional dependencies" setting in My App. However, this won't work unless I still specify the "additional directories" to name the folder where "static.lib" lives, even though it lives in the same folder with API Wrapper Lib on which it is already dependent.

My question is: is there an easier way to design API Wrapper Lib so that it embeds static.lib within itself, or automatically tells the linker "hey, when folks link against my .lib, make sure you also look to "static.lib" to resolve any missing symbols"

Or something like that..

The #pragma comment(lib, ...) is cool - but I still have to pollute the My App project with a special reference to the wrapper folder in addition to telling it "you're linkage dependent on the wrapper library".

Seems redundant and messy - always better to have one thing to set - preferably set by the wrapper library so that everything is take care of at that end - and the client need only include and specify dependency on the one thing.

Help!

Mordachai
  • 9,412
  • 6
  • 60
  • 112
  • 1
    I don't know if the following still possible (couldn't find it that fast) ,but in the old days one could include an external library in another library by specifying it as an input-file for the LIB command. You can try this by making "static.lib" a source file for your wrapper-lib (add existing item and choose the .lib from somewhere) – engf-010 Mar 05 '18 at 21:52
  • I'll look into that idea - thanks! – Mordachai Mar 05 '18 at 22:26
  • 1
    Just did a little test with 1 app depending on 1 lib that depends on second lib. With 1 REMARK : works with those 3 projects in 1 one solution and additional references from one to the another. But when I remove the project second lib from the solution ,the link fails ! ? – engf-010 Mar 05 '18 at 22:41
  • 1
    Sorry ,can't make this work. Tried several setting (Compiler and/or Librarian) ,but linking keeps failing. – engf-010 Mar 05 '18 at 23:41
  • I wonder if I could use an empty library project which somehow produces the precompiled static library? So that reference to this extra project would then link to it? – Mordachai Mar 06 '18 at 13:44
  • Very inventive ,certainly worth trying I guess ,maybe a custom build step is needed. – engf-010 Mar 06 '18 at 13:50
  • 1
    You in general know that something has be linked to make your code work, but you can't know where he decided to put the .lib file. So #pragma comment is for you, but Project > Properties > Linker is for him. A custom project template might help, but forcing source control mappings is not generally appreciated. Do keep in mind that providing static libraries is a job that is never done, you need to provide all flavors for all compiler versions. Raising awareness with the programmer to get him to pick the right one would be wise. – Hans Passant Mar 06 '18 at 17:45
  • 1
    I stumbled upon this - which might offer a solution by combining libs: https://stackoverflow.com/questions/2157629/linking-static-libraries-to-other-static-libraries – Mordachai Mar 06 '18 at 17:52
  • @HansPassant Yes - absolutely! Too bad this sort of thing isn't standardized into a single file-type that can be made to produce all that is required, without supplying source code (modules anyone?!!!) – Mordachai Mar 06 '18 at 17:54

2 Answers2

1

As with all "best" questions, I cannot be sure that my solution is "best" - only that it is "functional" and meets my requirements better than any others I've come up with.

Essentially, I've decided to use a pragma comment to tell the linker "link against the following file" and I've included a relative path for it.

This means I'm asserting knowledge of where this library file is located relative to the client projects who need to use it. This may not be appropriate in your situation? But if it is, this does work.

I could also have simply spelled out the exact location of this file as an absolute path. That removes my need to standardize what client projects relationship will be to this wrapper API library which "injects" the static library, but introduces the need for an absolute path meaning this wrapper library cannot move.

Either way there's some limitation, something less than ideal.

If I had a way to obtain the current project's path from the compiler, in macro form, I'd be golden! I could use the current absolute path to give me exactly what I need. Alas, I see no way to obtain that from MS Visual Studio. The current file with full path is available - but how then does one chop down to the path portion of that string at preprocessor time? That's outside of my skills.

So, my solution means that the client project doesn't need more than a dependency on my API wrapper library, and this line in the main header for that library:

 #pragma comment(lib, "..\\3rd Party\\Wrapper API Library\\static.lib")

As I said, not perfect, but functional and a reasonable improvement over having to add "additional library directories" and "additional dependencies" fields to each client project.

And it means if I have two such wrappers, and wish to switch between them, I need only update which of the wrappers I want included in my client project, and nothing more.

Much more satisfying!

If anyone has a way to obtain the project path or the file's path from the precompiler (macro stage) - then PLEASE share. And then this could be essentially perfect.

Mordachai
  • 9,412
  • 6
  • 60
  • 112
0

User @evpo adds this answer here, which seems even more elegant.

His answer is down a ways, and I'm quoting it here in its entirety:

Alternatively to Link Library Dependencies in project properties there is another way to link libraries in Visual Studio.

Open the project of the library (X) that you want to be combined with other libraries. Add the other libraries you want combined with X (Right Click, Add Existing Item...). Go to their properties and make sure Item Type is Library This will include the other libraries in X as if you ran

lib /out:X.lib X.lib other1.lib other2.lib

Mordachai
  • 9,412
  • 6
  • 60
  • 112
  • 1
    The thing that drives me NUTS about this answer is that THIS was already how my Wrapper API Library was configured. And yet I was encountering missing link symbols from the static.lib. But I must have had other issues, because this is working perfectly for me now! (Go figure!) – Mordachai Mar 06 '18 at 18:56