Problem with lib jsmn linking, could anybody help?


I have the problem that I want to use the jsmn library with the package handling from RIOT, but the linker goes into arm-none-eabi library for linking. The error message is below.

I created my own module where the entry for the JSMN library is written into the Makefile.dep. This function is used in a cpp file. The function that I use looks like this:

static void jsonRequestDispatcher(char *request)
    int r = jsmn_parse(&parser, request, strlen(request), tokens, MAX_TOKENS);
    if (r < 0) {
    if (r < 1 || tokens[0].type != JSMN_OBJECT) {
    int id = -1;
    const char *method= NULL;
    for (int i = 1; i < r; i++) {
        if (json_streq(request, &tokens[i], "method") == 0) {
            method = jsmn_get_string(request, &tokens[i+1]);
        else if (json_streq(request, &tokens[i], "id") == 0) {
            id = jsmn_get_int(request, &tokens[i+1]);
        else if (json_streq(request, &tokens[i], "jsonrpc") == 0) {
            if (jsmn_get_string(request, &tokens[i+1]) == NULL ||
                strcmp(jsmn_get_string(request, &tokens[i+1]), "2.0") != 0) {
                sprintf(request, "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32600,\"message\":\"Invalid Request\"},\"id\":%d}", id);
    if (method == NULL || id < 0) {
        sprintf(request, "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32600,\"message\":\"Invalid Request\"},\"id\":%d}", id);
    } else if (strcmp(method, "") == 0) {
        sprintf(request, "{\"jsonrpc\":\"2.0\",\"result\":{\"status\":\"OK\"},\"id\":%d}", id);
    }else if (strncmp(method, "device",strlen("device")) == 0) {
        /* TODO for execute, stop, record, monitor, info Library Communication*/
        sprintf(request, "{\"jsonrpc\":\"2.0\",\"result\":{\n \"options\":{}},\"id\":%d}", id);
    }else {
        sprintf(request, "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32601,\"message\":\"Method not found\"},\"id\":%d}", id);

The error message:

/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: /home/pi/muscle-device-microcontroller/app/bin/nucleo-f429zi/rpc_muscle/rpc_muscle.o: in function `jsmn_parse':
/home/pi/muscle-device-microcontroller/RIOT/build/pkg/jsmn/jsmn.h:269: multiple definition of `jsmn_parse';
/home/pi/muscle-device-microcontroller/app/bin/nucleo-f429zi/application_muscle_device/main.o:/home/pi/muscle-device-microcontroller/RIOT/build/pkg/jsmn/jsmn.h:269: first defined here
/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: /home/pi/muscle-device-microcontroller/app/bin/nucleo-f429zi/rpc_muscle/rpc_muscle.o: in function `jsmn_init':
/home/pi/muscle-device-microcontroller/RIOT/build/pkg/jsmn/jsmn.h:460: multiple definition of `jsmn_init'; /home/pi/muscle-device-microcontroller/app/bin/nucleo-f429zi/application_muscle_device/main.o:/home/pi/muscle-device-microcontroller/RIOT/build/pkg/jsmn/jsmn.h:460: first defined here
collect2: error: ld returned 1 exit status

The Makefile.dep looks like this:

ifneq (,$(filter rpc_muscle,$(USEMODULE)))
USEMODULE += ipv4_addr
USEMODULE += lwip_arp
USEMODULE += lwip_ipv4
USEMODULE += lwip_dhcp_auto
USEMODULE += lwip lwip_netdev
USEMODULE += lwip_udp
USEMODULE += lwip_tcp
USEMODULE +=ztimer_usec
USEMODULE += sock_async_event
USEMODULE += sock_ip
USEMODULE += sock_tcp
USEMODULE += sock_udp
USEMODULE += sock_util
USEMODULE += netdev_default
USEMODULE += od_string
USEPKG += jsmn

Did anybody until now had this problem?

You’re hitting a quirk of jsmn being a “single header C library”.

If you include jsmn.h in multiple ‘.c’ files, all but one must #define JSMN_HEADER before including ‘jsmn.h’.

See GitHub - zserge/jsmn: Jsmn is a world fastest JSON parser/tokenizer. This is the official repo replacing the old one at Bitbucket details.

Thanks a lot I missed the information on the GitHub page from zserge.