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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31541451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:58:22  来源:igfitidea点击:

Create shared library from cpp files and static library with g++

c++linkerg++shared-librariesstatic-libraries

提问by golobich

Just like title says, I want to create shared library from three cpp files and with some static library.

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

Basicly I want to do this

基本上我想这样做

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

This is my file1.cpp:

这是我的 file1.cpp:

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

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

This is my file2.cpp

这是我的 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 "";
    }
};

And this is my file3.cpp

这是我的 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 
    }
};

I think that I need to create three .o files (file1.o file2.o file3.o) and then combine them like this

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

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

When I have file.o I suppose that then I need to say this:

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

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

but I don't know how to compile .cpp files into .o files. I know I can do it like this

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

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

but I must also provide static library to this command, because file1.cpp (and other files) inherits class that is defined in /usr/local/include/TestSetIterator.hpp but is implemented in /usr/local/lib/libAlgatorc.a Because of -c I can't say -L /usr/local/lib -lAlgatorc

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

At the end, I want shared library of this three classes so that in main function I can load this library into my program and that I can call methods from this three classes. So, I want shared library with all symbols from static library (libAlgatorc.a) and from all three cpp files (file1.cpp, file2.cpp and file3.cpp)

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

I am using Ubuntu 12.04 x64.

我正在使用 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.

回答by Jonathan Wakely

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

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

You should probably use g++to link, not call lddirectly. Passing .ofiles to GCC will cause it to invoke the linker for you, so this works:

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

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

You say:

你说:

but I don't know how to compile .cpp files into .o files.

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

You just compile with -c(and if you want to put the object file in a shared library then also -fPIC):

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

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

but I must also provide static library to this command

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

No, because a command with -cis compiling, not linking, so you can't provide libraries because they are only used when linking.

不,因为一个命令-c是编译,而不是链接,所以你不能提供库,因为它们只在链接时使用。

So, I want shared library with all symbols from static library (libAlgatorc.a) and from all three cpp files (file1.cpp, file2.cpp and file3.cpp)

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

Then you need to read the answer I already pointed you to: https://stackoverflow.com/a/2649792/981959

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

Maybe you should read a tutorial on building software in unix-like environments, maybe something like An Introduction to GCCso that you understand the separate steps needed and what each command does.

也许您应该阅读有关在类 Unix 环境中构建软件的教程,例如GCC 简介之类的内容,以便您了解所需的单独步骤以及每个命令的作用。

To compile each file:

编译每个文件:

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

(you don't need the -ooptions here, by default GCC will compile a file such as file1.cppinto file1.owhen you use the -coption.)

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

Alternatively, you can do that in one step:

或者,您可以一步完成:

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

You can'tuse the -ooption here, because there are three different .ofiles produced as output of the -cstep, so you can't specify a single output file.

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

To link them all into a shared library that also includes the symbols from libAlgatorc.a:

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

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

Or in a single command that will compile all three files and then link them (note there is no -coption here):

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

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

N.B. it is redundant to say -I /usr/local/includeor -L /usr/local/includebecause those paths are always searched by default anyway.

NB 说-I /usr/local/include或者-L /usr/local/include因为这些路径总是默认搜索是多余的。

A simpler approach is to write a makefile:

一种更简单的方法是编写一个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

This is all you need in the makefile, because Make already knows how to create file1.ofrom the input file1.cpp(and setting CXXFLAGSfor the .otargets ensures that -fPICwill be used when compiling those files). Since you're not confident of the right commands for doing this, I suggest relying Make to get it right for you.

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