I am new to CMake and was hoping to use a pretty simple Raspberry Pi application as a learning experience. I have a few files in a simple directory structure, plus I'm using pigpio. My code compiles fine by itself, but when I use CMake to generate a makefile, the makefile cannot find the references in pigpio. pigpio includes a file, Findpigpio.cmake
, in the util
directory, so I tried including it in CMakeLists.txt
, but to no avail.
File structure:
RPapp
├──inc/
| ├──spi.h
| └──gpio.h
├──src/
| ├──spi.c
| ├──gpio.c
| └──main.c
├──pigpio/
| ├──util/
| | ├──Findpigpio.cmake
| | └──[whatever else is in here]
| └──[remainder of code cloned from github]
└──CMakeLists.txt
Here is my CMakeLists.txt
:
cmake_minimum_required(VERSION 3.0.0)
project(RPapp C)
include(pigpio/util/Findpigpio.cmake)
include_directories(inc)
set(CMAKE_C_STANDARD 11)
add_executable(RPapp ${PROJECT_SOURCE_DIR}/src/main.c ${PROJECT_SOURCE_DIR}/src/gpio.c ${PROJECT_SOURCE_DIR}/src/spi.c)
I mkdir _build
, cd _build
, and cmake ..
, which gives very promising output:
-- The C compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found pigpio: /usr/local/include
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/RPapp/_build
but then when I run make, the output shows that it cannot reference the functions from pigpio:
Scanning dependencies of target RPapp
[ 25%] Building C object CMakeFiles/RPapp.dir/src/main.c.o
[ 50%] Building C object CMakeFiles/RPapp.dir/src/gpio.c.o
[ 75%] Building C object CMakeFiles/RPapp.dir/src/spi.c.o
[100%] Linking C executable RPapp
/usr/bin/ld: CMakeFiles/RPapp.dir/src/main.c.o: in function `main':
main.c:(.text 0x38): undefined reference to `gpioTerminate'
/usr/bin/ld: CMakeFiles/RPapp.dir/src/main.c.o: in function `buff_rdy_handler':
main.c:(.text 0x88): undefined reference to `spiRead'
...(more of the same)
CodePudding user response:
I don't actually know about pigpio specifically. But from a pure cmake perspective you need to pull in the pigpio CMakeLists.txt and add that library as a link dependency. The include(pigpio/util/Findpigpio.cmake)
is unnecessary.
cmake_minimum_required(VERSION 3.0.0)
project(RPapp C)
# removed following line
#include(pigpio/util/Findpigpio.cmake)
include_directories(inc)
set(CMAKE_C_STANDARD 11)
add_executable(RPapp ${PROJECT_SOURCE_DIR}/src/main.c ${PROJECT_SOURCE_DIR}/src/gpio.c ${PROJECT_SOURCE_DIR}/src/spi.c)
# added these lines
add_subdirectory(pigpio)
target_link_libraries(RPapp pigpio)
CodePudding user response:
I'm posting an answer to my own question in case someone else is as misguided as I was. I should have been thinking about CMake more in terms of creating makefiles. If you don't do this frequently, and are trying to learn CMake, I recommend trying to put together a manual makefile for your example project first, then going through the process. I'm not sure why I was trying to learn CMake as though it has no connections to makefiles... not useful.
@kaylum is correct in his response, but there were other things I was missing as well. For starters, there was no point cloning pigpio into the file structure for the project - I already had it installed and could just link it as a library to the target. Likewise, even when I got it to try to (unnecessarily) build pigpio at build time, I still was missing a couple of dependencies. Anyway, here is one possible, simple CMakeLists.txt
file that can do the job I was trying to do:
# RPapp/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(RPapp C)
find_package(Threads)
include_directories(inc)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O2")
add_executable(RPapp ${PROJECT_SOURCE_DIR}/src/main.c ${PROJECT_SOURCE_DIR}/src/gpio.c ${PROJECT_SOURCE_DIR}/src/spi.c)
target_link_libraries(RPapp pigpio rt)
install(TARGETS RPapp DESTINATION bin)