Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linking a shared library with statics using CMake

Tags:

c

cmake

ld

pjsip

cmake 2.8
gcc (GCC) 4.8.1

Edit ----------

Wrapping the static libraries in whole-archive works for every library except the pjmedia-videodev The problem now is that when I try and build I get the following error.

cbar_factory_init': colorbar_dev.c:(.text+0x2a0): undefined reference to pjmedia_format_init_video'

Hello,

I have created a shared library and I need to link that library with about 10 static libraries. I then link my executable with the shared library.

My question is that when I run make it fails to link as it wants the static libraries as well. The purpose of is to create a wrapper for the static libraries. So the executable only has to link with 1 single shared library. As I am linking the shared library with the statics, then the statics will automatically become part of the source code of the shared library.

Only code sippnets to make it short. In my CMakeLists.txt that creates the shared library and links the static libraries:

add_library(app_module_sip SHARED app_module_sip_init.c)

 set(PJSIP_LIBRARIES
  g7221codec
  gsmcodec
  ilbccodec
  milenage
  pj
  pjlib-util
  pjmedia
  pjmedia-codec
  pjmedia-audiodev
  pjmedia-videodev
  pjnath
  pjsip
  pjsip-simple
  pjsip-ua
  pjsua
  portaudio
  resample
  speex
  srtp
)

target_link_libraries(app_module_sip pthread m uuid nsl rt asound crypto ssl ${PJSIP_LIBRARIES})

Now my CMakeLists.txt that makes the executable

add_executable(app sip_test.c)

target_link_libraries(app app_module_sip)

Is this correct what I am doing here. I don't want to link the executable with the static libraries. Just the single shared library as that is my wrapper what I will be calling the functions in.

It does link ok, if I link all the statics libraries when making the executable, but that is not the result I want.

Many thanks for any suggestions,

like image 360
ant2009 Avatar asked Oct 02 '13 16:10

ant2009


People also ask

How static library is linked?

In computer science, a static library or statically-linked library is a set of routines, external functions and variables which are resolved in a caller at compile-time and copied into a target application by a compiler, linker, or binder, producing an object file and a stand-alone executable.

How does CMake Target_link_libraries work?

target_link_libraries is probably the most useful and confusing command in CMake. It takes a target ( another ) and adds a dependency if a target is given. If no target of that name ( one ) exists, then it adds a link to a library called one on your path (hence the name of the command).

How do I build a shared library using Cmake?

As you can see, CMake automatically generated the Makefile for us, allowing us to build the shared library with the usual make all command. The build procedure called the gcc tool to compile the library’s sources and link them into the libconvert.so file.

Is it possible to mix shared and static versions of libraries?

A single project will not mix both shared and static versions of a library. Certainly for a single target, it is totally illegal to link to both at the same time. This means we don't need to support mixing both types in a single directory.

What's wrong with the CMake library target?

The core issue is that a CMake library target models the build and usage requirements for a single library configuration. When you import SomeLib::SomeLib from a package, the library type is already determined by the time you link another target to it.

How does CMake work on Linux?

With CMake, you write a configuration file called CMakeLists.txt. Taken this file as an input, the CMake utility can generate the build environment for you. Including the automatic detection of the compiler toolchain. On Linux, this essentially results in the automatic creation of a Makefile, which calls gcc for building the library.


2 Answers

I tried to test my solution but your CMakeLists.txt worked for me without any changes. Still, looking at this question: Include static lib in dynamic lib, it appears that you should try

target_link_libraries(app_module_sip ... ssl -Wl,-whole-archive ${PJSIP_LIBRARIES} -Wl,-no_whole-archive)

(scroll to the end, it's a long line)

like image 199
Roberto Avatar answered Sep 22 '22 15:09

Roberto


It's not that simple.

You can look at using '-Wl,--whole-archive' or '-Wl,--export-all-symbols' depending on your platform, but there's no good cross platform way of doing this. Everything does it differently, and windows plays a completely different game using lib.exe.

You probably want to do something like this:

http://www.mail-archive.com/[email protected]/msg01890.html

...and add support specifically for the platforms you want to support, one at a time.

like image 32
Doug Avatar answered Sep 22 '22 15:09

Doug