Search code examples
c++cmakefilecmakelibusb

CMake/Make cannot find libusb


I'm new to C/C++ and am trying to build and run ttwatch from github locally on an Ubuntu machine (Trusty Tahr). Instructions include installing some libraries first: cmake, openssl, curl, libusb, and include a note to install the "-dev" versions (eg. libssl-dev, libcurl-dev, libusb-1.0-0-dev). I'm having some trouble with libusb. I see questions about this all over the internet, but haven't yet found a solution that works.

Running cmake . appears to work fine:

meowmeow@kittytown:~/code/ttwatch$ cmake .
-- Enabled daemon function
-- Found libusb-1.0:
--  - Includes: /usr/include/libusb-1.0
--  - Libraries: /usr/lib/x86_64-linux-gnu/libusb.so
-- Configuring done
-- Generating done
-- Build files have been written to: /home/meowmeow/code/ttwatch

But running make shows that libusb is not being located properly:

meowmeow@kittytown:~/code/ttwatch$ make
[ 42%] Built target libttbin
[ 42%] Built target libttwatch
[ 42%] Built target ttbincnv
[ 42%] Built target ttbinmod
[ 42%] Built target manifest
Linking CXX executable ttwatch
CMakeFiles/ttwatch.dir/src/ttwatch.c.o: In function `main':
/home/meowmeow/code/ttwatch/src/ttwatch.c:1618: undefined reference to `libusb_init'
/home/meowmeow/code/ttwatch/src/ttwatch.c:1796: undefined reference to `libusb_exit'
...

If I check /usr/includes/, I see libusb:

meowmeow@kittytown:~/code/ttwatch$ ls /usr/include/libusb-1.0/libusb.h 
/usr/include/libusb-1.0/libusb.h

And dpkg shows:

meowmeow@kittytown:~/code/ttwatch$ dpkg -L libusb-1.0-0-dev
/.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/libusb-1.0.pc
/usr/lib/x86_64-linux-gnu/libusb-1.0.a
/usr/share
/usr/share/doc
/usr/share/doc/libusb-1.0-0-dev
/usr/share/doc/libusb-1.0-0-dev/copyright
/usr/include
/usr/include/libusb-1.0
/usr/include/libusb-1.0/libusb.h
/usr/lib/x86_64-linux-gnu/libusb-1.0.so
/usr/share/doc/libusb-1.0-0-dev/README
/usr/share/doc/libusb-1.0-0-dev/changelog.Debian.gz


meowmeow@kittytown:~/code/ttwatch$ dpkg -L libusb-1.0-0
/.
/lib
/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu/libusb-1.0.so.0.1.0
/usr
/usr/share
/usr/share/doc
/usr/share/doc/libusb-1.0-0
/usr/share/doc/libusb-1.0-0/README
/usr/share/doc/libusb-1.0-0/copyright
/usr/share/doc/libusb-1.0-0/changelog.Debian.gz
/lib/x86_64-linux-gnu/libusb-1.0.so.0

The file ttwatch/includes/libttwatch.h includes libusb as #include <libusb.h>, and I've tried modifying that to #include <libusb-1.0/libusb.h>, in hopes of better matching my /usr/includes/ files, but that didn't change the error output.

Any help would be greatly appreciated!

EDIT: Using make VERBOSE=1does show -lusb, and not -lusb-1.0:

...
/usr/bin/c++ -g CMakeFiles/ttwatch.dir/src/ttwatch.c.o CMakeFiles/ttwatch.dir/src/log.c.o CMakeFiles/ttwatch.dir/src/options.c.o CMakeFiles/ttwatch.dir/src/json.c.o CMakeFiles/ttwatch.dir/src/download.c.o CMakeFiles/ttwatch.dir/src/firmware.c.o CMakeFiles/ttwatch.dir/src/misc.c.o CMakeFiles/ttwatch.dir/src/get_activities.c.o CMakeFiles/ttwatch.dir/src/update_gps.c.o CMakeFiles/ttwatch.dir/src/set_time.c.o -o ttwatch -rdynamic libttwatch.a libttbin.a -lusb -lssl -lcrypto -lcurl

And libusb.so appears to exist:

meowmeow@kittytown:~/code/ttwatch$ dpkg-query -S /usr/lib/x86_64-linux-gnu/libusb.so 
libusb-dev: /usr/lib/x86_64-linux-gnu/libusb.so

I tried uninstalling libusb-dev (sudo apt-get remove libusb-dev) and installed libusb-1.0 (sudo apt-get install libusb-1.0) to see if that would solve the issue. I now have a /usr/lib/x86_64-linux-gnu/libusb-1.0.so (note the 1.0) instead, but am now getting this from make:

make[2]: *** No rule to make target /usr/lib/x86_64-linux-gnu/libusb.so', needed by ttwatch'. Stop.

Solution

  • I was not aware that Debian has the packages libusb-dev and libusb-1.0-dev. From the package information I cannot tell why there are 2 packages for the same library, perhaps libusb-dev is an older version with a different API and other packages might still have that as a dependency. So removing the package might not be a good idea, unless you don't care/need packages depending on libusb-dev, in which case you can do apt-get purge libusb-dev && apt-get autoremove. Be ware that this might uninstall packages that you need. So do it only if you know what you are doing.

    I did not expect that Debian allows you to install both packages at the same time, but this could be if the APIs of both libraries are different and don't conflict with each other.

    This seems to confuse cmake, which somehow cannot handle when both libraries are simultaneously installed. I've gone through the issues page and I haven't found an issue relating to that. So if you cannot manage to build it, I'd suggest that you go to the issue page, if you don't have an github account, create one and leave a bug report about building the package when libusb-dev and libusb-1.0-dev are simultaneously installed.

    Another option would be to make a small modification in the file cmake_modules/FindLibUSB.cmake before you do

    $ mkdir build && cd build
    $ cmake ..
    

    Find the line find_library(LIBUSB_1_LIBRARY, on the current stable version it is line 62. The next line is NAMES and the next line is usb-1.0 usb. Remove the usb from that, so that find_library only searches for libusb-1.0. Save the file and then you can do

    $ mkdir build && cd build
    $ cmake ..
    

    This should fix the problem.