ccmake

How to change CMake linking order of object files for source files?


Context

When using CMake, I have noticed that the source definition order will influence the linking order.

For example, consider this project with 3 source files.

target_sources(my-project.elf PUBLIC
    alpha.c
    beta.c
    gamma.c
)

Using make VERBOSE=1, we can see linking order is exactly the same has the definition order:

[100%] Linking C executable my-project.elf
/usr/bin/cmake -E cmake_link_script CMakeFiles/my-project.elf.dir/link.txt --verbose=1
/usr/local/build_tools/gcc-6.3-arm32-eabi/bin/arm-none-eabi-gcc
[Some linker flags]
CMakeFiles/my-project.elf.dir/alpha.c.obj
CMakeFiles/my-project.elf.dir/beta.c.obj
CMakeFiles/my-project.elf.dir/gamma.c.obj
-o  my-project.elf

Questions

Purpose:

The embedded systems domain is full of __weak function redefinition, functions called from interrupts, inline assembly implementation, etc.


EDIT:
I realized that linking order is not important.
My problem was related to the way I modelled my dependencies in CMake + the __weak functions definition.

Thanks to all.



Solution

  • How to change CMake linking order?

    As far as the linking order of sources of a target is concerned, try reordering the arguments.

    As for the linking order of libraries, you can use target_link_options with SHELL:.

    Is this a documented feature?

    No.

    can I rely on this behaviour?

    Generally yes, I never seen cmake reordering object files.

    The embedded systems domain is plagued with __weak function redefinition

    I would disagree.

    Why link order is important to me

    The link order of object files is irrelevant - all symbols are loaded at one pass. What is causing problems with weak symbols is the linking order of static libraries. In modern cmake use OBJECT libraries, in older cmake use --whole-archive linker flag. When using whole-archive, be aware of LINK_INTERFACE_MULTIPLICITY.