-
Notifications
You must be signed in to change notification settings - Fork 410
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CMake build system #220
Closed
Closed
Changes from 42 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
bf64499
add CMake build system
Youw 1bfcadc
CMake: add Windows build
Youw 095831f
CMake: add Darwin build
Youw a7e4285
add .pc generation for CMake build
7246840
add CMake export package installation
Youw 5e2436c
hidapi::hidapi as INTERFACE IMPORTED instead of ALIAS
Youw 1046923
handle static lib build exports
Youw d1bef57
install export order matters
Youw 88b253c
CMake package: support older version syntax
Youw 053597e
Merge branch 'master' into cmake-support
Youw a2a51cd
Merge branch 'master' into cmake-support
Youw 7260981
Merge branch 'master' into cmake-support
Youw fd64175
fix macOS build
Youw 443ea8f
Sync with v0.10.1 (master)
Youw 0c0f3b8
don't search pkg-config libusb, if CMake target usb-1.0 exists
Youw 7b53333
Update README.md
Youw ad7cc64
Merge remote-tracking branch 'origin/master' into cmake-support
Youw 9f7f81d
Update CMakeLists.txt
Youw 4b8f881
always use libhidapi-libusb.so for libusb backend
Youw 8ae8ffb
optionally specify possible values for CMAKE_BUILD_TYPE
Youw c393b88
BUILD_HIDTEST->HIDAPI_BUILD_HIDTEST to have consistent custom prefix
Youw 633a5ae
macos CI for CMake
Youw 81291b2
don't add (custom) build options, when a subdirectory of a bigger pro…
Youw 00fe9c0
Merge branch 'master' into cmake-support
Youw f1cd808
Explicitly check for trying to install 'EXCLUDE_FROM_ALL' hidapi
Youw 11021c0
Merge branch 'master' into cmake-support
Youw 84d7d57
Fix MinGW build on Linux/Unix platforms
Youw 197ae97
Merge remote-tracking branch 'origin/master' into cmake-support
Youw fe48fa0
documentation refactoring
Youw a323c29
Merge remote-tracking branch 'origin/master' into cmake-support
Youw 3235566
explicitly check for valid VERSION file
Youw 9801eb4
compatibility target aliases
Youw c7dfdb9
Merge branch 'master' into cmake-support
Youw ba9983f
optional CMAKE_FRAMEWORK variable
Youw 9b3afa1
MSVC support update
Youw aca4bd9
another piece of documentation drop
Youw 23f1bbe
fix doc link
Youw 4c1824e
CMake build documentation done
Youw a2c963c
save
Youw 4579257
save doc
Youw 609098e
Update CMakeLists.txt
Youw 0487a8c
non-ninja example
Youw 227ad87
add "build dir" description
Youw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# Building HIDAPI using Autotools | ||
|
||
To be able to use Autotools to build HIDAPI, it has to be [installed](#installing-autotools)/available in the system. | ||
|
||
Make sure you've checked [prerequisites](BUILD.md#prerequisites) and installed all required dependencies. | ||
|
||
## Installing Autotools | ||
|
||
HIDAPI uses few specific tools/packages from Autotools: `autoconf`, `automake`, `libtool`. | ||
|
||
On different platforms or package managers, those could be named a bit differently or packaged together. | ||
You'll have to check the documentation/package list for your specific package manager. | ||
|
||
### Linux | ||
|
||
On Ubuntu the tools are available via APT: | ||
|
||
```sh | ||
sudo apt install autoconf automake libtool | ||
``` | ||
|
||
### FreeBSD | ||
|
||
FreeBSD Autotools can be installed as: | ||
|
||
```sh | ||
pkg_add -r autotools | ||
``` | ||
|
||
Additionally, on FreeBSD you will need to install GNU make: | ||
```sh | ||
pkg_add -r gmake | ||
``` | ||
|
||
## Building HIDAPI with Autotools | ||
|
||
A simple command list, to build HIDAPI with Autotools as a _shared library_ and install in into your system: | ||
|
||
```sh | ||
./bootstrap # this prepares the configure script | ||
./configure | ||
make # build the library | ||
make install # as root, or using sudo, this will install hidapi into your system | ||
``` | ||
|
||
`./configure` can take several arguments which control the build. A few commonly used options: | ||
```sh | ||
--enable-testgui | ||
# Enable the build of Foxit-based Test GUI. This requires Fox toolkit to | ||
# be installed/available. See README.md#test-gui for remarks. | ||
|
||
--prefix=/usr | ||
# Specify where you want the output headers and libraries to | ||
# be installed. The example above will put the headers in | ||
# /usr/include and the binaries in /usr/lib. The default is to | ||
# install into /usr/local which is fine on most systems. | ||
|
||
--disable-shared | ||
# By default, both shared and static libraries are going to be built/installed. | ||
# This option disables shared library build, if only static library is required. | ||
``` | ||
|
||
|
||
## Cross Compiling | ||
|
||
This section talks about cross compiling HIDAPI for Linux using Autotools. | ||
This is useful for using HIDAPI on embedded Linux targets. These | ||
instructions assume the most raw kind of embedded Linux build, where all | ||
prerequisites will need to be built first. This process will of course vary | ||
based on your embedded Linux build system if you are using one, such as | ||
OpenEmbedded or Buildroot. | ||
|
||
For the purpose of this section, it will be assumed that the following | ||
environment variables are exported. | ||
```sh | ||
$ export STAGING=$HOME/out | ||
$ export HOST=arm-linux | ||
``` | ||
|
||
`STAGING` and `HOST` can be modified to suit your setup. | ||
|
||
### Prerequisites | ||
|
||
Depending on what backend you want to cross-compile, you also need to prepare the dependencies: | ||
`libusb` for libusb HIDAPI backend, or `libudev` for hidraw HIDAPI backend. | ||
|
||
An example of cross-compiling `libusb`. From `libusb` source directory, run: | ||
```sh | ||
./configure --host=$HOST --prefix=$STAGING | ||
make | ||
make install | ||
``` | ||
|
||
An example of cross-comping `libudev` is not covered by this section. | ||
Check `libudev`'s documentation for details. | ||
|
||
### Building HIDAPI | ||
|
||
Build HIDAPI: | ||
```sh | ||
PKG_CONFIG_DIR= \ | ||
PKG_CONFIG_LIBDIR=$STAGING/lib/pkgconfig:$STAGING/share/pkgconfig \ | ||
PKG_CONFIG_SYSROOT_DIR=$STAGING \ | ||
./configure --host=$HOST --prefix=$STAGING | ||
# make / make install - same as for a regular build | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
# Building HIDAPI using CMake | ||
|
||
To build HIDAPI with CMake, it has to be [installed](#installing-cmake)/available in the system. | ||
|
||
Make sure you've checked [prerequisites](BUILD.md#prerequisites) and installed all required dependencies. | ||
|
||
HIDAPI CMake build system allows you to build HIDAPI in two generally different ways: | ||
1) As a [standalone package/library](#standalone-package-build); | ||
2) As [part of a larger CMake project](#hidapi-as-a-subdirectory). | ||
|
||
**TL;DR**: if you're experienced developer and have been working with CMake projects or have been written some of your own - | ||
most of this document may not be of interest for you; just check variables names, its default values and the target names. | ||
|
||
## Installing CMake | ||
|
||
CMake can be installed either using your system's package manager, | ||
or by downloading an installer/prebuilt version from the [official website](https://cmake.org/download/). | ||
|
||
On most \*nix systems, the prefered way to install CMake is via package manager, | ||
e.g. `sudo apt install cmake`. | ||
|
||
On Windows CMake could be provided by your development environment (e.g. by Visual Studio Installer or MinGW installer), | ||
or you may install it system-wise using the installer from the official website. | ||
|
||
On macOS CMake may be installed by Homebrew/MacPorts or using the installer from the official website. | ||
|
||
## Standalone package build | ||
|
||
To build HIDAPI as a standalone package, you follow [general steps](https://cmake.org/runningcmake/) of building any CMake project. | ||
|
||
An example of building HIDAPI with CMake: | ||
```sh | ||
cd <build dir> | ||
# configure the build | ||
cmake <HIDAPI source dir> | ||
# build it! | ||
cmake --build . | ||
# install library; by default installs into /usr/local/ | ||
cmake --build . --target install | ||
# NOTE: you need to run install command as root, to be able to install into /usr/local/ | ||
``` | ||
Such invocation will use the default (as per CMake magic) compiler/build environment available in your system. | ||
|
||
You may pass some additional CMake variables to control the build configuration as `-D<CMake Variable>=value`. | ||
E.g.: | ||
```sh | ||
# install command now would install things into /usr | ||
cmake <HIDAPI source dir> -DCMAKE_INSTALL_PREFIX=/usr | ||
``` | ||
|
||
<details> | ||
<summary>Using a specific CMake generator</summary> | ||
|
||
An example of using `Ninja` as a CMake generator: | ||
|
||
```sh | ||
cd <build dir> | ||
# configure the build | ||
cmake -GNinja <HIDAPI source dir> | ||
# we know, that CMake has generated build files for Ninja, | ||
# so we can use `ninja` directly, instead of `cmake --build .` | ||
ninja | ||
# install library | ||
ninja install | ||
``` | ||
|
||
`-G` here specifies a native build system CMake would generate build files for. | ||
Check [CMake Documentation](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) for a list of available generators (system-specific). | ||
|
||
</details><br> | ||
|
||
Some of the [standard](https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html) CMake variables you may want to use to configure a build: | ||
|
||
- [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html) - prefix where `install` target would install the library(ies); | ||
- [`CMAKE_BUILD_TYPE`](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html) - standard possible values: `Debug`, `Release`, `RelWithDebInfo`, `MinSizeRel`; Defaults to `Release` for HIDAPI, if not specified; | ||
- [`BUILD_SHARED_LIBS`](https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html) - when set to TRUE, HIDAPI is built as a shared library, otherwise build statically; Defaults to `TRUE` for HIDAPI, if not specified; | ||
|
||
<details> | ||
<summary>macOS-specific variables</summary> | ||
|
||
- [`CMAKE_FRAMEWORK`](https://cmake.org/cmake/help/latest/variable/CMAKE_FRAMEWORK.html) - (since CMake 3.15) when set to TRUE, HIDAPI is built as a framework library, otherwise build as a regular static/shared library; Defaults to `FALSE` for HIDAPI, if not specified; | ||
- [`CMAKE_OSX_DEPLOYMENT_TARGET`](https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_DEPLOYMENT_TARGET.html) - minimum version of the target platform (e.g. macOS or iOS) on which the target binaries are to be deployed; defaults to a maximum supported target platform by currently used XCode/Toolchain; | ||
Youw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
</details><br> | ||
|
||
HIDAPI-specific CMake variables: | ||
|
||
- `HIDAPI_BUILD_HIDTEST` - when set to TRUE, build a small test application `hidtest`; | ||
|
||
<details> | ||
<summary>Linux-specific variables</summary> | ||
|
||
- `HIDAPI_WITH_HIDRAW` - when set to TRUE, build HIDRAW-based implementation of HIDAPI (`hidapi-hidraw`), otherwise don't build it; defaults to TRUE; | ||
- `HIDAPI_WITH_LIBUSB` - when set to TRUE, build LIBUSB-based implementation of HIDAPI (`hidapi-libusb`), otherwise don't build it; defaults to TRUE; | ||
|
||
**NOTE**: at least one of `HIDAPI_WITH_HIDRAW` or `HIDAPI_WITH_LIBUSB` has to be set to TRUE. | ||
|
||
</details><br> | ||
|
||
To see all most-useful CMake variables available for HIDAPI, one of the most convenient ways is too use [`cmake-gui`](https://cmake.org/cmake/help/latest/manual/cmake-gui.1.html) tool ([example](https://cmake.org/runningcmake/)). | ||
|
||
_NOTE_: HIDAPI packages built by CMake can be used with `pkg-config`, as if built with [Autotools](BUILD.autotools.md). | ||
|
||
### MSVC and Ninja | ||
It is possible to build a CMake project (including HIDAPI) using MSVC compiler and Ninja (for medium and larger projects it is so much faster than msbuild). | ||
|
||
For that: | ||
1) Open cmd.exe; | ||
2) Setup MSVC build environment variables, e.g.: `vcvarsall.bat x64`, where: | ||
- `vcvarsall.bat` is an environment setup script of your MSVC toolchain installation;<br>For MSVC 2019 Community edition it is located at: `C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\`; | ||
- `x64` -a target architecture to build; | ||
3) Follow general build steps, and use `Ninja` as a generator. | ||
|
||
### Using HIDAPI in a CMake project | ||
|
||
When HIDAPI is used as a standalone package (either installed into the system or built manually and installed elsewhere), the simplest way to use it is as showed in the example: | ||
|
||
```cmake | ||
project(my_application) | ||
|
||
add_executable(my_application main.c) | ||
|
||
find_package(hidapi REQUIRED) | ||
target_link_libraries(my_application PRIVATE hidapi::hidapi) | ||
``` | ||
|
||
If HIDAPI isn't installed in your system, or `find_package` cannot find HIDAPI by default for any other reasons, | ||
the recommended way manually specify which HIDAPI package to use is via `hidapi_ROOT` CMake variable, e.g.: | ||
`-Dhidapi_ROOT=<path to HIDAPI installation prefix>`. | ||
|
||
_NOTE_: usage of `hidapi_ROOT` is only possible (and recommended) with CMake 3.12 and higher. For older versions of CMake you'd need to specify [`CMAKE_PREFIX_PATH`](https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html#variable:CMAKE_PREFIX_PATH) instead. | ||
|
||
Check with [`find_package`](https://cmake.org/cmake/help/latest/command/find_package.html) documentation if you need more details. | ||
|
||
Available CMake targets after successful `find_package(hidapi)`: | ||
- `hidapi::hidapi` - indented to be used in most cases; | ||
- `hidapi::include` - if you need only to include `<hidapi.h>` but not link against the library; | ||
- `hidapi::winapi` - same as `hidapi::hidapi` on Windows; available only on Windows; | ||
- `hidapi::darwin` - same as `hidapi::hidapi` on macOS; available only on macOS; | ||
- `hidapi::libusb` - available when libusb backend is used/available; | ||
- `hidapi::hidraw` - available when hidraw backend is used/available on Linux; | ||
|
||
**NOTE**: on Linux often both `hidapi::libusb` and `hidapi::hidraw` backends are available; in that case `hidapi::hidapi` is an alias for **`hidapi::hidraw`**. The motivation is that `hidraw` backend is a native Linux kernel implementation of HID protocol, and supports various HID devices (USB, Bluetooth, I2C, etc.). If `hidraw` backend isn't built at all (`hidapi::libusb` is the only target) - `hidapi::hidapi` is an alias for `hidapi::libusb`. | ||
If you're developing a cross-platform application and you are sure you need to use `libusb` backend on Linux, the simple way to achieve this is: | ||
```cmake | ||
if(TARGET hidapi::libusb) | ||
target_link_libraries(my_project PRIVATE hidapi::libusb) | ||
else() | ||
target_link_libraries(my_project PRIVATE hidapi::hidapi) | ||
endif() | ||
``` | ||
|
||
## HIDAPI as a subdirectory | ||
|
||
HIDAPI can be easily used as a subdirectory of a larger CMake project: | ||
```cmake | ||
# root CMakeLists.txt | ||
cmake_minimum_required(VERSION 3.4.3 FATAL_ERROR) | ||
|
||
add_subdirectory(hidapi) | ||
add_subdirectory(my_application) | ||
|
||
# my_application/CMakeLists.txt | ||
project(my_application) | ||
|
||
add_executable(my_application main.c) | ||
|
||
# NOTE: no `find_package` is required, since HIDAPI targets are already a part of the project tree | ||
target_link_libraries(my_application PRIVATE hidapi::hidapi) | ||
``` | ||
Lets call this "larger project" a "host project". | ||
|
||
All of the variables described in [standalone build](#standalone-package-build) section can be used to control HIDAPI build in case of a subdirectory, e.g.: | ||
```cmake | ||
set(HIDAPI_WITH_LIBUSB FALSE) # surely will be used only on Linux | ||
set(BUILD_SHARED_LIBS FALSE) # HIDAPI as static library on all platforms | ||
add_subdirectory(hidapi) | ||
``` | ||
|
||
There is two important differences in the behavior of HIDAPI CMake build system when CMake is built as standalone package vs subdirectory build: | ||
|
||
1) In _standalone build_ a number of standard and HIDAPI-specific variables are marked as _cache variables_ or _options_. | ||
This is done for convenience: when you're building HIDAPI as a standalone package and using tools like `cmake-gui` - those are highlighted as variables that can be changed and has some short description/documentation. E.g.: | ||
![an example of highlighted variables in cmake-gui](documentation/cmake-gui-highlights.png "cmake-gui highlighted variables")<br> | ||
E.g.2:<br> | ||
![an example of drop-down menu in cmake-gui](documentation/cmake-gui-drop-down.png "cmake-gui drop-down menu")<br> | ||
When HIDAPI is built as a _subdirectory_ - **_none of the variables are marked for cache or as options_** by HIDAPI. | ||
This is done to let the host project's developer decide what is important (what needs to be highlighted) and what's not. | ||
|
||
2) The default behavior/default value for some of the variables is a bit different: | ||
- by default, none of HIDAPI targets are [installed](https://cmake.org/cmake/help/latest/command/install.html); if required, HIDAPI targets can be installed by host project _after_ including HIDAPI subdirectory (requires CMake 3.13 or later); **or**, the default installation can be enabled by setting `HIDAPI_INSTALL_TARGETS` variable _before_ including HIDAPI subdirectory. | ||
HIDAPI uses [GNUInstallDirs](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) to specify install locations. Variables like `CMAKE_INSTALL_LIBDIR` can be used to control HIDAPI's installation locations. E.g.: | ||
```cmake | ||
# enable the installation if you need it | ||
set(HIDAPI_INSTALL_TARGETS ON) | ||
# (optionally) change default installation locations if it makes sense for your target platform, etc. | ||
set(CMAKE_INSTALL_LIBDIR "lib64") | ||
add_subdirectory(hidapi) | ||
``` | ||
- HIDAPI prints its version during the configuration when built as a standalone package; to enable this for subdirectory builds - set `HIDAPI_PRINT_VERSION` to TRUE before including HIDAPI; | ||
|
||
Available CMake targets after `add_subdirectory(hidapi)` _are the same as in case of [standalone build](#standalone-package-build)_, and a few additional ones: | ||
- `hidapi_include` - the interface library; `hidapi::hidapi` is an alias of it; | ||
- `hidapi_winapi` - library target on Windows; `hidapi::winapi` is an alias of it; | ||
- `hidapi_darwin` - library target on macOS; `hidapi::darwin` is an alias of it; | ||
- `hidapi_libusb` - library target for libusb backend; `hidapi::libusb` is an alias of it; | ||
- `hidapi_hidraw` - library target for hidraw backend; `hidapi::hidraw` is an alias of it; | ||
- `hidapi-libusb` - an alias of `hidapi_libusb` for compatibility with raw library name; | ||
- `hidapi-hidraw` - an alias of `hidapi_hidraw` for compatibility with raw library name; | ||
- `hidapi` - an alias of `hidapi_winapi` or `hidapi_darwin` on Windows or macOS respectfully. | ||
|
||
Advanced: | ||
- Why would I need additional targets described in this section above, if I already have alias targets compatible with `find_package`? | ||
- an example: | ||
```cmake | ||
add_subdirectory(hidapi) | ||
if(TARGET hidapi_libusb) | ||
# see libusb/hid.c for usage of `NO_ICONV` | ||
target_compile_definitions(hidapi_libusb PRIVATE NO_ICONV) | ||
endif() | ||
``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use GitHub Actions' matrix feature to avoid having separate jobs for each OS. For example: https://github.com/Be-ing/portaudio/blob/8bcdc661ce518f6faa778b86ae12fd36b7f1c442/.github/workflows/c-cpp.yml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, I'll look into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, does the matrix variances run in parallel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup! And GitHub Actions is very generous with computing resources. You get 20 concurrent jobs for free (max 5 macOS jobs).