How to get listing file when cross compile

I’m using cmake 3.16.3 on xubuntu 20.04 to cross-compile a bare metal project that will run on ARM cortex-m7 microcontroller.
The project is structured in subdirectories, and for this I use the add_subdirectory() command.

I need the listing files created at compilation time (with the option -Wa,-anhlmsd=<file_name>.lst).

How can I do this with cmake?

bast regards
Max

Hi,

if I understand correctly you like to have the current filename inside CFLAGS. I don’t think there is direct support for it. I think you could create file specific CFLAGS using a loop and

get_property(allsrcfiles TARGET theliborwhatever PROPERTY SOURCES)
foreach(srcfile IN LIST allsrcfiles)
  set_source_files_properties(${srcfile} PROPERTIES COMPILE_FLAGS "-Wa,-anhlmsd=${srcfile}.lst")
endforeach()

possibly remove some path from srcfile in the loop.

We had a similar issue and for several reasons I won’t explain here for us a GNU Make specific solution was the best for us:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-builtin-macro-redefined -D'__FILE__=\"$(subst ${SRCROOT},./build,$(subst ${SRCROOT},.,$(realpath $<)))\"'")

The trick is that make sets “$<”, realpath makes it absolute, we ensure to have an absolute SRCROOT variable set and make applies the $(subst) function at the right time.

Some consider this dealing with black magic, it breaks any other Generator except make and your mileage may vary.

So maybe you need something like:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} '-Wa,-anhlmsd=\"$(notdir $<)\"'")

(untested)

Yes…

In fact I would like the <file>.c.lst files to be written in the same location where <file>.c.o and <file>.c.d are located.
I looked among the variables, but I didn’t find what I was looking for. Before going to browse through the cmake modules, could you suggest how I can do it?

I would like that my solution could not depend on GNU make (for example we would like to test also ninja). Everything depends on other features that I hope you can insert

best regards
Max

I think we’d need a new generator expression. Something like $<TARGET_OBJECT_DIR:tgt> perhaps (in order to support multi-config generators)? The foreach loop is likely to continue to be necessary without some other feature that would need more work. Could you please file a feature request on the issue tracker?

In the meantime I could browse cmake modules files, to see how the .o path is composed, so that I could copy it.
Do you think this is a viable way?

best regards
Max

This would probably work in most cases. Multi-config generators (IDEs) would be the main thing to watch out for.

Couldn’t we get property LIBRARY_OUTPUT_DIRECTORY and append basename and “.lst”?

No, that is where the linked library ends up. The .o (or .obj) files end up in a different place that is not accessible via a property (and I don’t think it can be since some generators don’t specify where they’ll end up, so CMake can’t give a reliable answer).

As mentioned in the thread that linked to this, I’ve found that generator expressions don’t seem to be expanded when generating the link command.

In my toolchain file I have:
set(CMAKE_EXE_LINKER_FLAGS "--std=c++11 -Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${exe_name}.map")

And I end up with

-Wl,-Map=$<TARGET_FILE_DIR:tgt>/mapfile.map

in the eventual call.

No, that wouldn’t work I imagine. You’ll want target_link_options which does handle generator expressions.

Well, that’s the problem. I have to have special logic in my project description to add “the right” linker flags for the current toolchain for every target.

It means I end up wrapping add_executable() with something, but it’s doable.

It seems like it would make life easier if the expansion of these variables took advantage of generator expressions. I don’t know if generator expressions can do it, but it would also be nice to be able to query target properties and expand to different things based on them.

This would allow the toolchain file to be a one stop shop for fleshing out compiler support.

set(CMAKE_EXE_LINKER_FLAGS $<IF:$<STREQUAL:$<TARGET_PROPERTY:MAKE_LISTFILE>,"true">,"-Wl,-Map=$<TARGET_FILE_DIR:tgt>/mapfile.map","">)

(I think that syntax is right, but you get the idea.) if the target that’s getting currently built has the property, add this string to the linker flags, expanding the target directory.

We’d need a new placeholder to say “the current target being compiled” to replace that literal tgt, but yeah, something like that looks mostly OK (quoting is off, but can just be refactored out into the whole thing). A feature request for genex support (and the “current target name” replacement) would be the way to go.

If I understand what I’m reading, this would mean that it’s impossible to drive CMake to configure the build-time writing of .lst files at the location I want and with the name I want.
Am I understanding this correctly?

best regards
Max

As of today, yes. I proposed a genex for this further up the thread:

That should be suitable to get “where the .o files for tgt will appear”.

I’ve been lazy, but I finally requested it here: Feature Request: Implement genex that gives access to the target directory and filename (#21650) · Issues · CMake / CMake · GitLab (kitware.com)

I worked around it for my mapfiles until I got burned by the same thing trying to generate list files per .o compiled.