Combining several static libraries into one using CMake


====================== Ask ======================

I have a very similar problem to one described on the cmake mailing list where we have a project dependent on many static libraries (all built from source in individual submodules, each with their own CMakeLists.txt describing the build process for each library) that I'd like to combine into a single static library for release to the consumers. The dependencies of my library are subject to change, and I do not want to burden developers further down the chain with those changes. The neat solution would be to bundle all of the libs into one single lib.

Interestingly, the target_link_libraries command does not combine all of the statics when setting the target to mylib and using it like so . .

target_link_libraries(mylib a b c d)

However, bizarrely, if I make the mylib project a submodule of an executable project, and only link againstmylib in the top level executable CMAkeLists.txt, the library does seem to be combined. I.e. mylib is 27 MB, instead of the 3MB when I set the target to only build mylib.

There are solutions describing unpacking of the libs into object files and recombining (here, and here), but this seems remarkably clumsy when CMake seems perfectly capable of automatically merging the libs as described in the above example. It there a magic command I'm missing, or a recommended elegant way of making a release library?


====================== Answer ======================

Given the most simple working example I can think of: 2 classes, a and b, where a depends on b . .

a.h

#ifndef A_H
#define A_H

class aclass
{
public:
    int method(int x, int y);
};

#endif

a.cpp

#include "a.h"
#include "b.h"

int aclass::method(int x, int y) {
    bclass b;
    return x * b.method(x,y);
}

b.h

#ifndef B_H
#define B_H

class bclass
{
public:
    int method(int x, int y);
};

#endif

b.cpp

#include "b.h"

int bclass::method(int x, int y) {
    return x+y;
}

main.cpp

#include "a.h"
#include <iostream>

int main()
{
    aclass a;
    std::cout << a.method(3,4) << std::endl;

    return 0;
}

It is possible to compile these into separate static libs, and then combine the static libs using a custom target.


cmake_minimum_required(VERSION 2.8.7)

add_library(b b.cpp b.h)
add_library(a a.cpp a.h)
add_executable(main main.cpp)

set(C_LIB ${CMAKE_BINARY_DIR}/libcombi.a)

add_custom_target(combined
        COMMAND ar -x $<TARGET_FILE:a>
        COMMAND ar -x $<TARGET_FILE:b>
        COMMAND ar -qcs ${C_LIB} *.o
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        DEPENDS a b
        )

add_library(c STATIC IMPORTED GLOBAL)
add_dependencies(c combined)

set_target_properties(c
        PROPERTIES
        IMPORTED_LOCATION ${C_LIB}
        )

target_link_libraries(main c)


It also works just fine using Apple's libtool version of the custom target . . .


add_custom_target(combined
        COMMAND libtool -static -o ${C_LIB} $<TARGET_FILE:a> $<TARGET_FILE:b>
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        DEPENDS a b
        )


Still seams as though there should be a neater way . .





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值