gnu arm assembler command line macro fails with "Invalid identifier for .ifdef"

assembly, gcc, gnu-assembler

Solution

The `gcc` binary drives the compilation process by invoking a number of other programs in sequence to actually perform the various stages of work (compiling, assembling, linking).

When you say:

gcc -x assembler-with-cpp -D MACRO_FROM_CMDLINE=1 ...

you are asking it to run the source through the C preprocessor, and then run the result through the assembler.

The C preprocessor step will turn:

.ifdef MACRO_FROM_CMDLINE

into:

.ifdef 1

before passing it to the assembler, which then can't make sense of it. This is why you get the "invalid identifier" error. It also explains why using C preprocessor `#ifdef` fixes the problem.

`--defsym` doesn't work because it's an option to the assembler, not the `gcc` driver program. (The `gcc` driver does understand and pass through some options to some of the programs it invokes, but not all.)

You can, however, pass arbitrary options through to the assembler using the

-Wa,option[,option...]

syntax, which tells the `gcc` driver to pass those option(s) through to the assembler (as a list of space-separated options).

For example:

gcc -x assembler-with-cpp -Wa,--defsym,MACRO_FROM_CMDLINE=1 ...

adds

--defsym MACRO_FROM_CMDLINE=1

to the list of options passed to `as` when `gcc` invokes it, and that's how to make your original `.ifdef` example work.

You can see the individual programs invoked by `gcc`, and the options it actually passes to them, by adding the `-v` option.

In this case, you should see something called `cc1` (the actual GCC C compiler binary) invoked with the `-E` flag (preprocess only) to preprocess the input to a temporary file, and then `as` invoked on the temporary file to assemble it.

Problem

My toolchain is a recent version of arm-gcc. I have a piece of code in an assembly file which must be conditionally included/assembled. ``` .ifdef MACRO_FROM_CMDLINE Assembly instr1 Assembly instr2 .endif ``` Encapsulated code is a recent addition. I have tried both: ``` gcc -x assembler-with-cpp --defsym MACRO_FROM_CMDLINE=1 <along with other necessary options> gcc -x assembler-with-cpp -D MACRO_FROM_CMDLINE=1 <along with other necessary options> ``` The `-D` results in "Invalid identifier for .ifdef " and ".endif without .if" errors. The `--defsym` results in "MACRO_FROM_CMDLINE=1 : No such file or directory", "unrecognized option --defsym" errors.

Original source