I'm on VS2022. I'm creating a little static library to handle embedded resources (so let's call it er) in my c++ project.
This library uses zlib (latest version, 1.3.1) to compress the files before processing it (details don't really matter here). So I built zlib and linked my er project against zlibstaticd.lib and zlibstatic.lib.
The cmake file is something like:
set (EXPORT_HEADER_FILES
export/er/er.hpp
)
set (SOURCE_FILES
cpp/er.cpp
)
source_group("er/cpp" FILES ${SOURCE_FILES})
source_group("er/export" FILES ${EXPORT_HEADER_FILES})
add_library(er STATIC ${EXPORT_HEADER_FILES} ${SOURCE_FILES})
set(ZLIB_LIBS
debug ${ZLIB_LIBRARY}/zlibstaticd.lib optimized ${ZLIB_LIBRARY}/zlibstatic.lib
)
target_link_libraries(er PRIVATE ${ZLIB_LIBS})
target_include_directories(er
PRIVATE hpp ${ZLIB_INCLUDE_DIRS}
PUBLIC export
)
Everything's fine so far.
Now, the point is I want er to be standalone, that's why zlib is linked privately. There is no mention of zlib in the er.hpp file.
So now I build er, and want to use it in my other project (lib2 let's call it).
So I add er and link it as static lib to my project (just like I did with zlib for er). But when I try to compile I now get linkers errors as follows:
Error LNK2019 unresolved external symbol inflate referenced in function "bool __cdecl er::decompress(...)
Error LNK2019 unresolved external symbol deflate referenced in function "bool __cdecl er::compress(...)
Error LNK2019 unresolved external symbol deflateEnd referenced in function "bool __cdecl er::compress(...)
Error LNK2019 unresolved external symbol inflateEnd referenced in function "bool __cdecl er::decompress(...)
Error LNK2019 unresolved external symbol deflateInit_ referenced in function "bool __cdecl er::compress(...)
Error LNK2019 unresolved external symbol inflateInit_ referenced in function "bool __cdecl er::decompress(...)
Now why would I get that? inflate, deflate, deflateEnd, inflateEnd,... Those are zlib functions and as I don't want to link zlib to lib2.
I'm really lost here. I tried the
#define ZLIB_WINAPI
#include <zlib/zlib.h>
in the er.cpp file like some can mentions in some answers I found on SO, but it doesn't do anything.
As Some programmer dude commented, archive libraries are not linked in any sense of the word.
You can think of them as a shopping bag filled with object files. You want to prepare a baked potato with sour cream; you have potatoes in one shopping bag (
er.lib) and sour cream in another (zlib.lib). When preparing the meal, you need to use both bags (at link time), i.e. link your final program with bother.libandzlib.lib.You could put all of your ingredients into a single shopping bag, and then you would only need that one shopping bag (the combined
erz.lib) at link time.To do that, you can unpack
er.libandzlib.libto extract all the.objfiles from them, and add these object files into the combinederz.liblibrary.Update:
I don't know about
cmakefunction, but you can trivially construct aMakefilerule for it. It turns out that (unlike UNIXar)LIB.EXEcan directly combine.LIBfiles in a single command: