Skip to content

Conversation

@a-michelis
Copy link
Contributor

This pull request modifies the necessary sections of CMake to export LIBUSB Targets, allowing it to operate better with fetchContent on targets that use target exporting.

Additionally, GNUInstallDirs is now used to provide better heurestics on the correct installation directories, and the right (shared) library installation directory is selected, based on whether the project is built using MSVC (so, windows) or not.

@mcuee mcuee added the enhancement New feature or request label Jul 25, 2025
@Youw
Copy link
Member

Youw commented Jul 27, 2025

allowing it to operate better with fetchContent

Can you elaborate? I didn't have any issues with libusb-cmake and FetchContent so far

@a-michelis
Copy link
Contributor Author

a-michelis commented Jul 27, 2025

Sure, i'l start with the context that helped me discover the "issue" and then elaborate on the enhancement:

I'm currently trying to reform the st-link open source toolset into a c++ library. originally, this project relies on libusb-1.0, but the approach back then was "let's download the pre-compiled library for windows, while only supporting mingw builds". By researching libusb project, I noticed this repo which was god-sent for windows builds (the project maintainers preffered the default libusb providers for *NIX OSes, so this applies only for MSVC/Windows). Using this repo when building for MSVC made things way more streamlined, so I provided a PR that uses the it with fechContent. This worked perfectly and the PR got merged, because the target doesn't use EXPORT option of install cmake command.

On my C++ Implementation, i leverage EXPORT option, since I plan to provide stlink target as a standalone Library, in addition to its internal use by the toolset. This is where I stumbled upon an issue where CMake would give me an error: Target could not be exported, because the dependency usb-1.0 does not use target export.

The approach in this PR allows libusb to be used the same as before, while enabling 3rd party projects to:

  • Reliably discover the installed libusb-1.0. with default cmake mechanisms (find_package)
  • Use the EXPORT option on 3rd-party targets which depend on libusb-1.0 that has been included usingfetchContent.

As for the GNUInstallDirs this is simply syntactic sugar to avoid future headaches with default export paths (ie: many OSes uses lib64instead of lib)

@Youw
Copy link
Member

Youw commented Jul 27, 2025

Thanks for clarification.

Now I get why you might need to introduce the EXPORT part (even though I think it is totally unrelated to the FetchContent specifically).

Just to clarify: does you c++ implementation uses libusb-1.0 as a public dependency? I.e. does your API uses some parts of libusb API as its own / addition?

As for the GNUInstallDirs this is simply syntactic sugar to avoid future headaches with default export paths

Hm... The thing is:
https://cmake.org/cmake/help/v3.14/command/install.html - at least since CMake 3.14:

For regular executables, static libraries and shared libraries, the DESTINATION argument is not required. For these target types, when DESTINATION is omitted, a default destination will be taken from the appropriate variable from GNUInstallDirs...

We should be just fine with only: install(TARGETS usb-1.0)

@a-michelis
Copy link
Contributor Author

a-michelis commented Jul 27, 2025

does you c++ implementation uses libusb-1.0 as a public dependency? I.e. does your API uses some parts of libusb API as its own / addition?

No, that's not the case!
Targets export is a way to inform CMake how to properly link to a library, during its usage in future projects. Judging by the given error (and the fact that my link to libusb was strictly private), this information includes -amongst other things- what additional dependencies must be provided by the host system for a library to be properly used.

So, if i build myLib with (private) dependency pm libusb, libusb should still be somehow provided by the host, and CMake wants to have that information to properly request the dependencies, when i use myLib on any other projects via CMake.


We should be just fine with only: install(TARGETS usb-1.0)

If GNUInstallDirs was our concern here, I'd totally say yes! But we also need EXPORT this time around. I haven't ever tried not defining DESTINATION -i can try it and, if it works, I can simply roll-back the GNUInstallDirs inclusion and DESTINATION tags to reduce overall changes.

@Youw
Copy link
Member

Youw commented Jul 28, 2025

Do you intend to build your library as a static library or a shared library (or both depending on an option)?

@a-michelis
Copy link
Contributor Author

Do you intend to build your library as a static library or a shared library (or both depending on an option)?

I intend to build my library as a shared library (and use libusb shared library as well). I suspect the issue here is not linker-related, tho. but more of a cmake quirk. I can post some screenshots of the error here, when i go back to my computer.

@Youw
Copy link
Member

Youw commented Jul 28, 2025

Not necessary, I totally get the issue.
First of all - the changes that you suggest totally make sense in some scenarios, especially in cases when the library that uses libusb is built as a static library, so its users on CMake level needs to know of all dependencies, like libusb.
Once this is cleaned up and tested/checked, we will have it merged.

As for your particular case, it should be enough to have libusb as a build-only dependency, e.g.: target_link_library(MyProject PRIVATE $<BUILD_INTERFACE:usb-1.0>)

@a-michelis
Copy link
Contributor Author

As for your particular case, it should be enough to have libusb as a build-only dependency, e.g.: target_link_library(MyProject PRIVATE $<BUILD_INTERFACE:usb-1.0>)

This was an eye-opener -i thought build interface must go hand-in-hand with install interface. Just tried it and it worked for me!

Other than that, I'm glad this PR is helpfull to the project. If you need me to update parts of it, I'm happy to revisit them.

@Youw
Copy link
Member

Youw commented Jul 29, 2025

My comments still stands - try to remove all explicit changes related to GNUInstallDirs, and lets let CMake handle it

Copy link
Member

@Youw Youw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently we do need to include GNUInstallDirs explicitly, to initialize corresponding CMake variables - that's fine I guess.

I don't believe this is complete - there still has to be libusb-config.cmake generated, but that is to be done separately, since I don't have enough time to do it myself right now.

@Youw Youw merged commit 0c424f7 into libusb:main Oct 19, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants