Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create shared library from cpp files and static library with g++ [duplicate]

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

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:

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

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

This is my 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

#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

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:

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

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

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)

I am using 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.
like image 279
golobitch Avatar asked Jul 21 '15 14:07

golobitch


People also ask

What is static and shared library?

Static libraries take longer to execute, because loading into the memory happens every time while executing. While Shared libraries are faster because shared library code is already in the memory.

Which of the following options is necessary to create a shared library?

The -shared or -dynamiclib option is required to create a shared library. The name of the source file is octagon.


1 Answers

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

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

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.

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

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

but I must also provide static library to this command

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

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)

Then you need to read the answer I already pointed you to: 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 GCC so that you understand the separate steps needed and what each command does.

To compile each file:

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

(you don't need the -o options here, by default GCC will compile a file such as file1.cpp into file1.o when you use the -c option.)

Alternatively, you can do that in one step:

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

You can't use the -o option here, because there are three different .o files produced as output of the -c step, so you can't specify a single output file.

To link them all into a shared library that also includes the symbols from 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 -c option here):

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/include or -L /usr/local/include because those paths are always searched by default anyway.

A simpler approach is to write a 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.o from the input file1.cpp (and setting CXXFLAGS for the .o targets ensures that -fPIC will 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.

like image 121
Jonathan Wakely Avatar answered Oct 15 '22 00:10

Jonathan Wakely