使用CMake将多个静态库合并为一个 [英] Combining several static libraries into one using CMake

查看:3814
本文介绍了使用CMake将多个静态库合并为一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的问题与cmake上描述的 非常相似。邮件列表中,我们有一个项目依赖于许多静态库(所有库都是从单个子模块中的源代码构建的,每个子模块都有自己的CMakeLists.txt描述每个库的构建过程),我想将这些库合并到一个静态库中进行发布给消费者。我的库的依赖关系可能会发生更改,因此,我不想让开发人员在这些更改的负担下承担更多责任。整洁的解决方案是将所有库捆绑到一个库中。

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.

有趣的是, target_link_libraries 命令确实可以将目标设置为 mylib 并像这样使用它时,不要合并所有静态变量。 。

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)

但是,奇怪的是,如果我将 mylib 项目设为可执行项目的子模块,并且仅链接到 mylib 在顶级可执行文件CMAkeLists.txt中,该库似乎已合并。即mylib是27 MB,而不是我将目标设置为仅构建 mylib 时的3MB。

However, bizarrely, if I make the mylib project a submodule of an executable project, and only link against mylib 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.

有解决方案描述将这些库解压缩到目标文件并重新组合(在此处,和< a href = https://stackoverflow.com/questions/2662430/combining-several-static-archives-into-a-new-one>此处),但是当CMake看起来非常有能力时,这显得非常笨拙如以上示例所述自动合并库。

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?

推荐答案

给出最简单的命令吗?我可以想到的工作示例:2个类, a b ,其中 a 取决于 b 。 。

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

#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);
}



bh



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



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)

使用苹果公司的 libtool 版本的自定义工具也可以正常工作Arget。 。 。

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 . .

这篇关于使用CMake将多个静态库合并为一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆