Skip to content
This repository has been archived by the owner on Apr 16, 2021. It is now read-only.

Error when linking against recent libmbed.a when not using as an mbed library #9

Open
ohazi opened this issue Sep 5, 2019 · 0 comments

Comments

@ohazi
Copy link

ohazi commented Sep 5, 2019

The following doesn't actually work:

#if !defined(ARDUINO_AS_MBED_LIBRARY)
#define PinMode MbedPinMode
#ifdef F
#define Arduino_F F
#undef F
#endif // F (mbed included after arduino.h)
#define F Mbed_F
#endif // !ARDUINO_AS_MBED_LIBRARY
#include "mbed.h"
#undef PinMode

The problem here is that both Arduino and mbed-os have a PinMode enum, and users of either platform expect that name to map to what they're used to.

I believe this was trying to get around the problem by #defining PinMode to something that wouldn't conflict, pulling in all of the mbed headers so that they would use the new name, and then #undefining it so that the Arduino API could use the PinMode name normally.

You might be able to do this with a header-only library if you're careful, but it won't work if you need to link against any pre-compiled artifacts that expect the original symbol name, like we do here with libmbed.a.

If you try to do this with a recent mbed-os, you'll get a linker error:

/tmp/arduino_build_196822/core/core.a(wiring_digital.cpp.o):
In function `pinMode':
.../cores/arduino/wiring_digital.cpp:57:
undefined reference to `mbed::DigitalIn::mode(MbedPinMode)'

which makes sense, since mode() expects a different type as the parameter:

$ arm-none-eabi-objdump -Ct libmbed.a | grep DigitalIn::mode
00000000         *UND*	00000000 mbed::DigitalIn::mode(PinMode)
00000000 g     F .text._ZN4mbed9DigitalIn4modeE7PinMode	0000001a mbed::DigitalIn::mode(PinMode)

One way you could tell the linker that these types are the same is with a typedef, but you can't un-typedef a symbol name and reuse it later like you can with the macro.

Another option would be to apply this macro substitution when compiling libmbed.a. You'd end up needing two versions of libmbed.a (one compiled with the substitution, and another compiled without it) if you wanted to be able to use either name depending on whether ARDUINO_AS_MBED_LIBRARY is defined, which seems to be what was intended here. Although selectively linking based off of a #define sounds painful.

I think the simplest fix would be to simply rename Arduino's PinMode enum to ArduinoPinMode. I don't think this would cause incompatibilities with legacy Arduino sketches, since most of them just use the enum variants as constants without referring to the enum type directly, although I suppose it's possible that somebody did this at one point.

ohazi added a commit to ohazi/ArduinoCore-nRF528x-mbedos that referenced this issue Sep 5, 2019
This was referenced Sep 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant