I'm using Keil 5.23 and trying to use arm-clang compiler v6.6.
I want to create an array that will contain compilation date and time. I need this array to be placed in flash memory, so I made it const. I don't need to access this array, so I made it static.
Now I have a problem. If I declare it like this:
static const char date_time[] = { "compilation time: " __DATE__ ", " __TIME__ };
It gets removed by compiler, even though I set -O0. Adding __attribute__((used)). According to this page www.keil.com/.../armclang_mig_chr1398848377314.htm even objects marked as 'used' can be removed by linker nonetheless. So I need to add a linker option --keep=symbol_name or --noremove.
If I add --noremove, linker keeps to much data, bloating binary size from 4KiB to 17KiB. If I use --keep, linker tells me that it can't find that symbol:
.\obj\dummy.axf: Warning: L6320W: Ignoring --keep command. Cannot find argument 'date_time'.
Even if I don't declare it as static.
Adding volatile doesn't help either.
Please, tell me, what am I doing wrong? How can I tell compiler and linker not to remove this array?
Remember that 'C' compilers like to add a leading underscore to names - so what happens if you specify the name as "_date_time" ... ?
Andrew Neil: I never heard that C compilers like to modify symbol names, I don't understand how libs would work if that kind of non-standardized mangling existed.
Anyway, adding underscore did nothing, linker still can't find that symbol.
I don't know if it is formally standardised, but it is certainly very common & widespread - if not universal.
stackoverflow.com/.../why-do-c-compilers-prepend-underscores-to-external-names
I don't know the answer for sure but I see a few clues.
1) I think you are skimming and making assumptions that are probably not correct.
Note: In Arm Compiler 6, functions marked with __attribute__((used)) can still be removed by linker unused section removal. To prevent the linker from removing these sections, you can use either the --keep=symbol or the --no_remove armlink options. In Arm Compiler 5, functions marked with __attribute__((used)) are not removed by the linker.
Your static const char is not a function. If --keep is looking for a function with that name it is not going to find that name.
2) There is no global symbol that the linker can see for date_time. You made it static. If you want a global symbol date_time that the linker can see you need to remove the static qualifier.
3) I looks like what you may want to happen is for the section that contains the static char const to be kept. You could try --keep=YourFileName.o
I would probably try removing the static and saying --keep=date_time and see if that works. That seems the closest to what you wanted (my assumption here)
Next would be keep the section that contains it. I don't think you need to remove the static qualifier in this case. I am not sure how important that qualifier is to you (I would have to make another assumption)
I am sure there are more ways to solve this and as I said, I have not actually solved this yet, I am just providing observations.
Robert McNamara: I already tried removing 'static' with no success, linker still can't see it. Weirdly, removing 'const' does work, linker starts to see this symbol, however, I don't want to waste both RAM and flash to keep this string around.
Trying to --keep=filename.o leads to error: .\obj\dummy.axf: Error: L6211E: Ambiguous section selection. Object filename.o contains more than one section.
I'm using similar string, but with one difference. It is transmitted via serial port to the host PC. In this case, string is present in flash memory. If you don't want to tansmit it, try to use some dummy function, in which this string is somehow used.
Andrey Shemet, that's my last resort. I'd prefer to find another way if there is one.
"--keep date_time"
seems to work instead of
"--keep=date_time"
Just const data in flash, no RAM allocated.
Robert McNamara Weirdly that doesn't work for me. Linker keeps saying