使用g ++从cpp文件和静态库创建共享库

gol*_*ich 12 c++ linker g++ shared-libraries static-libraries

就像标题所说,我想从三个cpp文件和一些静态库创建共享库.

基本上我想这样做

g++ libProject.so file1.cpp file2.cpp file3.cpp -I /usr/local/include -L /usr/local/lib -lAlgatorc 
Run Code Online (Sandbox Code Playgroud)

这是我的file1.cpp:

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

class SortingTestSetIterator : public TestSetIterator {
public: 
    TestCase *get_current(){
         //TODO: implement method
         return nullptr; 
    }
};
Run Code Online (Sandbox Code Playgroud)

这是我的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 "";
    }
};
Run Code Online (Sandbox Code Playgroud)

这是我的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 
    }
};
Run Code Online (Sandbox Code Playgroud)

我认为我需要创建三个.o文件(file1.o file2.o file3.o),然后将它们组合起来

ld -r file1.o file2.o file3.o -o file.o
Run Code Online (Sandbox Code Playgroud)

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

g++ -shared -o libProject.so file.o
Run Code Online (Sandbox Code Playgroud)

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

g++ -std=gnu++11 -o file1.o -fPIC -c file1.cpp -I /usr/local/include
Run Code Online (Sandbox Code Playgroud)

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

最后,我想要这三个类的共享库,以便在main函数中我可以将这个库加载到我的程序中,并且我可以从这三个类中调用方法.所以,我希望共享库包含来自静态库(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.
Run Code Online (Sandbox Code Playgroud)

Jon*_*ely 29

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
Run Code Online (Sandbox Code Playgroud)

你说:

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

您只需编译-c(如果您想将目标文件放在共享库中,那么-fPIC):

g++ -c file1.cpp -fPIC -o file1.o
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

编译每个文件:

g++ -c -fPIC file1.cpp
g++ -c -fPIC file2.cpp
g++ -c -fPIC file3.cpp
Run Code Online (Sandbox Code Playgroud)

(你不需要-o选择这里,默认情况下GCC将编译文件,如file1.cppfile1.o时,您使用-c的选项.)

或者,您可以一步完成:

g++ -c -fPIC file1.cpp file2.cpp file3.cpp
Run Code Online (Sandbox Code Playgroud)

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

要将它们全部链接到共享库,该库还包含以下符号libAlgatorc.a:

g++ file1.o file2.o file3.o -shared -o libProject.so -Wl,--whole-archive libAlgatorc.a -Wl,--no-whole-archive
Run Code Online (Sandbox Code Playgroud)

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

g++ -fPIC file1.cpp file2.cpp file3.cpp -shared -o libProject.so -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive
Run Code Online (Sandbox Code Playgroud)

NB说这是多余的,-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
Run Code Online (Sandbox Code Playgroud)

这是你在Makefile需要,因为化妆已经知道如何创建file1.o从输入file1.cpp(并设置CXXFLAGS.o目标确保-fPIC编译这些文件时,将使用).由于你对这样做的正确命令没有信心,我建议依靠Make来使它适合你.

  • 好多了!该命令`g++ -fPIC file1.cpp file2.cpp file3.cpp -shared -o libProject.so -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive` 就像一个魅力!问题也出在静态库中。静态库不是用 -fPIC 编译的,但必须是,因为我们将这些符号添加到共享库中。真的完美答案!:) 谢谢你的帮助! (2认同)