Home > On-Demand Archives > Talks >

CMake and the Dark Arts

Niall Cooling - Watch Now - EOC 2022 - Duration: 35:23

CMake and the Dark Arts
Niall Cooling

For many years embedded developers have relied on building an application image by invoking a "build" menu option with their development IDE. Unfortunately, this can lead to two challenges; first, it doesn't scale very well when a team of engineers develops a codebase. Second, it often ends up with an independent and often complicated set of scripts to create the complete build. 

Build systems were developed to simplify and automate running the compiler and linker and are an essential part of modern, agile software development. Historically GNU Make has been the de facto build tool for many years but can become challenging to maintain as codebases grow. 

Recent surveys show that CMake has become the build system of choice for the majority of new C/C++ projects. This presentation introduces the CMake build system and explains the steps required to add it to an existing embedded C/C++ project. It will also discuss "the good, the bad and the ugly" of CMake. By the end of the presentation you should be in a position to understand CMake based projects and make an informed decision whether CMake is the right tool for your future projects.

M↓ MARKDOWN HELP
italicssurround text with
*asterisks*
boldsurround text with
**two asterisks**
hyperlink
[hyperlink](https://example.com)
or just a bare URL
code
surround text with
`backticks`
strikethroughsurround text with
~~two tilde characters~~
quote
prefix with
>

alvangee
Score: 0 | 1 year ago | 1 reply

Hello!
One particular thing that stopped us from switching makefiles to CMake was linking with specific libraries.
In makefile it's done as
'LIBS := -lgcc -lc -lm'
then invoking compiler for linking as
'$(CROSS-COMPILER) $(LINKER_OPTIONS) $(OBJS) $(LIBS)'
Yes, we do linking through invoking compiler and passing linker options to it.
It works in GCC that way. And I'm sure we tried to invoke linker directly and it didn't solve the problem.

Trying it with CMake proved difficult. We Googled a lot and tried everything we saw as an answer to the library linking questions to no avail.

Did you ever link math library in your projects with CMake?
I believe you did and there should be a solution which we didn't find.
This just can't be that no one needs this except for us :)

NiallSpeaker
Score: 0 | 1 year ago | no reply

Linking in libraries is (normally) very straight forward using target_link_libraries, e.g.

cmake_minimum_required(VERSION 3.23)
project(MyApp)
add_executable(MyExe main.cpp)
target_link_libraries(MyExe PRIVATE  c m)

If just the name of the library is given with no path, the linker command will search for that library (e.g. c becomes -lc or c.lib, depending on the platform). This would be common for libraries provided by the system.

Nathan3
Score: 1 | 3 years ago | 1 reply

Thanks for the presentation. We are slowly moving towards using cmake and dropping the use of IDE-based compilation at my company.
Is it possible to explicitely tell cmake that the toolchain you want is NOT in the path, or/and that you want a specific version of the toolchain (to make sure all builds have the same results) ?

NiallSpeaker
Score: 0 | 3 years ago | 1 reply

Hi Nathan,
Yes, that's actually pretty straightforward. As part of the toolchain file, you can just set up symbols for the full path, e.g. set up the path to ${TOOLCHAIN_PREFIX}, e.g. (this is a quick and dirty example)

set(TARGET_TRIPLET "arm-none-eabi-")
set(TOOLCHAIN_PREFIX "/opt/gcc-arm-none-eabi-10.3-2021.10/")
set(ARM_TOOLCHAIN_PATH ${TOOLCHAIN_PREFIX}/bin)

set(CMAKE_C_COMPILER ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}-gcc)

etc.
Regards,
Niall.

Nathan3
Score: 0 | 3 years ago | 1 reply

Thanks Niall,

And if it is in the path but you want to make sure you are using a specific version (or a minimum version) how would you do that ?

NiallSpeaker
Score: 0 | 3 years ago | no reply

I wouldn't do it using CMake, I'd use (we do use) docker to build specific versions of the toolchain versions so the CMake is kept simple (i.e. in path toolchain) but the docker container gives a reproducible and comparable environment for building.

Niall.

Jordan
Score: 1 | 3 years ago | no reply

In regards to using "named collections" for source files, as opposed to globbing/wildcard, this is advantageous for one major reason, you can rebuild without re-running cmake and wiping out your last build. This is esspecially useful if your source takes a really long time to build. Just modifying the CMakeLists.txt to add your new source file and issuing "make/ninja" (or cmake --build ) will do a partial build. A second reason is if you want to tailor your build system to include different implementation files based on say a cmake option (perhaps your stubbing out a real implementation on ARM for an x86 simulator version). In this case you might need to explicitly include or exclude certain source files. When you glob, you will get all files and then you'll have to write some ugly script language to filter out what you didn't want.

Brian.Cabebe
Score: 1 | 3 years ago | 1 reply

This was an excellent presentation! I've started running across CMake projects and had no clue what was going on. Your comparison of the current Make process to the CMake process made all the differenece for me in understanding how CMake is used.

NiallSpeaker
Score: 0 | 3 years ago | no reply

Hi Brian
Really appreciate the kind words. Hopefully the next CMake based project may be easier to understand how it?s built.
Cheers
Niall.

JK
Score: 1 | 3 years ago | 1 reply

Great intro to CMAKE. Looking forward to learning a little more on your blog. I do have a question about add_link_options( --specs=nosys.specs), I know I can google, but looking to what reason you use this - it sounded like you mentioned that it ignores printf in the debug builds, which is a little confusing to me. Thanks

NiallSpeaker
Score: 1 | 3 years ago | 1 reply

Hi JK
The whole specs= is not especially well documented. It?s to do with setting up aliasing for pulling in different libraries. It?s on my backlog to write a blog about it as I went through the pain of trying to unpick the simple statement.
I?ll try and get something on the blog soon that will explain it all

Regards

Niall

JK
Score: 0 | 3 years ago | no reply

Thank you

Enrico
Score: 1 | 3 years ago | 1 reply

why are nested CMakefiles in directories preferred to one CMakefile file in the root ?

NiallSpeaker
Score: 0 | 3 years ago | no reply

The talk really didn?t have time to get into this in detail, but it?s all about localisation of change. CMake has a nice ability to create small ?components? (called libraries) within a subdirectory which help with build times and maintenance. Check out the blog and it might help clarify. But, as always, sometimes ?better? is subjective. Thanks for watching.

Vim
Score: 1 | 3 years ago | 1 reply

Thanks Niall for a great presentation on incorporating CMake into the embedded cross-compilation development environment! Our team has been looking to get away from vendor specific development environments to make our CI/CD build process easier.

NiallSpeaker
Score: 0 | 3 years ago | no reply

Hi Vim,
Thanks for the feedback. You?ll discover getting away from vendor specific environments Is like stopping banging you head again a brick wall ????
Cheers
Niall

Stephane.Boucher
Score: 0 | 3 years ago | no reply

Niall couldn't be available for a live Q&A today. If you have any questions or comments, please use this forum to post them and Niall will be able to respond later.

OUR SPONSORS

OUR PARTNERS