Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add wiringPi lib to cmake on RaspberryPi

for my project in c++ I wanted to create a cmake file to compile and link everything together.
This is my dir structure so far:

"quadro/minimu9-ahrs" alias home
|-build
|-include
|-src

in my home dir I have this 'CMakeLists.txt' file:

cmake_minimum_required (VERSION 2.6)
project(minimu)

set(HEADER_FILES $("include/*.h")
include_directories(include)
file(GLOB SOURCES "src/*.cpp")

add_executable(minimu ${SOURCES})
add_definitions(-std=c++0x -lwiringPi -lpthread)

#install(TARGETS minimu DESTINATION /usr/lib)

in my 'src' dir I got all the .cpp files, and in 'include' all my headers. When I'm comiling, I go into my build dir, delete everything existing in there (from previous builds) and type

cmake ..
make

my problem in now, that my main.cpp in src uses '#include wiringPi.h', but when I make the project it gives me the following error:

pi@raspberrypi ~/quadro/minimu9-ahrs/build $ make
Scanning dependencies of target minimu
[ 20%] Building CXX object CMakeFiles/minimu.dir/src/L3G.cpp.o
[ 40%] Building CXX object CMakeFiles/minimu.dir/src/LSM303.cpp.o
[ 60%] Building CXX object CMakeFiles/minimu.dir/src/main.cpp.o
[ 80%] Building CXX object CMakeFiles/minimu.dir/src/I2CBus.cpp.o
[100%] Building CXX object CMakeFiles/minimu.dir/src/MinIMU9.cpp.o
Linking CXX executable minimu
CMakeFiles/minimu.dir/src/main.cpp.o: In function `frequency_thread(void*)':
main.cpp:(.text+0x1c): undefined reference to `digitalWrite'
main.cpp:(.text+0x38): undefined reference to `digitalWrite'
CMakeFiles/minimu.dir/src/main.cpp.o: In function `signalHandler(int)':
main.cpp:(.text+0xd4): undefined reference to `digitalWrite'
main.cpp:(.text+0xe8): undefined reference to `digitalWrite'
CMakeFiles/minimu.dir/src/main.cpp.o: In function `main':
main.cpp:(.text+0x14c): undefined reference to `wiringPiSetup'
main.cpp:(.text+0x184): undefined reference to `pinMode'
main.cpp:(.text+0x1e8): undefined reference to `pthread_create'
main.cpp:(.text+0x29c): undefined reference to `pthread_join'
collect2: ld returned 1 exit status
CMakeFiles/minimu.dir/build.make:185: recipe for target 'minimu' failed
make[2]: *** [minimu] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/minimu.dir/all' failed
make[1]: *** [CMakeFiles/minimu.dir/all] Error 2
Makefile:72: recipe for target 'all' failed
make: *** [all] Error 2

so how do I tell the compiler in cmake where to find and how to use the wiringPi lib? And is there an easier way, instead of deleting everything in my build folder before cmaking? Like it compiles all the 'static' files one time, and only adds the changing file (=main.cpp) everytime again.

Further I want to execute my program everywhere like

sudo minimu

instead of going into the 'build' dir and type

sudo ./minimu

Thanks if you can help me guys!
And sorry if my english isn't that good :)
Have a nice day.

like image 840
julianmueller Avatar asked May 24 '15 13:05

julianmueller


3 Answers

I just figured this out today thanks to Sebastian over at github.

Assuming that you have wiringPi installed, the easiest thing to do is to make a FindWiringPi.cmake with the following:

find_library(WIRINGPI_LIBRARIES NAMES wiringPi)
find_path(WIRINGPI_INCLUDE_DIRS NAMES wiringPi.h)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(wiringPi DEFAULT_MSG WIRINGPI_LIBRARIES WIRINGPI_INCLUDE_DIRS)

And then put this in the folder where cmake looks for it's modules. For Ubuntu it's /usr/share/cmake-2.x/Modules. It's basically the same path for pi too.

Then in your CMakeLists.txt file use:

# Locate libraries and headers
find_package(WiringPi REQUIRED)
find_package(Threads REQUIRED) 

# Include headers
include_directories(${WIRINGPI_INCLUDE_DIRS}) 

# Link against libraries
target_link_libraries(<yourProjectName> ${WIRINGPI_LIBRARIES}) 
target_link_libraries(<yourProjectName> ${CMAKE_THREAD_LIBS_INIT}) 

The pthread module is a stock package and should be on your system already. So then navigate to your folder and do a cmake ./ and then make. If this doesn't work the first time, then remove your CMakeCache.txt with rm CMakeCache.txt and try again. MAKE SURE THAT YOU REMOVE THE CACHE AND NOT THE LIST!!

like image 173
Ethan Plummer Avatar answered Nov 15 '22 03:11

Ethan Plummer


Thanks for the QA, I figured out this can be done in a simpler manner (Raspberry Pi 3 Model B+) without altering anything in /usr/share/cmake-x.y/Modules. After your add_executable line, add the following

find_library(WIRINGPI_LIBRARIES NAMES wiringPi)
target_link_libraries(<executable_name> ${WIRINGPI_LIBRARIES})

For example:

cmake_minimum_required(VERSION 3.5)
project(OpenInsulin)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_VERBOSE_MAKEFILE ON)

# Include headers
include_directories(.)

add_executable(OpenInsulin
        main.cpp
        MCP9600.cpp
        MCP9600.h)

# Link against wiringPi
find_library(WIRINGPI_LIBRARIES NAMES wiringPi)
target_link_libraries(OpenInsulin ${WIRINGPI_LIBRARIES})
like image 29
Isaiah Becker-Mayer Avatar answered Nov 15 '22 04:11

Isaiah Becker-Mayer


Provide a flag -L <path> to compiler flags.

add_definitions(-std=c++0x -L/path/to/libwringPi.???.(so|a) -lwiringPi -lpthread)

I do not understand, why you clear the build dir before running cmake (this is not critique. I really do not understand, There might be a reason I dont know) . make checks if the sources are newer than the last compile output and compiles only the files, that are affected. But this works only, if do not delete the build targets.

To install the resulting program uncomment the install directive in you cmake and setup a target dir that's in you PATH. You can also create a dir /home//bin or so. Prepend it to the PATH environment variable and configure the target of you install directive with the new path. Then, in addition to cmake and make you have to perform a make install.

like image 23
Peter Paul Kiefer Avatar answered Nov 15 '22 02:11

Peter Paul Kiefer