代码之家  ›  专栏  ›  技术社区  ›  mortymacs

用所有依赖项编译C++项目到单个二进制文件中

  •  0
  • mortymacs  · 技术社区  · 5 年前

    我有一个C++项目,我想把它编译成一个包含所有共享库、第三方等等的二进制文件。 我想将编译后的文件移动到不同的服务器,而不安装任何依赖项。这就是为什么我需要一个一体化/捆绑的二进制文件。

    例如,我尝试编译以下内容:

    g++ sample.cpp -o sample -Wl,-Bstatic -l:libyaml-cpp.so
    

    但我犯了这个错误,而我真的犯了 libyaml-cpp.so 归档 /usr/lib 目录:

    /usr/bin/ld: attempted static link of dynamic object `/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/libyaml-cpp.so'
    collect2: error: ld returned 1 exit status
    

    3 回复  |  直到 5 年前
        1
  •  1
  •   HolyBlackCat    5 年前

    通常你会使用 g++ sample.cpp -o sample -static -lyaml-cpp .

    • 自己构建yaml cpp以获得静态库。

    • 为避免将其安装在系统目录中,您可以执行以下操作之一:

      • LD_LIBRARY_PATH env变量在运行程序时,指向 .so .

      • 添加 -Wl,-rpath='$ORIGIN' 在检查系统目录之前,生成的二进制文件将自动尝试从其目录加载库。

        patchelf . 当您想要包含其他共享库所依赖的共享库,而后者不是用它编译时,这非常有用

        2
  •  1
  •   Marcus Müller    5 年前

    您明确要求对共享对象(.so)进行链接!

    -l:libyaml-cpp.so
    

    你说你的链接器找不到 -lyaml-cpp

        3
  •  0
  •   danielschemmel    5 年前

    一般来说,有两种方法可以确保您的程序只包含一个(可执行)文件:

    静态链接

    lib*.a ). 链接程序时,静态库的行为与普通对象文件非常相似。请注意,您的问题明确提到了动态库( lib*.so ),这是另一种编译后从文件加载的库。

    请注意,glibc does not like 静态链接,以及 may not support it at all .

    将共享对象嵌入为资源

    或者,您可以将共享对象(和其他资源)嵌入到可执行文件中,并将其解压缩以供执行。这可以通过多种方式实现(想想自解压zip存档、以字节数组形式存储在全局变量中的文件、, this question may get you started ).

    然后,您必须将共享库转储到文件中(例如,在tempfs中)并 dlopen 他们。