How to differentiate settings for armclang and assembler/C++ files?

Hi, I have a working CMakeLists.txt to build a C++ project using armclang. I have now added an assembler file. Here is my CMakeLists.txt (cut down a bit):

cmake_minimum_required(VERSION 3.24.1)

project(my_arm)
set(EXECUTABLE ${PROJECT_NAME})

enable_language(CXX C ASM)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(SRC_FILES
        src/arm_src/main.cpp
        src/arm_src/PktProcWrite_asm.asm
        )

add_executable(${EXECUTABLE})

target_sources(${EXECUTABLE} PRIVATE ${SRC_FILES})

target_compile_definitions(${EXECUTABLE} PRIVATE
    _RTE_
    ARMCM4
    PLATFORM_IS_ARM=1 
    __FILE_INCOMPLETE USE_TUBE=1 
    SIMULATE_SECT_LISTS_AND_TAG_RAMS=0 
    SIMULATE_DESCRIPTORS=0
    )

target_compile_options(${EXECUTABLE} PRIVATE
        -mcpu=cortex-m4
        -mfpu=none 
        -mlittle-endian
        -Wall 
        -fshort-enums 
        -fshort-wchar 
        -ffunction-sections 
        -fshort-enums 
        -fshort-wchar 
        -fno-rtti
        )

set(CMAKE_ASM_FLAGS "--target=arm-arm-none-eabi")

target_include_directories(${EXECUTABLE} PRIVATE
        "${CMSIS_PATH}/CMSIS/Core/Include"
        src/arm_src
        )

target_link_options(${EXECUTABLE} PRIVATE
        --entry=Reset_Handler
        --map
        --info=totals
        --strict 
        --scatter=${RTE_SOURCE_PATH}/Device/ModelSim/scatter.scat
        )

My problem is that the asm file gets compiled with some C++ compiler settings:

"C:/Program Files/Arm/Development Studio 2022.1/sw/ARMCompiler6.18/bin/armclang.exe" -DARMCM4 -DELYSION_PLATFORM_IS_ARM=1 -DSIMULATE_DESCRIPTORS=0 -DSIMULATE_SECT_LISTS_AND_TAG_RAMS=0 -DUSE_TUBE=1 -D_RTE_ -D__FILE_INCOMPLETE -IC:/<snip>/Arm/Packs/ARM/CMSIS/5.9.0/CMSIS/Core/Include  -IC:/<snip>/src/arm_src/ --target=arm-arm-none-eabi -mcpu=cortex-m4 -mfpu=none -mlittle-endian -Wall -fshort-enums -fshort-wchar -ffunction-sections -fno-rtti -O2 -c -o CMakeFiles/<snip>/PktProcWrite_asm.o C:<snip>/PktProcWrite_asm.asm
armclang: warning: argument unused during compilation: '-D ARMCM4' [-Wunused-command-line-argument]
armclang: warning: argument unused during compilation: '-D ELYSION_PLATFORM_IS_ARM=1' [-Wunused-command-line-argument]
armclang: warning: argument unused during compilation: '-D SIMULATE_DESCRIPTORS=0' [-Wunused-command-line-argument]
armclang: warning: argument unused during compilation: '-D SIMULATE_SECT_LISTS_AND_TAG_RAMS=0' [-Wunused-command-line-argument]
armclang: warning: argument unused during compilation: '-D USE_TUBE=1' [-Wunused-command-line-argument]
armclang: warning: argument unused during compilation: '-D _RTE_' [-Wunused-command-line-argument]
armclang: warning: argument unused during compilation: '-D __FILE_INCOMPLETE' [-Wunused-command-line-argument]
armclang: warning: argument unused during compilation: '-fshort-enums' [-Wunused-command-line-argument]
armclang: warning: argument unused during compilation: '-fshort-wchar' [-Wunused-command-line-argument]
armclang: warning: argument unused during compilation: '-ffunction-sections' [-Wunused-command-line-argument]

How can I arrange for the armclang invocation for the .asm file to exclude the target_compile_options and target_include_directories ?

You can use generator expressions to control that. For example:

set (my_defs
    _RTE_
    ARMCM4
    PLATFORM_IS_ARM=1 
    __FILE_INCOMPLETE USE_TUBE=1 
    SIMULATE_SECT_LISTS_AND_TAG_RAMS=0 
    SIMULATE_DESCRIPTORS=0
    )
target_compile_definitions(${EXECUTABLE} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${my_defs}>")

Thank you, I understand. So now I have:

# Compiler options for C and C++ sources only
set(C_CXX_COMPILER_OPTIONS
        -fshort-enums
        -fshort-wchar
        -ffunction-sections
)
target_compile_options(${EXECUTABLE}
  PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${C_CXX_COMPILER_OPTIONS}>"
          "$<$<COMPILE_LANGUAGE:C>:${C_CXX_COMPILER_OPTIONS}>"
)

# Compiler options specific to Debug build type
target_compile_options( ${EXECUTABLE} PRIVATE $<$<CONFIG:DEBUG>:-O0 -g> )

# Compiler options specific to Release build type
target_compile_options( ${EXECUTABLE} PRIVATE $<$<CONFIG:RELEASE>:-O2> )

The optimisation options (-O0, -O2 etc) are still appearing in the assembler invocation. Is it possible to AND generator expressions so the ‘-O2’ only appears when CONFIG:RELEASE is true and C/C++ compiler is used?

Again, have a look at the documentation… Logical operators are available in generator expressions. And ensure that your genex are specified inside quotes to avoid unexpected interpretation.

And target_compile_options expects a CMake list so:

# separate arguments with ;
target_compile_options( ${EXECUTABLE} PRIVATE "$<$<CONFIG:DEBUG>:-O0;-g>" )

Thank you.