ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

使用 CMake 构建与集成 HIDAPI:从独立编译到宿主项目嵌入的完整指南

使用 CMake 构建与集成 HIDAPI:从独立编译到宿主项目嵌入的完整指南 使用 CMake 构建与集成 HIDAPI从独立编译到宿主项目嵌入的完整指南【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio本篇技术指南以 HIDAPI 官方 CMake 构建文档lib/hidapi/BUILD.cmake.md为主体系统讲解如何用 CMake 将 HIDAPI 构建为独立库、如何通过find_package或add_subdirectory两种方式把它集成进宿主项目并逐一拆解所有标准与 HIDAPI 专用 CMake 变量。HIDAPI 是跨平台Windows / Linux / FreeBSD / macOS的 HID 设备访问库本仓库Serial Studio的 Pro 版本正是通过 CMake 子目录方式静态集成 HIDAPI 来实现 HID 数据源驱动见 lib/CMakeLists.txt 与 app/CMakeLists.txt。读完本文你将掌握从零配置、编译、安装到在自有 CMake 工程中正确链接 HIDAPI 的完整实战方案。HIDAPI 的 CMake 构建方式总览HIDAPI 的 CMake 构建系统支持两种截然不同的使用模式独立包构建Standalone Package Build把 HIDAPI 当作一个独立项目自己配置、编译、安装到系统或任意前缀目录随后通过find_package(hidapi)供其它工程使用宿主项目子目录HIDAPI as a Subdirectory通过add_subdirectory(hidapi)把 HIDAPI 的源码直接纳入更大 CMake 工程的构建树所有目标target即时可用无需安装。TL;DR如果你已是 CMake 老手本文大部分内容可略读——直接对照文末的变量名、默认值与目标target名称表格即可上手。完整变量清单也可借助cmake-gui图形界面直观查看详见下文“使用 cmake-gui 查看变量”一节。在开始之前请先确认已满足构建前置条件lib/hidapi/BUILD.mdLinuxhidraw后端需要libudev开发包libusb后端需要libusb开发包# 仅 hidraw 后端需要 sudo apt install libudev-dev # 仅 libusb 后端需要 sudo apt install libusb-1.0-0-devFreeBSD需要libiconvpkg_add -r libiconvmacOS需要安装 Xcode 及其 Command Line ToolsWindows只需可用的编译器Visual Studio 或 Cygwin/MinGW 皆可。安装 CMakeCMake 可通过系统包管理器安装也可从官方站点下载安装包/预编译版本大多数 *nix 系统推荐用包管理器例如sudo apt install cmakeWindows 上可由开发环境自带如 Visual Studio Installer 或 MinGW installer也可使用官方系统级安装包macOS 上可通过 Homebrew / MacPorts 或官方安装包安装。独立包构建Standalone Package Build独立构建 HIDAPI 与构建任何 CMake 项目的通用流程一致配置 → 编译 → 安装# 前置在文件系统某处创建 build dir建议放在 HIDAPI 源码目录之外 # 所有中间产物/构建文件都会生成在这里 cd build dir # 配置构建 cmake HIDAPI source dir # 编译 cmake --build . # 安装库默认安装到 /usr/local/ cmake --build . --target install # 注意安装到 /usr/local/ 需要 root 权限上述调用会使用系统默认的编译器/构建环境。你也可以通过-DCMake Variablevalue方式传入额外变量控制构建配置例如# 安装命令将把库安装到 /usr cmake HIDAPI source dir -DCMAKE_INSTALL_PREFIX/usr使用特定的 CMake 生成器以 Ninja 为例cd build dir # 配置构建指定 Ninja 作为生成器 cmake -GNinja HIDAPI source dir # 既然 CMake 已生成 Ninja 构建文件可以直接用 ninja 代替 cmake --build . ninja # 安装库 ninja install这里的-G指定 CMake 为其生成原生构建系统的生成器类型可用生成器列表因平台而异详见 CMake 官方生成器文档。常用标准 CMake 变量变量作用HIDAPI 默认值CMAKE_INSTALL_PREFIXinstall目标安装库的前缀目录平台默认通常为/usr/localCMAKE_BUILD_TYPE构建类型Debug、Release、RelWithDebInfo、MinSizeRel未指定时为ReleaseBUILD_SHARED_LIBS置为TRUE时构建共享库否则静态构建未指定时为TRUEmacOS 专用变量变量作用HIDAPI 默认值CMAKE_FRAMEWORK置为TRUE时构建为 framework 库否则构建常规静态/共享库自 CMake 3.15 起FALSECMAKE_OSX_DEPLOYMENT_TARGET目标二进制可部署的最低平台版本如 macOS/iOS当前 Xcode/工具链支持的最高目标平台上述默认值可在 lib/hidapi/CMakeLists.txt 中得到印证当CMAKE_BUILD_TYPE未定义时被强制设置为Release第 22-24 行BUILD_SHARED_LIBS默认ON第 47 行。HIDAPI 专用 CMake 变量变量作用默认值HIDAPI_BUILD_HIDTEST置为TRUE时构建小型测试程序hidtest独立构建下默认OFFDebug 构建为ONHIDAPI_WITH_TESTS置为TRUE时构建全部单元测试目前仅在 Windows 可用因为只有 Windows 后端有测试OFFWindows Debug 构建为ONLinux 专用变量变量作用默认值HIDAPI_WITH_HIDRAW置为TRUE时构建基于 HIDRAW 的实现hidapi-hidrawTRUEHIDAPI_WITH_LIBUSB置为TRUE时构建基于 LIBUSB 的实现hidapi-libusbTRUE注意HIDAPI_WITH_HIDRAW与HIDAPI_WITH_LIBUSB至少有一个必须为TRUE否则配置阶段会直接报错。这一点在 lib/hidapi/src/CMakeLists.txt 中有硬性校验当两个后端都未构建且不存在hidapi_hidraw目标时抛出FATAL_ERROR。使用 cmake-gui 查看变量查看 HIDAPI 全部常用 CMake 变量的最便捷方式之一是使用cmake-gui工具。独立构建模式下大量标准变量与 HIDAPI 专用变量会被标记为cache 变量或 option在图形界面中会高亮显示并附带简短说明可直接修改cmake-gui 中高亮显示的 HIDAPI 与标准 CMake 变量例如CMAKE_BUILD_TYPE会以标准构建类型的下拉菜单形式呈现默认指向Releasecmake-gui 中 CMAKE_BUILD_TYPE 的下拉菜单备注由 CMake 构建的 HIDAPI 包同样可以配合pkg-config使用与用 Autotoolslib/hidapi/BUILD.autotools.md构建的效果一致。从 lib/hidapi/src/CMakeLists.txt 的hidapi_configure_pc函数第 51-73 行可以看到构建系统会为每个后端生成.pc文件并安装到${CMAKE_INSTALL_LIBDIR}/pkgconfig/目录。使用 MSVC 与 Ninja 组合构建用 MSVC 编译器配合 Ninja 生成器构建 CMake 项目包括 HIDAPI完全可行——对中型以上项目而言其速度远超 msbuild。步骤打开cmd.exe设置 MSVC 构建环境变量例如vcvarsall.bat x64其中vcvarsall.bat是 MSVC 工具链安装目录下的环境配置脚本以 MSVC 2019 Community 版为例其位置为C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\x64指定要构建的目标架构按常规构建步骤执行并使用Ninja作为生成器。在 CMake 工程中使用 HIDAPIfind_package 方式当 HIDAPI 以独立包形式安装到系统或手动构建并安装到其他目录后最简单的使用方式如下project(my_application) add_executable(my_application main.c) find_package(hidapi REQUIRED) target_link_libraries(my_application PRIVATE hidapi::hidapi)如果 HIDAPI 未安装在系统默认位置、或find_package因其他原因找不到它推荐通过hidapi_ROOTCMake 变量手动指定使用的 HIDAPI 包例如-Dhidapi_ROOTpath to HIDAPI installation prefix注意hidapi_ROOT仅在 CMake3.12 及以上版本可用也更推荐使用更老的版本需改用CMAKE_PREFIX_PATH指定前缀路径。find_package 后可用目标目标名说明hidapi::hidapi大多数情况下的首选目标hidapi::include只需包含hidapi.h头文件而不链接库时使用hidapi::winapi仅 Windows 可用等价于 Windows 上的hidapi::hidapihidapi::darwin仅 macOS 可用等价于 macOS 上的hidapi::hidapihidapi::libusb使用 libusb 后端时可用hidapi::hidrawLinux 上使用 hidraw 后端时可用Linux 后端选择的关键细节在 Linux 上hidapi::libusb与hidapi::hidraw两个后端常常同时可用此时hidapi::hidapi是hidapi::hidraw的别名。原因是 hidraw 后端是 Linux 内核原生的 HID 协议实现支持各类 HID 设备USB、蓝牙、I2C 等。若 hidraw 后端完全未构建hidapi::libusb是唯一目标则hidapi::hidapi退化为hidapi::libusb的别名。如果你的应用是跨平台的且确定在 Linux 上必须使用 libusb 后端一个稳妥的写法是if(TARGET hidapi::libusb) target_link_libraries(my_project PRIVATE hidapi::libusb) else() target_link_libraries(my_project PRIVATE hidapi::hidapi) endif()将 HIDAPI 作为子目录集成HIDAPI 可以非常容易地作为更大 CMake 工程的子目录使用# 根 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) # 注意无需 find_package因为 HIDAPI 目标已属于当前工程树 target_link_libraries(my_application PRIVATE hidapi::hidapi)我们把这种“更大的工程”称为宿主工程host project。独立构建一节中描述的全部变量都可以用于控制子目录模式下 HIDAPI 的构建例如set(HIDAPI_WITH_LIBUSB FALSE) # 仅 Linux 上生效 set(BUILD_SHARED_LIBS FALSE) # 在所有平台上静态构建 HIDAPI add_subdirectory(hidapi)注意如果你的工程在全局把BUILD_SHARED_LIBS作为CACHE变量使用那么如上以普通变量方式设置它在CMake 3.13 之前不会生效。详情参见 CMake 的 CMP0077 策略。子目录模式与独立构建的行为差异变量可见性不同。独立构建中大量标准变量与 HIDAPI 专用变量被标记为cache 变量或option方便cmake-gui高亮展示与修改而作为子目录构建时HIDAPI不会将任何变量标记为 cache 或 option——把决定权完全交给宿主工程开发者。默认行为不同默认情况下子目录模式下不安装任何 HIDAPI 目标如需要宿主工程可在包含 HIDAPI 子目录之后自行安装需 CMake 3.13或者在包含子目录之前设置HIDAPI_INSTALL_TARGETS变量以启用默认安装。安装位置遵循 GNUInstallDirs 规范可通过CMAKE_INSTALL_LIBDIR等变量控制# 按需启用安装 set(HIDAPI_INSTALL_TARGETS ON) # 可选按目标平台调整默认安装位置 set(CMAKE_INSTALL_LIBDIR lib64) add_subdirectory(hidapi)HIDAPI 在独立构建配置时会打印其版本号子目录模式下如需打印需在包含 HIDAPI 之前将HIDAPI_PRINT_VERSION置为TRUE。变量不被篡改。子目录构建中HIDAPI 不会修改或设置任何可能改变构建行为的 CMake 变量。例如独立构建中若未设置CMAKE_BUILD_TYPE或BUILD_SHARED_LIBS会被显式默认化为Release与TRUE而子目录构建中即使未设置这些变量也保持原样完全由宿主工程掌控。子目录模式下的目标清单add_subdirectory(hidapi)后可用的目标与独立构建一致另附几个额外目标目标名说明hidapi_include接口库hidapi::hidapi是其别名hidapi_winapiWindows 上的库目标hidapi::winapi是其别名hidapi_darwinmacOS 上的库目标hidapi::darwin是其别名hidapi_libusblibusb 后端的库目标hidapi::libusb是其别名hidapi_hidrawhidraw 后端的库目标hidapi::hidraw是其别名hidapi-libusbhidapi_libusb的别名兼容原始库名hidapi-hidrawhidapi_hidraw的别名兼容原始库名hidapiWindows/macOS 上分别对应hidapi_winapi/hidapi_darwin的别名进阶用法示例既然已有与find_package兼容的别名目标为何还需要上述额外目标一个典型场景是需要在编译期对具体后端目标附加自定义定义add_subdirectory(hidapi) if(TARGET hidapi_libusb) # 参见 libusb/hid.c 中 NO_ICONV 的用法 target_compile_definitions(hidapi_libusb PRIVATE NO_ICONV) endif()从源码结构看上述目标在 lib/hidapi/src/CMakeLists.txt 中按平台/后端分支创建Windows 分支添加windows子目录并设置EXPORT_ALIAS为winapimacOS 分支添加mac子目录并设置darwinLinux 分支则按HIDAPI_WITH_HIDRAW/HIDAPI_WITH_LIBUSB分别添加linux/libusb子目录最后统一以hidapi::hidapi别名指向实际后端目标第 169 行。同时构建静态与动态库如果你曾是或现在是Autotools 构建脚本的用户或者你常以包管理器维护者身份工作可能会问如何用 CMake 同时构建 HIDAPI 的静态库与共享库就像 Autotools 的./configure --enable-static --enable-shared ...CMake 本身不提供这种开箱即用的选项而 HIDAPI 也决定不为此引入任何手工的 CMake 级变通方案。若要模拟 Autotools 行为可行的做法是先构建并安装静态版本再构建并安装共享版本。两个变体的CMAKE_INSTALL_PREFIX必须指向同一目录这样静态库与共享库二进制同时可用两者共用同一套头文件生成可用的 Autotools/pkg-config.pc文件效果如同由 Autotools 原生生成并配置了--enable-static --enable-sharedCMake 包脚本也会完整生成但只有最后一次安装的构建被记录——即若最后安装的是共享版本find_package(hidapi)找到的 CMake 目标将指向共享二进制。这一方案的历史讨论可参考 libusb/hidapi 仓库的 issue #424。TL;DR / 完整示例# 第一步配置与构建 # 静态库 cmake -S HIDAPI source dir -B build dir/static -DCMAKE_INSTALL_PREFIXyour installation prefix -DBUILD_SHARED_LIBSFALSE cmake --build build dir/static # 共享库 cmake -S HIDAPI source dir -B build dir/shared -DCMAKE_INSTALL_PREFIXyour installation prefix -DBUILD_SHARED_LIBSTRUE cmake --build build dir/shared # 可选更改安装目标目录。 # 注意1CMake 仅在 UNIX 平台上支持该环境变量DESTDIR # 注意2这与上面设置的 CMAKE_INSTALL_PREFIX 不是一回事 # 注意3仅当存在与最终运行目录不同的暂存目录时才需要 # 例如交叉编译场景 export DESTDIR$STAGING_DIR # # 安装库 # 注意安装顺序很重要——Shared 变体必须最后安装 # 静态库 cmake --install build dir/static # 共享库 cmake --install build dir/shared实战Serial Studio 如何将 HIDAPI 嵌入宿主工程以本仓库Serial Studio为例可以看到“子目录集成”模式的真实落地。在 lib/CMakeLists.txt 的“hidapi (Pro edition only)”一节第 503-539 行中Serial Studio 在BUILD_COMMERCIAL商业版配置下将捆绑的 HIDAPI 作为子目录加入构建树if(BUILD_COMMERCIAL) set(HIDAPI_BUILD_HIDTEST OFF CACHE BOOL FORCE) set(HIDAPI_WITH_TESTS OFF CACHE BOOL FORCE) set(HIDAPI_INSTALL_TARGETS OFF CACHE BOOL FORCE) set(HIDAPI_PRINT_VERSION OFF CACHE BOOL FORCE) set(HIDAPI_WITH_LIBUSB OFF CACHE BOOL FORCE) set(HIDAPI_WITH_HIDRAW ON CACHE BOOL FORCE) set(BUILD_SHARED_LIBS OFF CACHE BOOL FORCE) add_subdirectory(hidapi) ... endif()几点值得注意的实践仅启用hidraw后端HIDAPI_WITH_LIBUSBOFF注释明确说明这是为了避免与构建中已有的usb-1.0Raw USB 驱动产生符号冲突静态链接BUILD_SHARED_LIBSOFF且关闭测试/示例/安装/版本打印保持依赖最小化与子目录模式“变量由宿主工程全权控制”的设计完全一致随后在 app/CMakeLists.txt 中商业版可执行文件通过target_link_libraries(${PROJECT_EXECUTABLE} PUBLIC hidapi::hidapi)直接链接该目标上层驱动 core/Devices/IO/Drivers/HID.h 通过#include hidapi.h使用 HIDAPI 的 C API封装了设备枚举hid_enumerate、打开hid_open_path、读写等操作为 Serial Studio 提供 HID 数据源支持。这套集成方式与本文介绍的add_subdirectory流程一一对应宿主工程在add_subdirectory前通过 cache 变量锁定后端选择与构建形态随后直接以hidapi::hidapi别名目标链接无需任何find_package。小结独立构建适合需要把 HIDAPI 安装到系统、供多个工程共享配合find_packagehidapi::hidapi的场景子目录集成适合希望完全掌控构建配置、随宿主工程一同编译的嵌入场景。Linux 上默认同时构建hidraw与libusb两个后端hidapi::hidapi默认指向hidraw至少保留一个后端是硬性约束。同时产出静态与共享库需分两次构建、两次安装且共享版本最后安装。宿主工程开发者应优先通过HIDAPI_WITH_HIDRAW/HIDAPI_WITH_LIBUSB/BUILD_SHARED_LIBS/HIDAPI_INSTALL_TARGETS等变量在add_subdirectory之前锁定 HIDAPI 的构建形态——Serial Studio 的集成方式即是一个可复用的范本。【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表