Trying to use Paho C client library for MQTT with Cmake - c

I have a simple test project to try and include the mqtt library but cant seem to get it working.
Here's my directory structure:
test/
build/
paho.mqtt.c/
CMakeLists.txt
main.c
Here's my CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
# set the project name
project(mqtt)
add_executable(${PROJECT_NAME} main.c)
add_subdirectory(paho.mqtt.c)
target_include_directories(
${PROJECT_NAME}
PUBLIC paho.mqtt.c/src
)
target_link_directories(
${PROJECT_NAME}
PUBLIC paho.mqtt.c/src
)
target_link_libraries(${PROJECT_NAME}
paho.mqtt.c
)
When I try and include MQTTAsync.h into main.c the output from my terminal reads
/usr/bin/ld: cannot find -lpaho.mqtt.c
If anyone can help it would be greatly appreciated. I'm new with CMake and C programming so forgive me for being a noob.

Related

Cannot properly include header file in executable file via CMake

I'm trying to run a project with such structure:
I have this CMake code:
cmake_minimum_required(VERSION 3.19)
project(Random C)
set(CMAKE_C_STANDARD 99)
add_executable(Main usage.c include/random.h source/random.c)
include_directories(include)
And I have this error in random.c:
BUT I don't have it in usage.c:
What is going on here?

Linker cannot find library from another project

guys,
I am relatively new to CMake and now I have a bug that I don't understand. Actually I thought I had no problems understanding the terms static and shared library and the functions of CMake. But currently...
So in my project projB I wanna use a static_library from project projA. ProjA is already compiled, linked, installed and used on my board. For ProjB the linker cannot find the library "example".
My issue: for me, i doesn't make sense why projA can find the shared library, projB not.
The error code:
Linking main ....
ld: cannot find -lexample
error: ld returned 1 exit status
My folder structure of projA:
include/ ... *.h (e. g. file.h)
src/ ... *.c (e. g. file.c)
CMakeFiles.txt
The CMakeLists.txt-File of projA:
cmake_minimum_required(VERSION 3.7)
PROJECT(projA)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_definitions(-g -O)
include_directories (include)
file (GLOB SOURCE_FILES src/*.c)
add_library (example STATIC ${SOURCE_FILES})
target_include_directories(example PUBLIC ${SOURCE_DIR}/include)
install(TARGETS example ARCHIVE DESTINATION usr/lib)
So projA will be later a library-component which can be used in many other projects. That's the reason why the created library is not part of projB and why I wanna import/include the created example.a file in a lot of other projects. The static library example.a should be stored in usr/lib.
In my projB the folder structure looks like:
CMakeFiles.txt
main.c
.... *.c
In my main.c-File I try to include the library with #<file.h> which is a part of my created library example.
The CMakeFiles.text of ProjB containing following Code:
cmake_minimum_required(VERSION 3.7)
PROJECT(projB)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set (CMAKE_C_STANDARD 99)
set (CMAKE_CXX_STANDARD 14)
add_definitions(-g -O -fpermissive)
# build executable
file (GLOB SOURCES *.c )
add_executable (exe ${SOURCES})
# target_include_directories(exe PUBLIC ${CMAKE_SOURCE_DIR}/usr/lib)
# add_library(example SHARED IMPORTED)
# set_property(TARGET example PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/usr/libexample.a)
target_link_libraries (exe example pthread)
install (TARGETS exe RUNTIME DESTINATION usr/sbin)
An attempt to find the error is commented out. I also worked with find_library(), but the library "example" could not be found. Of course I also built the library example as a shared_library and searched for a .so, etc.
As you can see from my example, this is not real code (used in production), but a simplified description of my problem. I am more interested in the systematic. Wrong thinking?
Does anyone have any idea what else I can try or why it doesn't work?
Is it because they are different projects? I mean, the file exists on my system, but is not found ...
Thanks a lot for your help!
Greetings
Matthias

Cannot find API header file for shared library with cmake

I am building a shared library in one project and using it in another. They share a prefix, but I'm not building them together (e.g., <prefix>/mylib and <prefix>/myproject). Both mylib and myproject have src and include directories.
The CMakeList.txt for the shared library:
cmake_minimum_required(VERSION 3.5)
project(mylib)
add_library(mylib SHARED
src/mylib.c
)
target_include_directories(mylib PRIVATE include)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER include/mylib.h)
install(TARGETS
mylib
LIBRARY DESTINATION lib
PUBLIC_HEADER DESTINATION include
RUNTIME DESTINATION bin)
This results in mylib.so being installed in install/mylib/lib/mylib.so and mylib.h being installed in install/mylib/include/mylib.h, which is what I intended.
I then want to build a project that uses mylib:
#include "mylib.h"
int main(void)
{
// use some functions in mylib
}
The associated CMakeList.txt file for main.c:
cmake_minimum_required(VERSION 3.5)
project(myproject)
find_package(mylib REQUIRED)
add_executable(myproject src/main.c)
target_link_libraries(myproject mylib)
install(TARGETS
myproject
DESTINATION lib/${PROJECT_NAME})
This produces:
main.c: fatal error: mylib.h: No such file or directory
#include "mylib.h"
^~~~~~~~~
If I change CMakeList.txt to include the following:
find_path(MYLIB_INCLUDE_DIR mylib.h)
...
target_include_directories(myproject PUBLIC ${MYLIB_INCLUDE_DIR})
Then it finds the header, but not the library. I get a linker error:
/usr/bin/ld: cannot find -lmylib
If I change CMakeList.txt to include the following:
find_library(MYLIB_LIB mylib)
...
target_link_libraries(myproject ${MYLIB_LIB})
Then it builds.
I (think I) understand why finding the library and include files manually works, but that seems to be the wrong way to go about things...
find_package(mylib) does seem to find the mylib package (I can print cmake cache variables and mylib_FOUND=1), but doesn't find the library and header in such a way that they are built with myproject.
You need to specify include directories for both "build" and "install" variants in target_include_directories in your library project:
target_include_directories(mylib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> # build variant
$<INSTALL_INTERFACE:include> # install variant
)
BTW, such example is provided in documentation for target_include_directories command.
Additionally, you need to EXPORT the library during installation:
install(
TARGETS mylib
EXPORT mylib
LIBRARY DESTINATION lib
PUBLIC_HEADER DESTINATION include
RUNTIME DESTINATION bin)
See this answer for a tutorial on exporting libraries with cmake.

CMake subdir library and main project

This is an example, I googled a lot for this today but I cannot find a good way for have this thing done.
For example I followed what's written in this link: http://mirkokiefer.com/blog/2013/03/cmake-by-example/
I have
/Build
/Src
=> main.c
/Lib
=> File.c
=> File.h
I have a CMakeLists.txt in the Src dir
SET(SOURCES
main.c
)
add_subdirectory(Lib)
ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCES})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} lib)
and in the Lib dir:
set(LibSrc
File.c
)
set(LibHead
File.h
)
add_library(lib STATIC ${LibSrc} ${LibHead})
target_include_directories(lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
When I compile the project everything compile corretly, but when the gcc links the library with the rest of the project I receive an error like:
main.cpp:(.text+0x10): undefined reference to `test()`
It is driving me crazy... Any hints on where I'm doing it wrong? Thank you
It looks like your target_link_libraries command is missing the list of dependencies. I guess in your case, you just want to link "lib", so you need to change this to:
target_link_libraries(${PROJECT_NAME} lib)
As an aside, you're missing a $ before {CMAKE_CURRENT_SOURCE_DIR} in the line
target_include_directories(lib PUBLIC {CMAKE_CURRENT_SOURCE_DIR})

C: How to add Ncurses and Math Flags into CMakeLists.txt

I'm importing a C project into the Clion IDE, that uses Cmake.
My project uses these external libraries: Math and Ncurses.
However i'm not able to get the script CMakeLists.txt working.
This is the script:
cmake_minimum_required(VERSION 2.8.4)
project(thegame)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lncurses -lm")
set(SOURCE_FILES thegame.c ./src/headers/set.h ./src/headers/functions.h ./src/headers/game.h ./src/headers/heap.h ./src/headers/lib.h
./src/headers/parser.h ./src/headers/pathfind.h ./src/headers/structures.h
./src/functions.c ./src/game.c ./src/heap.c ./src/lib.c ./src/parser.c ./src/pathfind.c ./src/set.c
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "~/Binaries")
add_executable(thegame ${SOURCE_FILES})
I'm getting a lot of messages like this:
thegame.c:(.text.startup+0x1c): undefined reference to "mousemask"
...
What I'm doing Wrong?

Resources