Skip to content
This repository was archived by the owner on Apr 16, 2021. It is now read-only.
This repository was 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

Description

@ohazi

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions