简体   繁体   中英

Making library with multiple classes, additional pre-existing .a library and other dependencies

I've done several classes that I'm using in a class called " LidarPathMapping ". I've been 2 days looking for a solution to make it possible for a person to include the class in his code and use it. I don't want him to need to include the other classes that LidarPathMapping depends on and all the other dependencies with which I compile the drivers with which I test my code. My code also depends on a library called librplidar_sdk.a and another called PIGPIO (it runs in a raspberry pi). I would like that a person that wants to use my code only needs to

#include "LidarPathMapping.h"

in his code and compile with something like:

g++ main.cpp -L. -lLidarPathMapping

I don't mind if the person needs to include the libraries I'm using (see in make file) but needing to include every object of each class I've done would defeat the purpose. I have no preference of method, I just want to simplify things for the person that wants to use it. I would appreciate if also someone could tell me how the library would be used by the user: how to include in .cpp file and in the g++ compilation command.Here is the makefile I've done to compile a driver to test my code:

CFLAGS=  -w -Wall

LDIR= /home/pi/Documents/code/cpp/andar/andar/include

LIBS= -lboost_iostreams -lboost_system -lboost_filesystem \
       -lrplidar_sdk -lstdc++ -lpthread -lpigpio -lrt -pthread \
       -lGL -lGLU -lglut

#DEFS = -D USE_OPEN_GL
######################### Objects ###########################

OBJS = objects/LidarPlusServo.o \
        objects/CloudManipulation.o \
        objects/RoverParameters.o \
        objects/csvReader.o \
        objects/Dstar.o \
        objects/LidarPathMapping.o \


######################### Headers ###########################

ANDARHEADERS = andar_include/LidarPlusServo.h \
               andar_include/CloudManipulation.h \
               andar_include/RoverParameters.h \
               csvReader/csvReader.hpp \
               include/Dstar.h \
               andar_include/LidarPathMapping.h \

######################### Source Files ###########################
ANDARSRC = LidarPlusServo.cpp \
               CloudManipulation.cpp \
               RoverParameters.cpp \
               csvReader/csvReader.cpp \
               Dstar.cpp \
               LidarPathMapping.cpp \


######################## Executable ##################################

#Change name here#
#If main file is called "helloWorld.cpp", write "helloWorld"

NAME = driverLidPathMap

$(NAME): $(OBJS) $(NAME).cpp
    sudo g++ -std=c++11 $(CFLAGS) -o $(NAME) $(NAME).cpp $(OBJS) \
                     $(LIBS) -L$(LDIR)

####################### Create Objects ########################
objects/LidarPlusServo.o: LidarPlusServo.cpp $(ANDARHEADERS) 
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) LidarPlusServo.cpp

objects/CloudManipulation.o: CloudManipulation.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) CloudManipulation.cpp

objects/RoverParameters.o: RoverParameters.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) RoverParameters.cpp

objects/csvReader.o: csvReader/csvReader.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c  -o $@ $(CFLAGS) csvReader/csvReader.cpp

objects/Dstar.o: Dstar.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c  -o $@ $(CFLAGS) Dstar.cpp

objects/LidarPathMapping.o: LidarPathMapping.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c  -o $@ $(CFLAGS) LidarPathMapping.cpp

First, here is a useful trick. You have a separate rule for each object:

objects/LidarPlusServo.o: LidarPlusServo.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) LidarPlusServo.cpp

objects/CloudManipulation.o: CloudManipulation.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) CloudManipulation.cpp

objects/RoverParameters.o: RoverParameters.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) RoverParameters.cpp

...

You are using the automatic variable $@ , but you can also use $< for the first argument in the prerequisite list:

objects/LidarPlusServo.o: LidarPlusServo.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) $<

objects/CloudManipulation.o: CloudManipulation.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) $<

objects/RoverParameters.o: RoverParameters.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) $<

...

Notice that all of these rules are the same, except for the target and the first prerequisite, which follow a simple rule, objects/foo.o: foo.cpp . So you can replace all of these rules with one pattern rule:

objects/%.o: %.cpp $(ANDARHEADERS)
    sudo g++ -std=c++11 -c -o $@ $(CFLAGS) $<

Now for building and using the library. I don't know enough about the internals of your source files to know exactly what changes are necessary, but I will give a simple example to show the technique.

Suppose I have three source files, ant.cpp , bee.cpp , crocket.cpp , with their respective header files, Each contains some classes, some of which depend on each other. Now I want to combine them into a shared library, libInsect.so , with an associated header file, Insect.h , and build an executable bughunt that uses it.

Insect.h is easy:

#include "ant.h"
#include "bee.h"
#include "cricket.h"

Now for the makefile:

OBJECTS := ant.o bee.o cricket.o

%.o: %.cpp %.h
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -fPIC -c $< -o $@

libInsect.so: $(OBJECTS)
    $(CXX) -fPIC -shared -o $@ $^

bughunt: bughunt.cpp libInsect.so
    $(CXX) -L. $< -lInsect -o $@

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM