# Using target\_sources with INTERFACE assembly sources does not generate absolute paths.

**URL:** https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140
**Category:** Usage
**Created:** [December 27, 2022, 9:48pm UTC](https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140 "2022-12-27T21:48:54Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![cookpate](https://discourse.cmake.org/user_avatar/discourse.cmake.org/cookpate/32/3037_2.png) [@cookpate](https://discourse.cmake.org/u/cookpate)
#### Post date: [December 27, 2022, 9:48pm UTC](https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140/1 "2022-12-27T21:48:54Z")

</div>

Was the ASM language simply left out of 3.13’s target\_sources relative path changes?  
I currently have to use CMAKE\_CURRENT\_SOURCE\_DIR when listing assembly files under INTERFACE sources.

I have the following project tree:

```auto
freertos
├── CMakeLists.txt # final static library target is created here if requested
└── portable
    ├── CMakeLists.txt # includes subdirectories for specific ports based on toolchain
    └── GCC # all ports for GCC toolchain variants
        └── ARM_CA9
            ├── CMakeLists.txt # defines sources for GCC_ARM_CA9 port as an interface library
            ├── port.c
            ├── portASM.S
            └── portmacro.h

```

When I configure this port with CMake 3.22 I end up with the following error:

```auto
CMake Error at freertos/CMakeLists.txt:209 (add_library):
  Cannot find source file:

    portASM.S

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
  .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc

```

My project has ASM language enabled.  
If I remove portASM.S from target\_sources, CMake configures just fine, but my project will not build without this assembly file.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [December 27, 2022, 10:41pm UTC](https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140/2 "2022-12-27T22:41:53Z")

</div>

~~Do you have the `ASM` language enabled in your project? Only `C` and `CXX` are enabled by default. If you haven’t explicitly enabled `ASM`, that might mean assembly source file extensions are not handled (that’s just a guess, I haven’t checked the code).~~

EDIT: Sorry, just saw you already mentioned that in your post.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [December 27, 2022, 10:45pm UTC](https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140/3 "2022-12-27T22:45:04Z")

</div>

Can you show the actual `CMakeLists.txt` file(s) involved in your project?

---

<div class="post-metadata">

### Author: ![cookpate](https://discourse.cmake.org/user_avatar/discourse.cmake.org/cookpate/32/3037_2.png) [@cookpate](https://discourse.cmake.org/u/cookpate)
#### Post date: [December 27, 2022, 11:43pm UTC](https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140/4 "2022-12-27T23:43:17Z")

</div>

The full CMake project may be found at [Paul Bartell’s FreeRTOS-Kernel fork](https://github.com/paulbartell/freertos-kernel/tree/cmake_refactor).

Previously, ports were defined using generator expressions in portable’s list file. This required -DFREERTOS-PORT to be specified. For CI/CD, we want to be able to compile all targets a toolchain variant & version is able to without having to reconfigure between runs.

A project in the current branch would build with `cmake -B build --toolchain freertos/toolchain/gcc-arm.cmake` with a similar root-level list file:

```auto
###############################################################################
# CMakeLists.txt
###############################################################################
cmake_minimum_required(VERSION 3.16)
project(example C ASM)

add_library(freertos_config INTERFACE)
target_sources(freertos_config INTERFACE FreeRTOSConfig.h)
target_include_directories(freertos_config SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(freertos_config INTERFACE projCOVERAGE_TEST=0)

set(FREERTOS_HEAP "4" CACHE STRING "FreeRTOS heap model number. 1 .. 5. Or absolute path to custom heap source file")
set(FREERTOS_PORT "GCC_ARM_CA9" CACHE STRING "FreeRTOS Port Identifier")

# should really be using fetch content with a paritcular release tag
# but this list file was created for local testing.
add_subdirectory(freertos)

target_compile_options(freertos_kernel
    PUBLIC
        -mthumb
        -mcpu=cortex-a9
        -mfpu=auto
        -mfloat-abi=hard )

```

```auto

###############################################################################
# FreeRTOS Kernel
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT
###############################################################################

###############################################################################
# FreeRTOS/CMakeLists.txt
###############################################################################
cmake_minimum_required(VERSION 3.16)
project(FreeRTOS-Kernel C ASM)

# detect toolchain being used

add_subdirectory( portable )

add_library( freertos_kernel STATIC )

# setup freertos_kernel_core and freertos_heap targets
# user supplies freertos_config target

target_link_libraries( freertos_kernel
    PUBLIC
        freertos_config
        freertos_heap
        # Aliased to the target FreeRTOS:Kernel:Port::${FREERTOS_PORT} is aliased to.
        freertos_kernel_port
        freertos_kernel_core )

```

```auto
###############################################################################
# FreeRTOS/portable/CMakeLists.txt
###############################################################################

###############################################################################
# Helper for defining a FreeRTOS port
# Useful for simple ports
###############################################################################
macro( freertos_define_port )
    set(oneValueArgs
        NAME ) # name to give to port library

    set(multiValueArgs
        ALIAS # backwards-compatible name(s)
        HEADERS # header files this port uses
        SOURCES ) # source files this port uses

    cmake_parse_arguments(PORT
        ""
        "${oneValueArgs}"
        "${multiValueArgs}"
        ${ARGN} )

    add_library( ${PORT_NAME} INTERFACE )

    target_sources( ${PORT_NAME} INTERFACE "${PORT_SOURCES}" )

    if( ${CMAKE_VERSION} VERSION_LESS "3.23.0" )
        target_sources( ${PORT_NAME} PUBLIC "${PORT_HEADERS}" )
        target_include_directories( ${PORT_NAME} INTERFACE . )
    else()
        target_sources( ${PORT_NAME}
            PUBLIC
                FILE_SET HEADERS
                    BASE_DIRS .
                    FILES "${PORT_HEADERS}" )
    endif()

    foreach( ALIAS IN LISTS PORT_ALIAS )
        add_library( FreeRTOS::Kernel::Port::${ALIAS} ALIAS ${PORT_NAME} )
    endforeach()
endmacro()

# while handling specific port names for backwards compatibility:
    add_subdirectory( GCC/ARM_CA9 )

    get_target_property(target_name
        FreeRTOS::Kernel::Port::${FREERTOS_PORT}
        ALIASED_TARGET )
    add_library(freertos_kernel_port ALIAS ${target_name})

```

There are dozens of ports we are building with CMake, this is just one of them, hence the macro in portable’s list file. Several of them have various file extensions for ASM, some use inline ASM in a C file which also works just fine.

```auto

###############################################################################
# FreeRTOS/portable/GCC/ARM_CA9/CMakeLists.txt ARM CA9 for GCC
###############################################################################
freertos_define_port(
    NAME freertos_port_arm_ca9
    ALIAS GCC_ARM_CA9
    HEADERS
        portmacro.h
    SOURCES
        port.c
        portASM.S )
```

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [December 28, 2022, 12:13am UTC](https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140/5 "2022-12-28T00:13:29Z")

</div>

I don’t see anything specific to any particular language in the change that added that behavior. I suggest you open an issue in [CMake’s issue tracker](http://gitlab.kitware.com/cmake/cmake/issues/new). You would be well advised to add a minimal project which demonstrates the problem, as linking to a large, complicated project like yours will make it much less likely for anyone to want to investigate it.

---

<div class="post-metadata">

### Author: ![cookpate](https://discourse.cmake.org/user_avatar/discourse.cmake.org/cookpate/32/3037_2.png) [@cookpate](https://discourse.cmake.org/u/cookpate)
#### Post date: [December 28, 2022, 12:40am UTC](https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140/6 "2022-12-28T00:40:03Z")

</div>

While reproducing, everything was fine up until creating a similar macro in a parent directory’s list file.

---

<div class="post-metadata">

### Author: ![cookpate](https://discourse.cmake.org/user_avatar/discourse.cmake.org/cookpate/32/3037_2.png) [@cookpate](https://discourse.cmake.org/u/cookpate)
#### Post date: [December 28, 2022, 1:18am UTC](https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140/7 "2022-12-28T01:18:26Z")

</div>

I found the exact problem:  
quote-wrapping a dereferenced list passes it semi-colon delimited, while I believe the 3.13 change assumes that the list is merely dereferenced which passes each source space-delimited, as its own variable

```auto
macro (my_add_library)
    message(STATUS "Macro invoked from ${CMAKE_CURRENT_SOURCE_DIR}")
    set(singleValueArgs "NAME")
    set(multiValueArgs "SOURCES;ASM")
    cmake_parse_arguments(MY "" "${singleValueArgs}" "${multiValueArgs}" ${ARGN})

    message(STATUS "Adding ${MY_NAME} library with sources: ${MY_SOURCES}")
    add_library(${MY_NAME} INTERFACE)

    target_sources( ${MY_NAME} INTERFACE "${MY_SOURCES}" )

    foreach(SOURCE IN LISTS MY_SOURCES MY_ASM)
        find_file(FOUND_${SOURCE} ${SOURCE} PATHS .)
        message(STATUS "${SOURCE}: '${FOUND_${SOURCE}}'")
    endforeach()

    get_target_property(MY_INTERFACE_SOURCES ${MY_NAME} INTERFACE_SOURCES)
    message(STATUS "Added sources: ${MY_INTERFACE_SOURCES}")
endmacro()

# defer creation of inner library to path
add_subdirectory(path)

```

```auto
cmake -B build
-- Macro invoked from /home/cookpate/sandbox/cmakebug/relative/path
-- Adding inner library with sources: main.c;emptyasm.s
-- main.c: '/home/cookpate/sandbox/cmakebug/relative/path/main.c'
-- emptyasm.s: '/home/cookpate/sandbox/cmakebug/relative/path/emptyasm.s'
-- Added sources: /home/cookpate/sandbox/cmakebug/relative/path/main.c;emptyasm.s
-- Configuring done
CMake Error at CMakeLists.txt:7 (add_library):
  Cannot find source file:

    emptyasm.s

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
  .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc

CMake Error at CMakeLists.txt:7 (add_library):
  No SOURCES given to target: outer

```

unquoting the list gives each value in INTERFACE\_SOURCES an absolute path. This doesn’t depend on source languages used.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [December 28, 2022, 1:52am UTC](https://discourse.cmake.org/t/using-target-sources-with-interface-assembly-sources-does-not-generate-absolute-paths/7140/8 "2022-12-28T01:52:51Z")

</div>

```auto
target_sources( ${MY_NAME} INTERFACE "${MY_SOURCES}" )

```

That line is incorrect. The `${MY_SOURCES}` should not be quoted. The `target_sources()` command expects each source file as a separate argument. If `MY_SOURCES` contained more than one file, `target_sources()` would end up seeing a single file with a semicolon in its file name, not two separate file names. I think what you’re actually seeing is `target_sources()` sees `main.c;emptyasm.s`, interprets it as a relative path and prepends `${CMAKE_CURRENT_SOURCE_DIR}` to that whole string. From it’s perspective, there is a single file whose name is `main.c;emptyasm.s`. Then, later on during the generation stage, the semicolon is interpreted as a list separator, so at that point, `emptyasm.s` is now seen as a separate file.

TLDR: Don’t quote a whole list of files when passing it to `target_sources()`. Doing so makes it see that as a single file name when deciding whether to prepend a path or not.
