27

I am trying to pass -S to GCC for one of my executables. I tried this:

set_target_properties(MyTarget PROPERTIES COMPILE_FLAGS "-S") 

but I get "file format not recognized; treating as linker script"

(It builds fine without that line)

Is there something wrong with passing -S like this? Or is there another way to have CMake output the assembly .s files?

Paweł Bylica
  • 3,780
  • 1
  • 31
  • 44
David Doria
  • 9,873
  • 17
  • 85
  • 147
  • 11
    I learned that if you type 'make help' on a CMake project, you will see a list of targets. "MyTarget.s" is one of them, so simply doing "make MyTarget.s" produces the assembly I was looking for. – David Doria Oct 19 '12 at 02:43
  • I believe that `make MyTarget.s` did what you wanted because your target has a source file named `MyTarget.c` or `MyTarget.f90` and that in general `make .s` would not work. – Philippe Carphin Jul 10 '23 at 22:02

3 Answers3

30

CMake has targets built in for both assembler and preprocessor output. For a file called src.cpp, CMake generates the target src.s for assembler output and src.i for the preprocessor output. It generates the assembler/preprocessor outputs for each target seperately in case the compile flags are different. Using the make generator for your CMake project, you can get the assembler and preprocessor outputs like this:

make src.s   # assembler output
make src.i   # preprocessor output
ingomueller.net
  • 4,097
  • 2
  • 36
  • 33
  • 2
    How can I combine this with interlaced source comments, e.g. [this](http://stackoverflow.com/a/137479/388010)? À la `g++ -g -O0 -c -fverbose-asm -Wa,-adhln test.cpp > test.lst` – Sebastian Graf Jul 17 '15 at 17:34
  • 3
    For now, I manually alter the right makefile and adding `-fverbose-asm` after it has been generated. Then I can use the `as -alhnd` bit. – Sebastian Graf Jul 17 '15 at 17:45
23

If you're trying to actually build MyTarget and leave the generated assembly, you can replace -S with -save-temps and then do make MyTarget

Fraser
  • 74,704
  • 20
  • 238
  • 215
0

I want to add to @ingomueller.net's answer. CMake does have .s targets but for multi directory projects, you have to navigate to the right directory within your build directory to get it. That directory is determined by the location of the CMakeLists.txt file that creates the target and the add_subdirectory() commands that get to it.

If

<source_dir>/<d1>/CMakeLists.txt

has

add_excutable(x <d2>/file.c)
#or
add_library(x <d2>/file.c)

Then you can run make <d2>/file.s if you go to the right directory first. In general, this will be the value of ${CMAKE_CURRENT_BINARY_DIR} where the target is created. In most cases this would be

<build_dir>/<d1>

But this can be different because add_subdirectory() can take two arguments which can change things. For example, say <d1> is a/b, if the toplevel CMakeLists.txt does add_subdirectory(a/b/ c), then you will need to go to <build_dir>/c. Also the second argument of add_subdirectory can be an absolute path. And since we can get to the CMakeLists.txt file that creates the target through multiple add_subdirectory() commands, the only general answer is "whatever the value of ${CMAKE_CURRENT_BINARY_DIR} is where the target is created".

CMake will print the path to the generated file which will be CMakeFiles/<target_name>.dir/<d2>/file.c.s relative to $PWD.

Also, note that you can do either make <d2>/file.s or make <d2>/file.c.s and both will generate the file file.c.s however you could have file.c and file.f90 in the same directory, in that case make <d2>/file.s will generate two files file.c.s and file.f90.s but doing make <d2>/file.c.s will generate just one.