Linking libraries with Weak symbols

Recently I’ve started having problems while linking a ststm32 program. The linking succeeds but the linker uses the Weak interrupt handlers instead of the normal (strong) ones. You can often solve this problem by linking individual object files instead of library archives. I tried forcing PlatformIO to not use the framework library archives with the following in my platformio.ini.

lib_archive = false

But this didn’t make any difference, the framework library archives are still being created and the weak handlers are used instead of the strong ones.

Any suggestions?

I ran in a quite similar issue with a interrupt handler which was implemented in a cpp file. Therefor the c++ compiler mangle the name (which is required for overloading functions in c++) and the weak handler was not replaced by the “normal” one. The solution is to wrap the function with the extern "C" { ... } command. The compiler will not longer mangle the name of the function and replaces the weak function correctly.

Hope this helps.


Unfortunately, the weak symbol (and the normal one too) are down deep in the framework code which I don’t have easy access to. Best if I find some way around it. Thanks though.

Is the interrupt function declared in C code and you’re implementing it in a CPP file? Then you need to change your CPP function to include the extern "C" declaration, not the one in the framework code.

No, this is all in C code. It’s a understood problem with the gcc linker in that when the linker searches archived libraries it stops at the first occurrence of the symbol even if it’s a weak symbol. The solution is not to archive the libraries using lib_archive = false but that doesn’t seem to working for me.

You can further invest the build process by doing a verbose build. pio run -v. You should then see how the linker is invoked and why that’s maybe wrong, then we can get it fixed.

Done that. Even tried hacking with by using PlatformIO’s advanced scripting but none of that should be necessary since PlatformIO has a builtin mechanism for this problem (the lib_archive = false option) but I can’t seem to get it to work. I escalated it up to a GitHub issue `lib_archive = false` not disabling library archiving · Issue #205 · platformio/platform-ststm32 · GitHub

Thanks for looking.

Thank you so much for reporting this issue. lib_archive = false works for dependent libraries. In your case, you would like also disable archiving of Arduino Core and its Variant.

This is a bug, we will think how to resolve it in `lib_archive = false` not disabling library archiving · Issue #205 · platformio/platform-ststm32 · GitHub


This default setting is unintuitive and unexpected, especially if done under the hood. IMHO, since the interrupt handlers are very frequently defined with weak substitutes, the default archiving of the /lib folder resulted in two weeks of frustration with platformio for me. It is not same for other conventional tools.

I placed the /rtos in the /lib folder, and the known working program stopped working. The story is here:

I think the default decision is wrong, and the tool should default to “false” always. If the developer knows what they are doing, they may explicitly alter the default. And it should be spelled in bold in “Beware” section. And also the lib_archive must be always included in the automatically generated (.ini) file, with a comment what it does and what will happen when it is changed.