CMake macro inclusion issue - macros

The aim is to have small and useful libraries included into a main application.
I create a CMakeLists.txt file to create three different library : image, utils_dir and utils_geom. The thing that bother me is the horrible redundancy with the target definition. So I tried to create some macro and I'm confronted to an inclusion issue.
The pattern of my project is presented below.
src/CMakeLists.txt (main CMakeLists including subdirs)
src/cmake/Macro.cmake (containing macro)
src/libs/core/CMakeLists.txt (library def and macro use)
I can't include my Macro.cmake file which contain the macro definition.
With the following code in the top level CMakeLists.txt (in src/) :
include(Macro.cmake)
test_macro()
And in the Macro.cmake :
macro( test_macro )
MESSAGE("Success !")
endmacro
I've got :
CMake Error at libs/core/CMakeLists.txt:8 (include):
include could not find load file:
Macro.cmake
CMake Error at libs/core/CMakeLists.txt:9 (test_macro):
Unknown CMake command "test_macro".
Did someone is using a likely configuration ?

Related

How to add an ESP-IDF library to an external library

I'm trying to add an external library into my project.
My projectstructure looks like this:
-project
-- main
--- main.c
--- displayfunctions.c (where i implement my Displayfunctions based on the library)
--- 2 other .c files which got nothing to do with my Display
--- CMakeLists.txt
-- components
--- displaylibrary
---- CMAKELists.txt
---- all displayrelevant librarys pngle.c fontx.c etc..
---- include
----- all corresponding header files pngle.h fontx.h etc.
my CMakeLists.txt file in project/components/displaylibrarys looks like this:
idf_component_register(SRCS "pngle.c" "decode_jpeg.c" "decode_png.c" "fontx.c" "ili9340.c"
INCLUDE_DIRS "include" )
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
when i try to compile my project I get the following Error Message:
../components/Displaylibrarys/fontx.c:7:10: fatal error: esp_spiffs.h: No such file or directory #include "esp_spiffs.h"
so apparantly my compiler does not link the in my external library included esp-idf library with an actual esp-idf library. I tried it with this approach too
idf_component_register(SRCS "pngle.c" "decode_jpeg.c" "decode_png.c" "fontx.c" "ili9340.c"
INCLUDE_DIRS "include"
REQUIRES esp_spiffs)
but without a result. How should i properly tell my compiler that it knows this library?
The ESP-IDF build system works with components. Your library is a component, and so are many parts of the ESP-IDF library.
As part of the component approach, your component needs to declare what other components it depends on. That's what the REQUIRES clause is for.
You almost got it right except the the component is called spiffs instead of esp_spiffs.
idf_component_register(SRCS "pngle.c" "decode_jpeg.c" "decode_png.c" "fontx.c" "ili9340.c"
INCLUDE_DIRS "include"
REQUIRES spiffs)
I usually check the ESP-IDF components directory to figure out the correct name. The component and directory name are the same: https://github.com/espressif/esp-idf/tree/master/components

How to link my .h and .c files in the same project but different directory using CMake

I'm currently working on an embedded C project in Eclipse, cross-compiling to an M4 Cortex target. This project will create 3 separate executable files: apple.hex, orange.hex, and pear.hex. The "apple" source directory compiles, builds, and links without any dependencies on "orange" or "pear". The "orange" source directory also compiles, builds, and links without any dependencies.
However, "pear" needs to access numerous .h and .c assets from "orange". I've had many attempts at getting my CMakeLists.txt to "find" and "link" the code from "orange" to "pear", but to no avail.
Here is my current CMakeLists.txt file:
cmake_minimum_required(VERSION 3.0)
file(GLOB LD_FILE *gcc_nrf52.ld)
set(MY_APP_DIR ${CMAKE_SOURCE_DIR}/apps/orange)
create_application(
NAME
"pear"
PLATFORM
target
INCLUDE_DIRS
./
${MY_APP_DIR}
LINKER_SCRIPT
${LD_FILE}
SOURCES
${MY_APP_DIR}/foo.c
${MY_APP_DIR}/foo_bar.c
main.c
LIBRARIES
SomeLib_1
SomeLib_2
SomeLib_3
)
However, the compiler keeps complaining, saying that it cannot find "foo.h" and "foo_bar.h".
1) Do I need to separately create a static library in orange in order to access it in pear?
2) If I don't need to create a static library to access orange from pear, how do I link orange to pear?
3) I cannot find where CMake places the object files. Where are they?
This project is all under a single makefile.
Any help would be greatly appreciated, thanks!
I was able to fix my directory issues so that all of the include directories in ${MY_APP_DIR} are being linked into "Pear". However, a new issues has arisen. The linker cannot find the map file needed to create the executable image:
/usr/local/Caskroom/gcc-arm-embedded/5_4-2016q3,20160926/gcc-arm-none-eabi-5_4-2016q3/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: cannot open map file /Users/admin/Github/target/apps/pear/pear.map: No such file or directory.
I'm not sure why a map find isn't being created. Is the linker (ld) still missing files?
I'll try to answer your questions
You are not linking your libraries to your target.
You need something like:
$target_link_libraries(yourtarget yourlibraries)
after your add_executable command.
3) I cannot find where CMake places the object files. Where are they?
CMake puts all of its outputs in the build tree by default, so unless you are liberally using ${CMAKE_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR} in your cmake files, you should find the output files in the folder where your CMakeLists.txt file is.

SwiftPM: How to setup Swift module.map referring to two connected C libraries

I'm trying to build a Swift Package Manager system package (a module.modulemap)
making available two system C libraries where one includes the other.
That is, one (say libcurl) is a base module and the other C library is including
that (like so: #include "libcurl.h"). On the regular C side this works, because
the makefiles pass in proper -I flags and all is good (and I could presumably
do the same in SPM, but I'd like to avoid extra flags to SPM).
So what I came up with is this module map:
module CBase [system] {
header "/usr/include/curl.h"
link "curl"
export *
}
module CMyLib [system] {
use CBase
header "/usr/include/mylib.h"
link "mylib"
export *
}
I got importing CBase in a Swift package working fine.
But when I try to import CMyLib, the compiler complains:
error: 'curl.h' file not found
Which is kinda understandable because the compiler doesn't know where to look
(though I assumed that use CBase would help).
Is there a way to get this to work w/o having to add -Xcc -I flags to the
build process?
Update 1: To a degree this is covered in
Swift SR-145
and
SE-0063: SwiftPM System Module Search Paths.
The recommendation is to use the Package.swift pkgConfig setting. This seems to work OK for my specific setup. However, it is a chicken and egg if there is no .pc file. I tried embedding an own .pc file in the package, but the system package directory isn't added to the PKG_CONFIG_PATH (and hence won't be considered during the compilation of a dependent module). So the question stands: how to accomplish that in an environment where there libs are installed, but w/o a .pc file (just header and lib).

Cedet Help: Configuring a "Make" project

I am learning cedet for my c/c++ projects. However, I am facing difficulty in Make projects.
Say I have a file
main.cpp that looks like this
//main.cpp
#include "temp.h"
blah... <c++ code>
and I have temp.h and temp.cpp
that look like this
//temp.h
some declarations
//temp.cpp
some definitions
Then in emacs+cedet, I do ede-new and then I add a target main using ede-new-target and add main.cpp to main.
Then I write temp.h and temp.cpp and add temp.cpp to target temp.
I choose all targets as program generating this Project.ede file
;; Object Test
;; EDE project file.
(ede-proj-project "Test"
:name "Test"
:file "Project.ede"
:targets (list
(ede-proj-target-makefile-program "main"
:name "main"
:path ""
:source '("main.cpp")
)
(ede-proj-target-makefile-program "temp"
:name "temp"
:path ""
:source '("temp.cpp")
)
)
)
Now when I generate the makefile using ede-proj-regenerate, it creates a Makefile that generates main.o and temp.o
The make however fails as the Makefile generated does not identify the dependency of main.cpp on temp.cpp. How can I tell cedet EDE to identify this dependency? What is wrong in what I am doing here?
And secondly, how do I tell it that I do not want main.o as this is the final target program/executable and not an object file.
For your example, the created Makefile should be creating both main.o, and main. The name of the target you create should be the name of your program, so if you changed the target named "main" to "Pickle", it will create a main.o, and a Pickle program.
When you edit temp.cpp, you should add it to main, or Pickle if you choose to rename the target. Put all your source files for the program into the single target, unless you are choosing to create a library, in which case add temp to a library type target instead.
To "Fix things up", you can use the customize-project command to access all the other options not usually available via simple commands from Emacs proper. That will let you add dependencies on libraries, add your headers as aux src, and other useful things. Just read the doc strings associated with the different options.
A quick start for EDE can be found here.

What is the difference between building C++ Builder project from IDE and command line?

I have different behaviour of compiler, when building project from IDE and from command-line, which I can not explain.
The detailed issue's description is rather big, but it's really simple.
I have a C++ Builder project, which has a PAS-file included (IncludeUnits.pas). This pas-file has several units and inc-files listed. These files are located in separate folders and these folders are listed in library&include paths in project's options.
Folders layout:
C:\Demo\Bin
C:\Demo\Project
C:\Demo\Project\CBuilder5
C:\Demo\Project\Common
C:\Demo\Source
C:\Demo\Source\Common
Bin is output folder, Project/CBuilder5 holds project (bpr-file), Project/Common holds included pas-file (IncludeUnits.pas), Source and Source/Common hold other files (pas&inc). I think that it's pretty usual layout.
C:\Demo\Project\Common\ IncludeUnits.pas :
unit IncludeUnits;
interface
uses
Test;
implementation
end.
C:\Demo\Source\ Test.pas :
unit Test;
interface
{$I Test.inc}
implementation
end.
C:\Demo\Source\Common\ Test.inc :
// this file is empty
If I compile this project from C++ Builder IDE - it will compile fine. C++ Builder IDE doesn't have any additional paths in IDE settings set.
Now, I want to compile it from command-line. First, I issue
bpr2mak.exe MyProject.bpr
command.
This command creates MyProject.mak file, where I can see all paths ("....\Source" and "....\Source\Common" are the paths in question):
...
INCLUDEPATH = $(BCB)\include;$(BCB)\include\vcl;..\Common;..\..\Source;..\..\Source\Common
LIBPATH = $(BCB)\lib\obj;$(BCB)\lib;..\Common;..\..\Source;..\..\Source\Common
...
Now, I run make command:
make.exe -B -f"MyProject.mak"
It gives me the following output:
C:\PROGRA~1\Borland\CBUILD~2\BIN\dcc32 -N2....\Bin -N0....\Bin -$Y+ -$W -$R -v -JPHNE -M -UC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common -D_DEBUG;_RTLDLL;NO_STRICT -OC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common --BCB ..\Common\IncludeUnits.PAS
Borland Delphi Version 13.0 Copyright (c) 1983,99 Inprise Corporation
C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(6) C:\Demo\Source\Test.pas(1) C:\Demo\Source\Test.pas(5) Fatal: File not found: 'Test.inc'
As you can see - all search path is passed to compiler and the file (Test.inc) is all here - in that Source\Common folder. But still compiler can't find it?
Of course, I run both commands from folder with bpr-file. And changing paths to absolute doesn't help.
Copying Test.inc from Source\Common to Source will help. Changing {$I Test.inc} to {$I Common\Test.inc} will also help.
Why? It seems that I'm missing something. Remember: project have no problems with compiling from IDE, Test.inc is found without copying or changing declaration. Did I miss some switch to make or dcc32?
I found the reason: command line for dcc32 misses -I switch, which specifies paths for include files.
For some reason, bpr2mak doesn't respect this option. Fortunately, it allows you to specify alternate template for conversion bpr -> mak. I edited default template and added "-I" option to it, pass new template to bpr2mak - and it worked.