I am trying to develop an application using GreatScottGadget's Ubertooth One. To start, I need to be able to use the libusb library. I'm working with Ubuntu 20.04.
I have a simple CMakeLists.txt file that sets the module path to a path in my project that contains all the Find*.cmake files that I stole from the ubertooth repository here. I include libusb like so:
find_package(USB1 REQUIRED)
When I run CMake, this is the error I get:
Could not find package configuration file provided by "USB1" with any of the following names:
USB1Config.cmake
usb1-config.cmake
Add the installation prefix of "USB1" to CMAKE_PREFIX_PATH or set
"USB1_DIR" to a directory containing one of the above files. If "USB1"
provides a separate development package or SDK, be sure that it has been
installed.
As far as I can tell, I have libusb already installed. apt list --installed | grep libusb shows libusb-1.0.0-dev/focal,now 2:1.0.23-2build1 amd64 [installed] (among others). I can see the shared object in /usr/lib/x86_64-linux-gnu
$ ls /usr/lib/x86_64-linux-gnu | grep libusb
libusb-0.1.so.4
libusb-0.1.so.4.4.4
libusb-1.0.a
libusb-1.0.so
libusb-1.0.so.0
libusb-1.0.so.0.2.0
libusbmuxd.so.6
libusbmuxd.so.6.0.0
Additionally, I can build the host code provided in the ubertooth repository just fine. In the CMake output, I see the following:
-- Checking for module 'libusb-1.0'
-- Found libusb-1.0, version 1.0.23
-- Found LIBUSB: /usr/lib/x86_64-linux-gnu/libusb-1.0.so
Looking through the ubertooth repository, I don't see anything special they are doing to find the package. The host project adds libubertooth as a subdirectory, in in its CMakeLists.txt, it uses the same method I have to find the library. I'm not seeing any other differences.
Maybe I'm misunderstanding and the libubertooth subdirectory isn't where the library is being found. Maybe there's some global config that I'm not setting. I haven't managed to find whatever it is.
I checked the libusb homepage and downloaded the source, but I didn't find any USB1Config.cmake files, so I'm not sure how this is supposed to work.
What am I missing to be able to find the library and use it in my project?
This is because you don't have a FindUSB1.cmake in you project. You can find it on ubertooth/host/cmake/modules/FindUSB1.cmake.
BTW, don't use stole, you can find ubertooth's license, it's GPL-2.0
Related
I am cross-compiling a C library using CMake and a toolchain file. My toolchain file sets CMAKE_SYSROOT to the appropriate value so compilation works with no issues. However, when installing, the library does not install to the directory pointed to by CMAKE_SYSROOT. I can achieve that effect by running make install DESTDIR=xxx though.
I understand that there are two separate concepts here:
The cross-compilation toolchain, which consists of binaries that can be run on my local architecture
The CMAKE_SYSROOT which is the root directory of a target-architecture filesystems, containing header files and libraries, passed to e.g. gcc through the --sysroot flag.
I have two questions:
Is it a good idea to conflate the sysroot where my cross-compilation toolchain lives, with the sysroot where all my cross-compiled libraries will be installed? It feels to me like it should be the same, but am not sure, and to CMake it appears they are distinct concepts. Update: answered in the comments below, these are indeed distinct concepts.
What is the modern CMake way to specify the installation directory when cross-compiling like described above? Update: I believe this should be the same as CMAKE_SYSROOT, and I feel CMake should offer a way to only define this once somewhere.
Thanks!
There is no interference between sysroot and install directory (prefix).
Sysroot is given by CMAKE_SYSROOT variable and denotes prefix for tools used during build process.
Install directory(prefix) is given by CMAKE_INSTALL_PREFIX variable and denotes the path, where the project will be used upon installation. E.g. with install prefix /usr/local the project's executable foo expects to be run as /usr/local/bin/foo.
Note, that with default installation procedure, CMake installs files to the host machine. For install files onto the target machine, this procedure is needed to be adjusted. Parameter DESTDIR=xxx for make install is a way for install files directly to the target machine. Another way is to create a package (e.g. with CPack) on host, and install that package on target machine.
Note, that in the above paragraph it is irrelevant, whether cross-compilation took a place or not: it is possible to build the project on one machine and install it to the other, but similar one, without any cross-compilation.
I'm trying to compile VLC on a Ubuntu machine. So after getting all the additional packages required for build, when I run ./configure it says Qt5Core along with a few other Qt related libraries are not found. The problem is that I know that a complete installation of Qt5 and it's libraries are available on my system in the home directory rather than global directory. When building it seems that pkg-config does not check the home directory. How do I inform the actual location of Qt5 installation to the build system?
Note: I have tried downloading Qt from apt sources but that installation was for Qt5.9 rather than the required Qt5.11.
configure needs to fnd the .pc files for Qt modules,
If you check config.log , it might be complaining about that :
configure:xxxx: $PKG_CONFIG --exists --print-errors "Qt5Core >= 5.11.0 Qt5Widgets Qt5Gui Qt5Quick Qt5QuickWidgets Qt5QuickControls2 Qt5Svg"
Package Qt5Quick was not found in the pkg-config search path.
Perhaps you should add the directory containing `Qt5Quick.pc'
to the PKG_CONFIG_PATH environment variable
No package 'Qt5Quick' found
Package Qt5QuickWidgets was not found in the pkg-config search path.
Perhaps you should add the directory containing `Qt5QuickWidgets.pc'
to the PKG_CONFIG_PATH environment variable
There, and to link configure to a specific Qt installation, you have a couple of options ,
Either export variable QT_LIBS
export QT_LIBS=/path/to/qt/libs/
OR , directly add Qt pkgconfig path containing the .pc files to shell PKG_CONFIG_PATH,
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/path/to/qt/libs/pkgconfig/
I'm trying to build a cmake project, and the repo I have been given has the lines
find_library(gmp gmp)
if(NOT gmp)
message(FATAL_ERROR "gmp not found")
endif()
which cause CMake configuration to fail.
I have been told this CMake works on Redhat Enterprise Linux 7.3.
I have also been told this repo should build in any Linux environment with the correct libraries installed, and an Ubuntu environment has been specifically referenced.
I am building in Debian 9.4.0, I have installed gmp, libgmp.so is located at /usr/lib/x86_64-linux-gnu/openssl-1.0.2/engines/libgmp.so
and I also have a libgmp.so.10 at /usr/lib/x86_64-linux-gnu/libgmp.so.10.
So, to recap, I have been handed a repo I have been told builds, but it does not build, it fails at this specific step, and I can't get google to give me any relevant results on how to fix the issue/what I am doing wrong.
libgmp is installed, but the development libraries are not.
Cmake find_libraries looks for the files required for software development, and while the libgmp package is installed, the libgmp-dev package is not.
Install libgmp-dev.
CMake doesn't search "so-version" files:
If find_library is called for "gmp" library name, CMake searches libgmp.so file, but not libgmp.so.10 one.
Normally, the library file without so-version is just a soft link to the newest so-version file. If your Linux distro doesn't create such link, you may create it manually:
ln -s libgmp.so libgmp.so.10
If you want CMake to find /usr/lib/x86_64-linux-gnu/openssl-1.0.2/engines/libgmp.so file, which is not under directory normally searched by CMake, you need to hint CMake about it. E.g. with PATHS option:
find_library(gmp gmp PATHS "/usr/lib/x86_64-linux-gnu/openssl-1.0.2/engines")
I've just started working with CMake and I noticed that they have both a find_package and a find_library. And this confuses me. Can somebody explain the difference between a package and a library in the world of programming? Or, in the world of CMake?
Appreciate it, guys!
Imagine you want to use zlib in your project, you need to find the header file zlib.h, and the library libz.so (on Linux). You can use the low-level cmake commands find_path and find_library to find them, or you can use find_package(ZLIB). The later command will try to find out all what is necessary to use zlib. It can be extra macro definitions, or dependencies.
Update, more detail about find_package: when the CMake command find_package(SomeThing) is called, as in the documentation, there are two possible modes that cmake can run:
the module mode (that searches for a file FindSomeThing.cmake)
or the config mode (that searches for a file named SomeThingConfig.cmake)
For ZLIB, there is a module named FindZLIB, shipped with CMake itself (on my Linux machine that is the file /usr/share/cmake/Modules/FindZLIB.cmake). That module is a CMake script that uses the CMake API to search for ZLIB files in default locations, or ask the user for the location if it cannot be found automatically.
I configure and package my library using CMake and CPack. I have written my own find-module: FindMyLib.cmake.
How do I tell CMake/CPack to add this file to the CMake module directory, so that future developers can simply specify FIND_PACKAGE(MyLib) to use my library?
You can set CMAKE_MODULE_PATH and distribute your custom FindFoo.cmake with your project. For example:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
The CMake module directory is part of the install tree of CMake itself, and as such you shouldn't be trying to add anything there.
The CMake module directory contains modules which have been written or at least reviewed by Kitware, and adding your own there would give the impression to users of your project that this was the case for your project also.
You'd be better to just install FindMyLib.cmake to one of the places searched by find_package:
<prefix>/ (Windows)
<prefix>/(cmake|CMake)/ (Windows)
<prefix>/<name>*/ (Windows)
<prefix>/<name>*/(cmake|CMake)/ (Windows)
<prefix>/(lib/<arch>|lib|share)/cmake/<name>*/ (Unix)
<prefix>/(lib/<arch>|lib|share)/<name>*/ (Unix)
<prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (Unix)
<prefix>/<name>.framework/Resources/ (Apple)
<prefix>/<name>.framework/Resources/CMake/ (Apple)
<prefix>/<name>.framework/Versions/*/Resources/ (Apple)
<prefix>/<name>.framework/Versions/*/Resources/CMake/ (Apple)
<prefix>/<name>.app/Contents/Resources/ (Apple)
<prefix>/<name>.app/Contents/Resources/CMake/ (Apple)
See the documentation for find_package for the full details of how find_package searches. Also the CMake packaging tutorial is useful in this case.
The best way to allow
future developers can simply specify FIND_PACKAGE(MyLib) to use my library
is to write a package config file (-config.cmake) , not a Find module.
The package config file should then be installed in one of the folders where the FindPackage module looks for (something like /lib/package/ or /lib/cmake/package the second being preferred)
The FindPackage module will automatically load the config file if it can find it there.
The CMake wiki has more detailed instructions at https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/Packaging