Amit Jain
Amit Jain

Reputation: 241

Link only static library when both static and shared C++ libraries are present in lib folder

I am using conan as dependency manager and cmake as build tool. I have some pre-built third party libraries present, which have both shared and static libraries in the lib folder ( .a and .so files ). My plan is to create conan packages from those pre-built libraries, and use them to build application

When I try to link the libraries while building the application, it links shared libraries by default. But I want to use the static libraries for an specific application.

One way to solve the problem is to create two separate conan packages for static and shared libraries and include the required static package in the conanfile, but that will lead to redundancy for Artifact management ( Same header files will be present in multiple packages ).

Is there a better way there by making any changes to the conanfile.py or CMakeLists.txt, so that I can link static libraries and not shared libraries, even if similar shared libraries are present in the same lib file ( e.g. libX.a and libX.so both are there in the same lib folder )?

Upvotes: 4

Views: 4837

Answers (1)

drodri
drodri

Reputation: 5972

One way to solve the problem is to create two separate conan packages for static and shared libraries and include the required static package in the conanfile, but that will lead to redundancy for Artifact management (Same header files will be present in multiple packages).

This would be my first suggestion. But not as two separate packages, but using the same package recipe with options={"shared": [True, False]}, and make it generate 2 different package binaries (but for the same package. Unless you have a huge library with thousands of headers (and even though), the impact in download times and disk space is really small. It could be a problem if the packages had to be manually created or installed, but as everything is automatic, you won't notice. This approach has an advantage of easier future maintenance if some config.h is generated (with different configuration for different platforms or static/shared), or have different headers for different platforms, typical "header_win.h" and "header_linux.h", can be fully automated with conan to have a single "header.h" that would be transparent for consumers.

If you still want to not have this duplication, there can be different approaches:

First, you can make a "PkgHeaders" package with only the headers, that will be required from the "Pkg" package, that will contain only the binaries (shared or static)

Another approach: You can make the "Pkg" package to contain both the static and shared versions. It would be similar to the release/debug multi-config package explained here in the docs. The idea is that the package doesn't have a shared option. It will create and package both. The package_info() method will declare different variables for each, something like

 def package_info(self):
     self.cpp_info.shared.libs = ["libX.so"]
     self.cpp_info.static.libs = ["libX.a"]

This will generate different CMake variables in the generated conanbuildinfo.cmake

set(CONAN_LIBS_SHARED libX.so ${CONAN_LIBS_SHARED})
set(CONAN_LIBS_STATIC libX.a ${CONAN_LIBS_STATIC})

Note, however, that these variables will not be used automatically in the consumer, but you will have to explicitly decide which one to use.

So the added complexity is not worth. Unless your library has hundreds of MBs of headers, I'd go for sure for the first approach.

Upvotes: 1

Related Questions