1

I was given some sample code from a vendor that relies on libusb. I get this when I try to compile using make:

mkdir -p .obj
gcc -I./ -I../libsoccptp/include -std=gnu++11 -pthread -g -o .obj/authentication.o -c authentication.cpp -lusb-1.0 -lusb
gcc -std=gnu++11 -pthread -g -o ../out/bin/authentication .obj/authentication.o -L../out/lib -lsoccptp -L/usr/lib -lusb-1.0 -lstdc++ -lusb-1.0 -lusb
../out/lib/libsoccptp.so: undefined reference to `libusb_has_capability'
../out/lib/libsoccptp.so: undefined reference to `libusb_hotplug_register_callback'
../out/lib/libsoccptp.so: undefined reference to `libusb_handle_events_timeout_completed'
../out/lib/libsoccptp.so: undefined reference to `libusb_hotplug_deregister_callback'
collect2: error: ld returned 1 exit status
Makefile:28: recipe for target '../out/bin/authentication' failed
make: *** [../out/bin/authentication] Error 1

I've found lots of other posts by people with similar problems getting libusb to link correctly. But it seems like the solution for others is just making sure -lusb-1.0 and -lusb are added as arguments to the compiler. Clearly, my vendor has already set up the Makefile to do just that. I've also verified I have the latest version of libusb-1.0 on Ubuntu, which is supposedly the same environment my vendor uses.

Why is it not linking correctly?

For reference, here's the Makefile:

ROOT_DIR ?= ..
OUT ?= ../out
OUT_DIR := $(OUT)/bin
CC := gcc

LIBS := -L${OUT}/lib -lsoccptp -L/usr/lib -lusb-1.0 -lstdc++

override INCLUDES += -I./ -I${ROOT_DIR}/libsoccptp/include

.PHONY: clean

OBJ_DIR := .obj
SOURCES := authentication.cpp shoot_an_image_and_get_it.cpp check_LiveView_status_and_get_images.cpp parser_handling.cpp list_objects.cpp change_camera_setting.cpp
OBJECTS := $(addprefix $(OBJ_DIR)/, $(notdir $(SOURCES:.cpp=.o)))
TARGETS := $(addprefix ${OUT_DIR}/, $(notdir $(basename ${SOURCES})))

all: ${OUT_DIR} $(OBJ_DIR) ${TARGETS}

objs: $(OBJ_DIR) $(OBJECTS)

$(OBJ_DIR)/%.o : %.cpp
    $(CC) $(INCLUDES) -std=gnu++11 -pthread -g -o $@ -c $< -lusb-1.0 -lusb

$(OUT_DIR)/%: $(OBJ_DIR)/%.o
    ${CC} -std=gnu++11 -pthread -g -o $@ $< ${LIBS} -lusb-1.0 -lusb

${OUT_DIR}:
    mkdir -p ${OUT_DIR}

$(OBJ_DIR):
    mkdir -p $(OBJ_DIR)

clean:
    rm -rf ${TARGETS} $(OBJ_DIR)
Dan Laks
  • 211
  • 2
  • 9

2 Answers2

1

After discussion with an engineer from the vendor that provided the software, it was determined that I was using a newer version of Ubuntu (v16) then they had developed the software on. When I compiled on the older version (v14), it compiled just fine.

The engineer wasn't able to explain what changed in Ubuntu 16 that broke their code, but this solved the problem for me for now.

Dan Laks
  • 211
  • 2
  • 9
0

The solution that worked for me to resolve this error when compiling RISC-V OpenOCD with libusb was to define these environment variable values, in this particular case for libusb v1.0.26 using WSL from /mnt/c/workspace/riscv-openocd with the libusb installed as a subdirectory.

Run these commands from that project directory:

export LIBUSB_VER=libusb-1.0.26
export LIBUSB1_LIBS="-lusb-1.0 -L$PWD/$LIBUSB_VER/libusb"
export LIBUSB1_CFLAGS="-lusb -lusb-1.0 -isystem $PWD/$LIBUSB_VER/libusb"

So in my case:

echo $LIBUSB_VER
echo $LIBUSB1_LIBS
echo $LIBUSB1_CFLAGS

Results in these values:

0 $  echo $LIBUSB_VER
libusb-1.0.26

0 $  echo $LIBUSB1_LIBS
-lusb-1.0 -L/mnt/c/workspace/riscv-openocd/libusb-1.0.26/libusb

0 $  echo $LIBUSB1_CFLAGS
-lusb -lusb-1.0 -isystem /mnt/c/workspace/riscv-openocd/libusb-1.0.26/libusb

Having those environment variables resolved the undefined reference to libusb functions error message.

gojimmypi
  • 426
  • 4
  • 7