# Cmake Cortex-M multitarget build

**URL:** https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536
**Category:** Code
**Created:** [July 10, 2020, 3:21pm UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536 "2020-07-10T15:21:05Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![aphardt](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/65b543/32.png) [@aphardt](https://discourse.cmake.org/u/aphardt)
#### Post date: [July 10, 2020, 3:21pm UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536/1 "2020-07-10T15:21:05Z")

</div>

Hi

Im trying to achieve a cmake build environment where i can build multiple targets (binaries) at once.

cmake and make/ninja actually run successfully, but the generated ELF’s somehow do not run at all. When i run them with a segger debug session, they seem not to be able to map gdb addresses to source files.

what i also notice is that targetA and B are identical in size, even if they do not execute the same in the main program.

i found a lot of good inputs on github for cmake, both for either A.) cortex-M or B.) multiple-target builds, but never combined. i assume i have some configuration error.

Could someone help me out? If needed, i can also provide the entire project as a zip.

thank you!

== the main project (CMAKELISTS) =====================  
set(CMAKE\_SYSTEM\_NAME Generic)  
set(CMAKE\_SYSTEM\_PROCESSOR arm)  
set(CMAKE\_ASM\_COMPILER arm-none-eabi-gcc)  
set(CMAKE\_C\_COMPILER arm-none-eabi-gcc)  
set(CMAKE\_CXX\_COMPILER arm-none-eabi-g++)  
set(CMAKE\_EXE\_LINKER\_FLAGS “-specs=nano.specs -Wl,–gc-sections” CACHE INTERNAL “”)  
set(CMAKE\_ASM\_COMPILER\_ID GNU)  
set(CMAKE\_C\_COMPILER\_ID GNU)  
set(CMAKE\_CXX\_COMPILER\_ID GNU)  
set(CMAKE\_ASM\_COMPILER\_FORCED TRUE)  
set(CMAKE\_C\_COMPILER\_FORCED TRUE)  
set(CMAKE\_CXX\_COMPILER\_FORCED TRUE)

enable\_language (ASM)  
set (CMAKE\_ASM\_FLAGS “${CFLAGS} -x assembler-with-cpp”)  
set (CPU\_OPTIONS -mthumb -mcpu=cortex-m3)

cmake\_minimum\_required (VERSION 3.17.3)

project (main-project)

set (CMAKE\_ASM\_FLAGS\_DEBUG “-g”)  
set (CMAKE\_C\_FLAGS\_DEBUG “-Og -g -UNDEBUG -DDEBUG”)  
set (CMAKE\_CXX\_FLAGS\_DEBUG “-Og -g -UNDEBUG -DDEBUG”)  
set (CMAKE\_ASM\_FLAGS\_RELEASE “-g”)  
set (CMAKE\_C\_FLAGS\_RELEASE “-Og -g -UNDEBUG -DDEBUG”)  
set (CMAKE\_CXX\_FLAGS\_RELEASE “-Og -g -UNDEBUG -DDEBUG”)

add\_definitions( -DEFM32GG380F1024 )  
add\_definitions( -DDEBUG\_EFM )

add\_subdirectory (libraries/math\_lib\_1)  
add\_subdirectory (libraries/math\_lib\_2)  
add\_subdirectory (libraries/efm32)  
add\_subdirectory (libraries/dummy\_interface)

add\_subdirectory (targetA)  
add\_subdirectory (targetB)  
add\_subdirectory (targetZ)

== TARGET A ========================================

# identical to B and Z just different main program

project (targetA)

include\_directories( ${PROJECT\_NAME}  
${CMAKE\_SOURCE\_DIR}  
${CMAKE\_SOURCE\_DIR}/targetA  
)

link\_directories( ${PROJECT\_NAME}  
${CMAKE\_SOURCE\_DIR}  
)

add\_executable ( ${PROJECT\_NAME}  
main  
dummy  
targetA\_interface  
)

set ( LINKER\_SCRIPT “libraries/linker/targetA\_linker.ld” )

target\_link\_libraries ( ${PROJECT\_NAME}  
PRIVATE  
${CPU\_OPTIONS}  
-T${LINKER\_SCRIPT}  
-Wl,–gc-sections  
-nostartfiles  
-Xlinker  
-Map=${PROJECT\_NAME}.map  
m  
gcc  
math\_lib\_1  
math\_lib\_2  
efm32  
dummy\_interface  
)  
set\_target\_properties( ${PROJECT\_NAME}  
PROPERTIES  
SUFFIX “.elf”  
)  
=== LIB =======================================

add\_library ( efm32  
startup\_efm32gg  
system\_efm32gg)  
target\_include\_directories ( efm32  
PUBLIC ${CMAKE\_CURRENT\_SOURCE\_DIR})

---

<div class="post-metadata">

### Author: ![kyle.edwards](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/k/65b543/32.png) [@kyle.edwards](https://discourse.cmake.org/u/kyle.edwards)
#### Post date: [July 10, 2020, 3:33pm UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536/2 "2020-07-10T15:33:01Z")

</div>

First off, I would not suggest setting `CMAKE_<lang>_COMPILER`, or in fact anything above your `enable_language()`, inside your project file. Those should instead be set via a [CMake toolchain file](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html).

Second, you can get rid of the `enable_language()` call and change `project(main-project)` to `project(main-project ASM)`. This will also skip enabling C and C++ (assuming they’re not needed of course.)

Third, your linker options:

```auto
${CPU_OPTIONS}
-T${LINKER_SCRIPT}
-Wl,–gc-sections
-nostartfiles
-Xlinker
-Map=${PROJECT_NAME}.map

```

should be in a `target_link_options()` call instead.

Fourth, what’s going on here?

```cmake
add_executable ( ${PROJECT_NAME}
main
dummy
targetA_interface
)

```

These look like target names rather than source files, which makes me think they should be linked with `target_link_libraries()` instead. Does your program have any source files, or is it simply combining libraries?

And finally, I would use `objdump -s` and `objdump -S` on your output to see if any code is getting compiled in at all.

---

<div class="post-metadata">

### Author: ![aphardt](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/65b543/32.png) [@aphardt](https://discourse.cmake.org/u/aphardt)
#### Post date: [July 10, 2020, 3:41pm UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536/3 "2020-07-10T15:41:45Z")

</div>

> [@kyle.edwards](#):
>
> `target_link_options`

A.)  
`target_link_options` then it wont link anylonger at all, ninja stops execution at some point

B.)

```auto
add_executable ( ${PROJECT_NAME}
main
dummy
targetA_interface
)

```

those are 3 target specific source files (\*.cpp)

I would like to share my project with you, but the website does not allow newbie-users to attach data. can i somehow else publish my project?

---

<div class="post-metadata">

### Author: ![kyle.edwards](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/k/65b543/32.png) [@kyle.edwards](https://discourse.cmake.org/u/kyle.edwards)
#### Post date: [July 10, 2020, 3:48pm UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536/4 "2020-07-10T15:48:09Z")

</div>

How about starting a small repository on GitHub? You can of course strip out any proprietary data you don’t want to share.

---

<div class="post-metadata">

### Author: ![aphardt](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/65b543/32.png) [@aphardt](https://discourse.cmake.org/u/aphardt)
#### Post date: [July 10, 2020, 3:51pm UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536/5 "2020-07-10T15:51:58Z")

</div>

Ok ill do the github repository later, good idea. but for now i dont have an account, so ill share it with wetransfer  
(offline)

---

<div class="post-metadata">

### Author: ![kyle.edwards](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/k/65b543/32.png) [@kyle.edwards](https://discourse.cmake.org/u/kyle.edwards)
#### Post date: [July 10, 2020, 3:57pm UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536/6 "2020-07-10T15:57:35Z")

</div>

Thanks. I just took a look at your project.

I would suggest making the `.cpp` extension in `add_executable()` (and `add_library()`) explicit for the sake of readability.

When I said to use `target_link_options()`, I didn’t mean to move _everything_ into `target_link_options()`, just things that are not libraries. So it would look something like:

```cmake
target_link_options ( ${PROJECT_NAME}
PRIVATE
${CPU_OPTIONS}
-T${LINKER_SCRIPT}
-Wl,–gc-sections
-nostartfiles
-Xlinker
-Map=${PROJECT_NAME}.map
)
target_link_libraries(${PROJECT_NAME}
m
gcc
math_lib_1
math_lib_2
efm32
dummy_interface
)

```

---

<div class="post-metadata">

### Author: ![aphardt](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/65b543/32.png) [@aphardt](https://discourse.cmake.org/u/aphardt)
#### Post date: [July 10, 2020, 4:05pm UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536/7 "2020-07-10T16:05:45Z")

</div>

ok thanks. i applied your suggestions. its still building suggessfully, but the final binary is the same.

the objdump seems to have all functions available, so i assume everything is linked into the binary correctly (hard assumption though!)

---

<div class="post-metadata">

### Author: ![kyle.edwards](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/k/65b543/32.png) [@kyle.edwards](https://discourse.cmake.org/u/kyle.edwards)
#### Post date: [July 10, 2020, 5:23pm UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536/8 "2020-07-10T17:23:50Z")

</div>

One more thing… did you run CMake with `-DCMAKE_BUILD_TYPE=Debug`?

---

<div class="post-metadata">

### Author: ![aphardt](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/65b543/32.png) [@aphardt](https://discourse.cmake.org/u/aphardt)
#### Post date: [August 7, 2020, 11:06am UTC](https://discourse.cmake.org/t/cmake-cortex-m-multitarget-build/1536/9 "2020-08-07T11:06:12Z")

</div>

The issue is it hardfaults directly after the Reset\_Handler().  
I dont see whats going bad here at the moment.
