Use SDK (libraries, header files, etc) during creating a C++ ROS package - c++

I am working with Teledyne Lumenera USB Camera. I installed lucam-sdk_2.4.3.94 for Linux on my Ubuntu 18.04. It includes these files:
The api folder contains this files:
One of the folders is example which contains several examples for working with Teledyne Lumenera USB Camera. Each example in example folder, shows one of the aspects of the camera like setting focus, reading camera info, etc. Each example has a folder that contains some .cpp, .h and one make file.
I want to write a C++ ROS node that uses this SDK.
First, I create a ROS package in my catkin_ws/src then I copy one of the examples in SDK into the src package folder.
When I use catkin_make, it says that it does not recognize lucamapi.h, which is one of the header files in the SDK.
My question is two parts:
1- the code that I copied from example folders contains some .cpp and .h files. Also, that has a make file beside themselves. I do not know how to handle the make file. How can I put parameters of the following MakeFile into CMakeList.txt?
2- I do not know how to change CMakeList.txt in my ROS package in order to have access to SDK headers, lib, etc.
This is make file for one of of the examples in the SDK:
#
CC = g++
LD = $(CC)
ifndef ARCH
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/x86_64/x86-64/)
endif
LU_LDFLAGS = -lm -lpthread -lstdc++
PROG = livePreview
VERSION = 0.1
INCLUDES = $(LUMENERA_SDK)/include
CFLAGS = -DVERSION=\"$(VERSION)\" -I$(INCLUDES) -g
CFLAGS += -DLUMENERA_LINUX_API
OBJS =
ALL_INCLUDES =
all lu: $(PROG)
clean:
rm -f $(PROG) *.o *.core core *.bak *~
livePreview: verify_environment livePreview.o Camera.o
$(LD) livePreview.o Camera.o `pkg-config --libs opencv` -llucamapi $(LU_LDFLAGS) -o $#
verify_environment:
#if test "$(LUMENERA_SDK)" = "" ; then \
echo "LUMENERA_SDK environment variable is not set!"; \
exit 1; \
fi
Camera.o: Camera.cpp $(INCLUDES)/lucamapi.h
$(CC) $(CFLAGS) -c Camera.cpp
livePreview.o: livePreview.cpp $(INCLUDES)/lucamapi.h
$(CC) $(CFLAGS) -c livePreview.cpp

I solved the problem. Working with CMakeList and ROS was confusing.
Go to this repository, and read instalation part, then look at CMakeList.txt:
https://github.com/farhad-dalirani/lumenera_camera_package

Related

Petalinux Recipe-app for mixed C and C++ application

I have a rather large C program that I have already written. I'm now being asked to utilize a C++ class that a co-worker has written. I'm use to working with python, so writing my application in C and now being asked to work with C++ is causing some migraines. So ignoring my main application I decided to do some research and came across a youtube video that shows me how to do a very simple C program that calls a C++ class.
In order to compile the C program and allow it to call a C++ file, I needed to do two things, 1) use the C++ compiler (g++) and make sure to surround my c++ functions with < extern "C">. By doing this I was able to compile and run the application with no issues.
Here are the files that I'm currently using.
cppObject.cpp
cppObject.h
cppFunctions.cpp
cppFunctions.h
test.c
"test.c" is where the main method is, which calls the cppFunctions class, which then references functions within cppObject.cpp. Now I don't think I need to go into each of these functions as I can compile this with no issues, using.
g++ cppObject.cpp cppFunctions.cpp test.c -o test_exc
This generates an executable which runs with no issues.
Now because this is being built with Petalinux, Petalinux generates a recipe-app that includes a bitbake file and a makefile. Which both need to be modified in some way to accomplish my goal.
I'll be using this test case to reference for my main application.
As my C application has mainly been written, compiles, and runs with no issues. I decided to model the makefile and bitbake files after them.
APP = APP_name
# Add any other object files to this list below
APP_OBJS = file1.o \
file2.o \
file3.o \
file4.o \
file5.o \
# ...
all: build
build: $(APP)
LDLIBS += -lm
LDFLAGS += -lpthread
$(APP): $(APP_OBJS)
$(CC) -o $# $(APP_OBJS) $(LDFLAGS) $(LDLIBS)
clean:
rm -f $(APP) *.o
So based on the above makefile I attempted the same thing, using the test applications file names, and g++ instead of gcc
APP = test
# Add any other object files to this list below
APP_OBJS = cppObject.o cppFunctions.o test.o
all: build
build: $(APP)
$(APP): $(APP_OBJS)
$(CXX) -o $# $(APP_OBJS) $(LDFLAGS) $(LDLIBS)
clean:
rm -f $(APP) *.o
Now the bitbake file which matches my original application looks like this.
#
# This file is the **** recipe.
#
SUMMARY = "Simple **** application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://file1.c \
file://file2.c \
file://file3.c \
file://file4.c \
file://file5.c \
file://file2.h \
file://file3.h \
...
"
S = "${WORKDIR}"
do_compile() {
oe_runmake
}
do_install() {
install -d ${D}${bindir}
install -m 0755 **** ${D}${bindir}
}
I ended up making this one for the test application
#
# This file is the test recipe.
#
SUMMARY = "Simple test application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://cppObject.cpp \
file://cppFunctions.cpp \
file://cppObject.h \
file://cppFunctions.cpp \
file://test.c \
file://Makefile \
"
S = "${WORKDIR}"
do_compile() {
oe_runmake
}
do_install() {
install -d ${D}${bindir}
install -m 0755 test ${D}${bindir}
}
The petalinux-build -c for the application fails to build and the main error "test.c:2:10: fatal error: cppFunctions.h No such file or directory"
If I setup the makefile on its own and run make, it will build just fine, if I replace the objectfiles with the C/C++ files instead.
I'm assuming what is happening is Petalinux uses the bitbake file to generate the object files. Which then the Makefile uses to build the actual application.
Any insight that would allow me to use petalinux to build the application.
So caught a error in the .bb file, #vermaete also pointed it out. I left off the cppFunctions.h file. I ended up adding it to the .bb file and rebuilt the recipe. Unfortunately, I'm still getting a build error. However, its different, in that its having issues with an undefined reference.
undefined reference to 'printObjValue'
Which is a function call.

How to do makefile to compile multiple .cpp files in different directories using a single makefile?

I have the following files in my proj2 directories and need to compile them together to have one executable file.
proj2/main.cpp
proj2/model/Player.cpp
proj2/model/gameBoard.cpp
proj2/controller/TTTController.cpp
proj2/Makefile
I'm using the following command inside my makefile, but it is not working.
all:
g++ /project2_p1/main.cpp /project2_p1/controller/TTTController.cpp /model/gameBoard.cpp /model/Player.cpp -o ttt
clean:
-rm ttt
Can anybody help me please.Thank you
I strongly recommend you start learning make as it is one of the fundamental tools that programmers use. And, if you can learn C++, you can definitely learn make.
In your project you have source files buried in their own subdirectories so in order to find them all you can use the $(shell find...) command. Same with any header files in your project.
By making all: the direct target it gets executed unconditionally and you lose the benefits of using make - only compile when you change something.
Having said that the basic template I am providing here could be improved to recompile only those source files that have changed but that's an exercise for the reader.
I think this should work in your case:
# set non-optional compiler flags here
CXXFLAGS += -std=c++11 -Wall -Wextra -pedantic-errors
# set non-optional preprocessor flags here
# eg. project specific include directories
CPPFLAGS +=
# find cpp files in subdirectories
SOURCES := $(shell find . -name '*.cpp')
# find headers
HEADERS := $(shell find . -name '*.h')
OUTPUT := ttt
# Everything depends on the output
all: $(OUTPUT)
# The output depends on sources and headers
$(OUTPUT): $(SOURCES) $(HEADERS)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(OUTPUT) $(SOURCES)
clean:
$(RM) $(OUTPUT)
thats my minGW project's makefile codes:
hepsi: derle calistir
Nesneler := ./lib/Hata.o ./lib/Hatalar.o ./lib/Dugum.o ./lib/ListeGezici.o ./lib/BagilListe.o
derle:
g++ -I ./include/ -o ./lib/Hata.o -c ./src/Hata.cpp
g++ -I ./include/ -o ./lib/Hatalar.o -c ./src/Hatalar.cpp
g++ -I ./include/ -o ./lib/Dugum.o -c ./src/Dugum.cpp
g++ -I ./include/ -o ./lib/ListeGezici.o -c ./src/ListeGezici.cpp
g++ -I ./include/ -o ./lib/BagilListe.o -c ./src/BagilListe.cpp
g++ -I ./include/ -o ./bin/test $(Nesneler) ./src/test.cpp
calistir:
./bin/test
In your project I think this will work;
all: compile run
Objects := ./lib/Player.o ./lib/gameBoard.o ./lib/TTTController.o
compile:
g++ -I ./include/ -o ./lib/Player.o -c ./model/Player.cpp
g++ -I ./include/ -o ./lib/gameBoard.o -c ./model/gameBoard.cpp
g++ -I ./include/ -o ./lib/TTTController.o -c .controller/TTTController.cpp
g++ -I ./include/ -o ./bin/main $(Objects) ./main.cpp
run:
./bin/main
lib folder contains .o files. You can chance it if you want.
include folder refers your header .h or .hpp files. You can change every one of them according to your headers location.
bin folder contains your .exe file called main.exe. You can change or remove it like that
run:
./main
I hope it'll work.
#Galik has right. if you want to learn C++, you should definitely learn make.

Iotivity : Build the C++ examples

I have just started with iotivity and have been reading the documentation. On this setup page, under the heading running the c++ samples, it tells how to run the examples, but before that I should build them first and it seems the page Build the C++ samples it refers to, is missing.
When I tried to build the examples in a normal way using g++, it gave some missing header errors, meaning that's not the right way or will take a lot of effort.
Do any one know how to build the examples packet with iotivity release?
Place the following makefile in the iotivity/resource/examples directory :
IDIR=-I../include -I./../csdk/stack/include/ -I./../c_common/ -I./../oc_logger/include
CC=g++
CFLAGS=-Wall -std=c++11 $(IDIR) -loc -loctbstack -loc_logger -lpthread
SERV_OBJ = simpleserver.o
CLIENT_OBJ = simpleclient.o
%.o: %.cpp
$(CC) -c -o $# $^ $(CFLAGS)
#Build the simpleserver executable
all:simpleserver simpleclient
simpleserver:$(SERV_OBJ)
$(CC) -o $# $^ $(CFLAGS)
#Build the simpleclient executable
simpleclient:$(CLIENT_OBJ)
$(CC) -o $# $^ $(CFLAGS)
and then hit make on the terminal. Then execute simpleclient and simpleserver on two different terminals. In case you get the error :
./simpleclient: error while loading shared libraries: liboc.so: cannot open shared object file: No such file or directory
type the following:
export LD_LIBRARY_PATH=../../out/linux/x86_64/release
I researched a lot to find where the executables get generated for the c++ samples, finally found the path.
On 64-bit Ubuntu 14.04 LTS ,
when iotivity is built as follows:
$ scons
the executables get created in path /iotivity/out/linux/x86_64/release/resource/examples for the code present in /iotivity/resource/examples so you can just go to /iotivity/out/linux/x86_64/release/resource/examples and execute simpleserver(./simpleserver) and simpleclient(./simpleclient)
Check this page about IoTivity supported (and unsupported) examples :
https://wiki.iotivity.org/examples#
cd ${project_dir}/out/${TARGET_OS}/${TARGET_ARCH}/${BUILD_MODE}/resource/examples/
killall simpleserver simpleclient # make sure none are running
./simpleserver 2>&1 | tee simpleserver.log.txt &
./simpleclient 2>&1 | tee simpleclient.log.txt
Some c++ examples are not working in 1.3.0 while 1.2.1 should be ok
But if you want to build other examples from outside the main tree, I made a dedicated project that use gnu make.
Hope this helps

How to "make" an SDL project on linux?

Makefiles are quite confusing to me. I am attempting to "make" my project that I have worked on in Windows. The confusing part is actually constructing the make file from scratch. I would am trying to also link to the SDL2 library, and that is in a '.a' format.
Here is my code for the make file so far, I have tried multiple versions, and this is the latest:
CXX = gcc
OUT = Engine
SRC =Software-Rendering/src/
SDL_INCLUDE_DIR =Software-Rendering/lib/SDL2/include/SDL/
LIB_DIR =Software-Rendering/lib/SDL2/x86/linuxLib/
SDL = -l${LIB_DIR}libSDL -l${LIB_DIR}/libSDL2main
CPP_FILES =Bitmap.cpp Main.cpp Vector3.cpp Window.cpp
H_FILES =Bitmap.h ErrorReport.h Vector3.h Window.h
O_FILES = Bitmap.o ErrorReport.o Main.o Vector3.o Window.o
all: $(OUT)
$(OUT): $(O_FILES)
$(CXX) -o $# $^ ${SDL}
#Making all of the object files down
$(O_FILES): $(H_FILES)
$(CXX) -c $(CPP_FILES)
#Make sure we can easily clean up the directory
clean:
rm -f Engine ${O_FILES}
clean_obj:
rm -f ${O_FILES}
I decided to put the ".a" files in a special directoy in my project so whenever someone clones my repository on github all of the files for compiling and linking are already there.
Why isn't this working and how can I make it work?
Your library linking directive are wrong -- -l prefixes lib to the name you specify, and then searches through the libdir path set by the -L options. So what you want is something like:
SDL = -L$(LIB_DIR) -lSDL -lSDL2main
You can make it clearer/more standard by using the standard varnames for libraries:
LDFLAGS = -L$(LIB_DIR)
LDLIBS = -lSDL -lSDL2main
$(OUT): $(O_FILES)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
Also, get rid of the explicit command to compile source files -- the default built in rule is fine and easier to use.

Makefile target always up to date with code generation

I have a script which generates multiple C++ .h and .cpp files, based on a configuration file. This script also generates a file called 'Makefile.inc', and this file contains a variable with the required object filenames, for the generated .cpp files.
Example of a Makefile.inc file (all paths are absolute):
MESSAGE_OBJS = \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/error-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/challenge-request-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/challenge-response-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/login-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/get-game-list-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/game-list-response-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/join-game-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/connect-to-game-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/leave-game-message.o
Using the answer in this question as base, I created the following Makefile:
# Include the generated makefile for messages.
# This includes a variable with all message targets
include atlarge/messages/Makefile.inc
# Create a variable with all source targets
LIBOBJS = \
atlarge/exceptions.o \
atlarge/message-factory.o \
atlarge/envelope.o \
atlarge/client.o \
atlarge/user.o \
atlarge/atlarge-protocol.o \
atlarge/atlarge-gameserver.o \
$(MESSAGE_OBJS)
CXXFLAGS += -W -Wall -I. -g -O3 -MD \
`pkg-config jansson --cflags` \
`libgcrypt-config --cflags` \
`pkg-config glib-2.0 --cflags` \
-fPIC -DDEBUG -DENABLE_LOGGING
PREFIX = /usr/local
# TODO use pkg-config for jansson
LDLIBS += -lm -ljansson -latlarge-util `libgcrypt-config --libs` `pkg-config glib-2.0 --libs`
LDFLAGS += -shared -L/usr/local/lib
# Include automatically generated dependencies
-include $(LIBOBJS:.o=.d)
all: libatlarge.so
# If the message Makefile doesn't exist yet, generate it
atlarge/messages/Makefile.inc: atlarge/messages/messages.conf
python ../common/messagegen.py -o ./atlarge/messages/ atlarge/messages/messages.conf
libatlarge.so: $(LIBOBJS)
$(CXX) $(LDFLAGS) -o $# $^ $(LDLIBS)
clean:
#rm -f *.o
#rm -f atlarge/*.o
#rm -f atlarge/messages/*.o
#rm -f atlarge/messages/*.cpp
#rm -f atlarge/messages/*.h
#rm -f atlarge/messages/Makefile.inc
#rm -f atlarge/*.d
#rm -f atlarge/messages/*.d
#rm -f *.d
#rm -f ../common/*.d
#rm -f ../common/*.o
#rm -f *.a
#rm -f *.so
#rm -f tags
install: libatlarge.so
#install -m 0644 $^ $(PREFIX)/lib
#install -m 0755 -d $(PREFIX)/include/atlarge
#install -m 0755 -d $(PREFIX)/include/atlarge/messages
#install -m 0644 -D atlarge/*.h $(PREFIX)/include/atlarge
#install -m 0644 -D atlarge/messages/*.h $(PREFIX)/include/atlarge/messages
#ldconfig
#echo "Installed"
.PHONY: all clean install splint messages
As you can see, I first include the generated Makefile.inc. Then a variable with all library object files is defined, and this variable makes use of the variable declared in the generated Makefile.inc. After that some variables with compiler flags are declared.
To make use of Makefile remaking, I included a target rule for the generated Makefile.inc, so if the dependency of Makefile.inc (the configuration file) is newer than Makefile.inc, it gets regenerated, and Make will restart itself.
So this is the goal:
Check if Makefile.inc needs to be (re)generated.
Include it
Use the variable inside Makefile.inc in the $LIBOBJS variable in the main Makefile.
And this actually works. If I update the messages.conf file, Make detects that, and will run the python script. It will then restart itself, include the new Makefile.inc, and then proceed with compiling.
But here comes the part that doesn't work: if I don't update the messages.conf file, but only .h or .cpp files which are by default in the $LIBOBJS list, Make will not proceed to compile.
For example, if alter client.cpp and no other files, I get the following error:
make: `atlarge/exceptions.o' is up to date.
Well yeah, great you found out that exceptions.o is up to date, but I altered client.cpp, so why don't you start compiling that one? Why does make quit immediatly after seeing that the first target in LIBOBJS is up to date?
Who knows what's causing this, and what could be a solution? Is there maybe a better way to handle code generation with makefiles?
Thanks in advance.
NB: I also use dependency files generated by gcc, and that was working fine before I added the code generation, so I don't think that's a problem.
You need to move the all target to come BEFORE the include. Make always builds the first target it sees in the makefile unless you give a specific target on the command line. Since the include comes before any target, the first target defined in Makefile.inc will be the default target and when you run make that's the one that will be built. That's why it tries to build exceptions.o and then stops. If you run make all explicitly, it will work as you expect.
Where is the dependency for the object files on the source files
or the header files? There is an implicit rule which should
pick up the dependencies if the .cpp file is in the same
directory as the .o, but if they're not, you'll have to
provide your own, or use VPATH (see §4.5.1 in the manual). And
you also need to generate the dependencies for the includes, see
§4.1.4 in the manual.