Skip to content

Multi‐file compilation

Felipe Torrezan edited this page Mar 24, 2024 · 5 revisions

Introduction

The IAR C/C++ Compiler offers the possibility for compiling multiple files as a single compilation unit. Doing so will typically improve both size and speed performance as the compiler will oversee the application's code further down, unleashing its full potential for interprocedural optimizations. Ultimately, compiling the entire application from a single compilation unit should give the compiler complete visibility.

From the compiler's command line perspective, the file set must be passed as additional parameters from a single invocation, with the --mfc option:

iccarm file1.c file2.c file3.c --mfc ...

As per CMake 3.28, target_sources() doesn't provide a clear way for specifying file sets for such purpose.

Applies to

  • CMake targets using 2 or more source files.

Solutions

Consider one of the following approaches for when building a target using multi-file compilation:

Approach #1 - Include *.c source files into a single compilation unit

Changing the source code to include the file set from a single compilation unit will effectively mimic the effect provided by --mfc:

/* File: file1.c */

#include "file2.c"
#include "file3.c"
/* ... */

void main() { 
/* ... */

Approach #2 - Trick CMake by passing the file set as target_compile_options()

Sometimes changing the sources might be cumbersome depending on how largely partitioned the project was. A workaround for using --mfc from a CMake project could be:

cmake_minimum_required(VERSION 3.20)

project(MyProject)

add_executable(MyProject)

target_sources(MyProject PRIVATE file1.c)

set(MFC_FILES
  ${CMAKE_CURRENT_SOURCE_DIR}/file2.c
  ${CMAKE_CURRENT_SOURCE_DIR}/file3.c)

target_compile_options(MyProject PRIVATE ${MFC_FILES} --mfc --discard_unused_publics)

target_link_options(MyProject PRIVATE --semihosting)

where the output from cmake --build . --clean-first --verbose would be:

[1/2] /opt/iarsystems/bxarm/arm/bin/iccarm --silent /myproject/file1.c /myproject/file2.c /myproject/file3.c --mfc --discard_unused_publics --dependencies=ns CMakeFiles/myproject.dir/file1.o.d -o CMakeFiles/myproject.dir/file1.o
[2/2] : && /opt/iarsystems/bxarm/arm/bin/ilinkarm CMakeFiles/myproject.dir/file1.o --silent --semihosting -o MyProject.elf && :

Tip

According to the User Guide, the option --discard_unused_publics might be helpful in scenarios where --mfc is used within a project-wide scope, where the compiler can have full visibility of the source code from a single compilation unit.

Clone this wiki locally