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.
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!!
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})
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With