【问题标题】:Create shared library from cpp files and static library with g++ [duplicate]使用g ++从cpp文件和静态库创建共享库[重复]
【发布时间】:2015-10-11 01:10:08
【问题描述】:

正如标题所说,我想从三个 cpp 文件和一些静态库创建共享库。

基本上我想这样做

g++ libProject.so file1.cpp file2.cpp file3.cpp -I /usr/local/include -L /usr/local/lib -lAlgatorc 

这是我的 file1.cpp:

#include <iostream>
#include <TestSetIterator.hpp>

class SortingTestSetIterator : public TestSetIterator {
public: 
    TestCase *get_current(){
         //TODO: implement method
         return nullptr; 
    }
};

这是我的 file2.cpp

#include<iostream>
#include<TestCase.hpp>
#include<Entity.hpp>
#include<ParameterSet.hpp>

class SortingTestCase : public TestCase {
public: 
    std::string print() { 
         //TODO: implement method
        return "";
    }
};

这是我的 file3.cpp

#include <iostream>
#include <AbsAlgorithm.hpp>
#include "SortingTestCase.cpp"
class SortingAbsAlgorithm : public AbsAlgorithm {
private: 
    SortingTestCase Sorting_test_case;
public:
    bool init (TestCase &test) {
         //TODO: implement method
         return true; 
    }

    void run() {
         //TODO: Implement method 
    }

    void done() {
         //TODO: Implement method 
    }
};

我认为我需要创建三个.o文件(file1.o file2.o file3.o)然后像这样组合它们

ld -r file1.o file2.o file3.o -o file.o

当我有 file.o 时,我想我需要这样说:

g++ -shared -o libProject.so file.o

但我不知道如何将 .cpp 文件编译成 .o 文件。 我知道我可以这样做

g++ -std=gnu++11 -o file1.o -fPIC -c file1.cpp -I /usr/local/include

但我还必须为此命令提供静态库,因为 file1.cpp(和其他文件)继承了 /usr/local/include/TestSetIterator.hpp 中定义但在 /usr/local/lib/ 中实现的类libAlgatorc.a 因为 -c 我不能说 -L /usr/local/lib -lAlgatorc

最后,我想要这三个类的共享库,以便在主函数中我可以将这个库加载到我的程序中,并且我可以从这三个类中调用方法。所以,我想要包含来自静态库(libAlgatorc.a)和所有三个 cpp 文件(file1.cpp、file2.cpp 和 file3.cpp)的所有符号的共享库

我使用的是 Ubuntu 12.04 x64。

> g++ --version
g++ (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【问题讨论】:

  • 这不是我已经向您指出的问题吗? stackoverflow.com/questions/2649735/…
  • 没有。没有从静态库和 cpp 文件构建的共享库。仅从静态库构建共享库。我想把这两者结合起来。
  • 还是基本一样。只需将 .o 文件添加到该答案中的命令即可。关键是另一个答案显示了如何确保静态库中的所有符号最终都在共享库中,这正是您的问题。
  • 其实一模一样,如果您阅读问题,您会看到链接器命令包含文件:some.o another.o
  • 我来的时候正在找g++ ./libsomething.cpp -fPIC -shared -o ./libsomething.so

标签: c++ linker g++ shared-libraries static-libraries


【解决方案1】:

ld -r file1.o file2.o file3.o -o file.o

您可能应该使用g++ 链接,而不是直接调用ld。将 .o 文件传递​​给 GCC 会导致它为您调用链接器,所以这是可行的:

g++ file1.o file2.o file3.o -o file.o

你说:

但我不知道如何将 .cpp 文件编译成 .o 文件。

您只需使用-c 进行编译(如果您想将目标文件放入共享库中,则还需使用-fPIC):

g++ -c file1.cpp -fPIC -o file1.o

但我还必须为此命令提供静态库

不,因为带有-c 的命令正在编译,而不是链接,因此您无法提供库,因为它们仅在链接时使用。

所以,我想要包含来自静态库 (libAlgatorc.a) 和所有三个 cpp 文件(file1.cpp、file2.cpp 和 file3.cpp)的所有符号的共享库

那么你需要阅读我已经指出你的答案:https://stackoverflow.com/a/2649792/981959

也许您应该阅读有关在类 unix 环境中构建软件的教程,可能类似于 An Introduction to GCC,以便了解所需的单独步骤以及每个命令的作用。

编译每个文件:

g++ -c -fPIC file1.cpp
g++ -c -fPIC file2.cpp
g++ -c -fPIC file3.cpp

(此处不需要-o 选项,默认情况下,当您使用-c 选项时,GCC 会将file1.cpp 等文件编译为file1.o。)

或者,您可以一步完成:

g++ -c -fPIC file1.cpp file2.cpp file3.cpp

不能在此处使用-o 选项,因为-c 步骤的输出会生成三个不同的.o 文件,因此您不能指定单个输出文件。

要将它们全部链接到一个共享库中,该库还包含来自libAlgatorc.a 的符号:

g++ file1.o file2.o file3.o -shared -o libProject.so -Wl,--whole-archive libAlgatorc.a -Wl,--no-whole-archive

或者在一个命令中编译所有三个文件然后链接它们(注意这里没有-c选项):

g++ -fPIC file1.cpp file2.cpp file3.cpp -shared -o libProject.so -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive

注意说-I /usr/local/include-L /usr/local/include 是多余的,因为无论如何这些路径总是默认搜索。

更简单的方法是编写一个makefile:

libProjects.so: file1.o file2.o file3.o
        $(CXX) -shared $^ -o $@ -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive

file1.o file2.o file3.o : CXXFLAGS+=-fPIC

这就是你在makefile中所需要的,因为Make已经知道如何从输入file1.cpp创建file1.o(并且为.o目标设置CXXFLAGS可确保在编译时使用-fPIC那些文件)。由于您对执行此操作的正确命令没有信心,我建议依靠 Make 来为您提供正确的命令。

【讨论】:

  • 如果我像你一样这样做,我会得到这个:/usr/bin/ld: /usr/local/lib/libAlgatorc.a(ParameterSet.o): relocation R_X86_64_32 against `.rodata.str1 .1' 制作共享对象时不能使用;使用 -fPIC /usr/local/lib/libAlgatorc.a(ParameterSet.o) 重新编译:无法读取符号:错误值 collect2:错误:ld 返回 1 个退出状态
  • 这意味着libAlgator.ca 中的对象不可重定位,因此不能在共享库中使用。您要么需要获得 libAlgatorc 的新版本,其中的内容是使用 -fPIC 构建的(可能会获得 .so intead),要么您无法完成这项工作,并且必须将您的主要可执行文件链接到 @987654356 @ 而不是将其包含在 libProject.so
  • 好多了!那个命令g++ -fPIC file1.cpp file2.cpp file3.cpp -shared -o libProject.so -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive就像一个魅力!问题也在静态库中。静态库不是用 -fPIC 编译的,但它必须是,因为我们正在将这些符号添加到共享库中。真是完美的答案! :) 谢谢你的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多