On esp32, using esp-idf, I built a module called webSocket.c/.h .
it includes
#include "esp32/sha.h"
As this module is generic, I want to put it in a component. I moved it to
"components/webSocket" directory and added a CMakeLists.txt file like this:
FILE(GLOB cFiles *.c)
set(
COMPONENT_SRCS
${cFiles}
)
set(COMPONENT_ADD_INCLUDEDIRS
"."
)
register_component()
From this point, the module does not compile anymore because the above included file is unreachable.
This module is part of esp-idf framework, or more accurately, part of mbedtls lib which is embedded in esp-idf framework.
I tried all these path without success:
mbedtls/port/include/esp32/sha.h
port/include/esp32/sha.h
include/esp32/sha.h
esp32/sha.h
sha.h
None is successfull, how should I do?
Added
set(COMPONENT_REQUIRES mbedtls)
to CMakeLists did the trick.
Related
I'm following a tutorial on CMake and I have problems understanding the necessity of using the 'include_directories' command at one point.
Let me explain the project first:
In my working directory I have:
- a main.cpp function, a CMakeLists.txt(the main one), a configuration file, a 'MathFunction' directory and a 'build' directory
In the MathFunction directory I have:
- a CMakeLists.txt file that will be invoked by the main one
- A file 'mysqrt.cxx' that contains the implementation of a function which will be used in 'main.cpp' application
- A 'MathFunctions.h' header file that contains the prototype of that function
In the CMakeLists from 'MathFunction' directory I'm creating a library using code from 'mysqrt.cxx' like this:
add_library(MathFunctions mysqrt.cxx)
This snippet is a part of my main CMake code:
# add the MathFunctions library?
#
if (USE_MYMATH)
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") # WHY DO WE NEED THIS
add_subdirectory (MathFunctions)
set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
add_executable(Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions)
Now I do not understand why I need too add that 'include_directories' command in order to use the library? Shouldn't it be enough that the last command 'target_link_libraries' links the already created executable and libraries togheter so there would be no need to also include_directories?
Thank you for reading and I'm sorry if I have not explained it very well but I hope you will understand what I mean :D
Command include_directories sets directories for header files (.h) to be searched. Linking (target_link_libraries) with a library basically specifies only a library file (.so, .dll or other type). As you see, these are different things.
When linking executable with a library target, CMake propagates (more precisely, "consumes") some properties of that library target to the executable. Among these properties there is INTERFACE_INCLUDE_DIRECTORIES property, which adds include directories to the executable.
So, when a library target has INTERFACE_INCLUDE_DIRECTORIES property correctly being set, you don't need to explicitly specify include directories for executable:
MathFunctions/CMakeLists.txt:
add_library(MathFunctions mysqrt.cxx)
# Among other things, this call sets INTERFACE_INCLUDE_DIRECTORIES property.
target_include_directories(MathFunctions PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
CMakeLsits.txt:
add_executable(Tutorial tutorial.cxx)
# This also propagates include directories from the library to executable
target_link_libraries (Tutorial MathFunctions)
Note, that using simple
# This *doesn't* set INTERFACE_INCLUDE_DIRECTORIES property.
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
in MathFunctions/CMakeLists.txt doesn't imply propagating include directories to the linked executable.
I have a CMake project that looks like this:
project/
CMakeLists.txt
subprojectA/
CMakeLists.txt
include/
headerA.hpp
src/
libraryA.cpp
subprojectB/
CMakeLists.txt
src/
mainB.cpp
The "library" subproject, A, is compiled as a static library, becoming libsubprojectA.a. The "main" project, B, is compiled as a binary and depends on the library. mainB.cpp includes a reference to headerA.hpp.
Here is subprojectA/CMakeLists.txt:
project(SubProjectA)
include_directories(include)
add_library(subprojectA STATIC src/libraryA.cpp)
set(${PROJECT_NAME}_INCLUDE_DIRS
${PROJECT_SOURCE_DIR}/include
CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
And here is subprojectB/CMakeLists.txt:
project(SubProjectB)
include_directories(${SubProjectA_INCLUDE_DIRS})
add_executable(mainBinary src/mainB.cpp)
target_link_libraries(mainBinary subprojectA)
The main Project CMakeLists.txt looks like:
project(Project)
add_subdirectory(subprojectB)
add_subdirectory(subprojectA)
Note that subprojectB, the main project, is listed before subprojectA.
Here's the problem. When I first run "cmake" on this project, ${SubProjectA_INCLUDE_DIRS} is not set within SubProjectB.
What I think is happening is that the CMakeLists for SubProjectB loads first, when ${SubProjectA_INCLUDE_DIRS} has not yet been set. It sets its own include path to an empty string as a result. However, even though libsubprojectA.a gets built successfully before mainBinary, the include path was already set empty beforehand. As a result, I get this error when trying to make mainBinary:
subprojectB/src/mainB.cpp:1:23: fatal error: headerA.hpp: No such file or directory
#include "headerA.hpp"
^
It's a workaround to put subprojectA before subprojectB in the main Project CMakeLists in the declarative world of CMake. What I really want is to know the proper way to indicate to CMake that the include_directories(${SubProjectA_INCLUDE_DIRS}) line depends on the definitions that exist inside SubProjectA's CMakeLists. Is there a better way to do this?
If you want to express that include directory subprojectA/include is an interface of the library subprojectA, attach this property to the target with target_include_directories command:
subprojectA/CMakeLists.txt:
project(SubProjectA)
add_library(subprojectA STATIC src/libraryA.cpp)
# PUBLIC adds both:
# 1) include directories for compile library and
# 2) include directories for library's interface
target_include_directories(subprojectA PUBLIC include)
So any executable(or other library) which linked with subprojectA will have this include directory automatically:
subprojectB/CMakeLists.txt:
project(SubProjectB)
add_executable(mainBinary src/mainB.cpp)
target_link_libraries(mainBinary subprojectA)
Of course, for use last command properly you need to process directory with library before one with executable:
CMakeLists.txt:
project(Project)
add_subdirectory(subprojectA)
add_subdirectory(subprojectB)
I compiled all the information and now iam trying to implement CMake build system for a super project and i really need a guidance here,it would be great to transform all data i acquired by reading about CMake across different sites to practical knowledge
i have a fundamental questions regarding understating CMake Targets
In case of multi directories structure,i want to achieve most portability thus having target for each directory and then use these different targets as link for others in another directories, my goal is to be agile as possible and not be coupled with a certain directory structure, make use of CMake to figure the dependency, where i would be only concerned about targets
my final target is a library of libraries
USE CASE :
First level directory {PROJECT} ( 2 folders ) :
CMakeLists.txt common_env source
First level CMakeLists.txt :
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(dassys)
# iam using this because target scope change with sub-directory
include(common/CMakeLists.txt)
include(src/CMakeLists.txt)
#Add Library
add_library(dassys INTERFACE)
#Creating library
target_link_libraries(dassys INTERFACE
common
src
)
Second Level directory {{PROJECT} /common}(2 folders 1 file ):
cfgd_*** CMakeLists.txt dstdh header.h
Second Level CMakeLists.txt
#Adding Subdirectory
include(${CMAKE_CURRENT_LIST_DIR}/dstdh/CMakeLists.txt)
include(${CMAKE_CURRENT_LIST_DIR}/cfgd_***/CMakeLists.txt)
#add_subdirectory(dstdh)
#add_subdirectory(cfgd_***)
#Add Library
add_library(common INTERFACE)
#Creating library
target_link_libraries(common INTERFACE
dstdh
cfgd_***
)
----------------------------------------------------------------------------------------------------------------------------------
Thrid Level directory { {PROJECT} /common/dstdh }(6 files ):
CMakeLists.txt dassert.h dfloat.h dstdbit.h dstdbool.h dstdint.h dstdio.h dstring.h
Thrid Level CMakeLists.txt
#Adding Library
add_library(dstdh INTERFACE )
target_sources(dstd INTERFACE
${CMAKE_CURRENT_LIST_DIR}/dassert.h
${CMAKE_CURRENT_LIST_DIR}/dfloat.h
${CMAKE_CURRENT_LIST_DIR}/dstdbit.h
${CMAKE_CURRENT_LIST_DIR}/dstdbool.h
${CMAKE_CURRENT_LIST_DIR}/dstdint.h
${CMAKE_CURRENT_LIST_DIR}/dstdio.h
${CMAKE_CURRENT_LIST_DIR}/dstring.h
)
#Add include for Header only library
target_include_directories(dstdh INTERFACE
"${CMAKE_CURRENT_LIST_DIR}/dstdh/"
)
and here is my question, i need to link against dstd library in another directory
how can this be done because as far as i understand
target_link_libraries ( mylib dstd ) should work in different directory because i have target which is dstd INTERFACE library, and i need Cmake to resolve this dependency by finding this target and link against it
i get compilation error as dstdint.h is not found when mylib is being compiled
I have a library project whose hierarchy looks something like this:
Root:
+ src/
+ apple.cpp
+ bananas/
+ bananas.cpp
...
+ include/
+ apple.h
+ bananas/
+ bananas.h
...
I've been using Visual Studio to compile it and it works fine but now I want to diversify it by allowing the library to be compiled using CMake. I've created the following CMakeLists.txt file (located in Root):
cmake_minimum_required(VERSION 2.8) # Version 2.8 required
file(GLOB_RECURSE HEADERS # Fetch all of the Lib's Headers
${CMAKE_CURRENT_SOURCE_DIR}/include/*.h
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp
)
file(GLOB_RECURSE SOURCES # Fetch all of the Lib's Srcs
${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
)
add_library( # Create the Library from Srcs
HoneycombGameEngine ${SOURCES}
)
target_include_directories( # Add the Headers to the Lib
HoneycombGameEngine
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
It compiles with CMake and generates its files, however when I run make to actually compile the library, I get an error in the bananas.cpp file (first file it chooses to compile) that it cannot find the bananas.h header file. If it is relevant, the bananas.cpp include header statement looks like this:
#include "..\..\include\bananas\bananas.h"
I'm not exactly sure what I'm doing wrong, this my first time using CMake so I mostly wrote my CMakeLists file using bits and examples from the internet. Anything that could point me in the right direction and help me solve this issue is much appreciated.
You are only get all .h inside include directory.
Bananas.h is inside bananas directory. Then you have to use something like it:
file(GLOB_RECURSE HEADERS # Fetch all of the Lib's Headers
${CMAKE_CURRENT_SOURCE_DIR}/include/*.h
${CMAKE_CURRENT_SOURCE_DIR}/include/bananas/*.h
)
I started with the following directory structure:
project
exec
executable.exe
lib
src
include
config
<cmake-generated config file>
I created the library in the lib/src folder by using a CMakefile in the lib/src folder. The exe would compile.
Then, I moved my CMakeFile up to /lib, making sure to change the source file paths to /src/*
Now, when I try to compile, all my libraries compile and link fine, but when I try to link the executable, I get /usr/bin/ld: cannot find -lconfig.
Does anyone have any idea why this happens or how to fix it?
Here is some of my code:
./CMakeLists.txt:
include_directories(config)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
ADD_SUBDIRECTORY(libs) #library sources
ADD_SUBDIRECTORY(exec) #executable sources
CONFIGURE_FILE(${core_SOURCE_DIR}/config/config.h.in
${core_SOURCE_DIR}/config/config.h)
./libs/CMakeLists.txt:
file(GLOB src ...)
file(GLOB header ...)
add_library(lib ${src} ${header})
./exec/CMakeLists:
add_executable(executable executable.cpp)
link_directories(${core_SOURCE_DIR}/lib) #not sure if this is required
target_link_libraries(executable ${lots_of_libs})
Every library in lots_of_libs can be found as a .a file in the lib directory
One problem, probably not risolutive, is this:
link_directories(${core_SOURCE_DIR}/lib) #not sure if this is required
should be:
link_directories(${PROJECT_BINARY_DIR}/lib)
or:
link_directories(${LIBRARY_OUTPUT_PATH})
Anyway, normally you wouldn't need to add to your link_directories the path to a library that is built within the project, even if you have specified a different LIBRARY_OUTPUT_PATH