-
Notifications
You must be signed in to change notification settings - Fork 260
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
CMake: Search for dependencies in FluidSynthConfig.cmake #1211
CMake: Search for dependencies in FluidSynthConfig.cmake #1211
Conversation
@pedrolcl FYI |
@@ -1,10 +1,108 @@ | |||
# for the find_dependency() macro: | |||
# include(CMakeFindDependencyMacro) |
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.
This CMake module is where the find_dependency() macro is defined. See:
https://cmake.org/cmake/help/latest/module/CMakeFindDependencyMacro.html
Also:
find_dependency forwards the correct parameters for QUIET and REQUIRED which were passed to the original find_package()
Thank you for the feedback! Now that the |
I don't think so. On the other hand, there is nothing similar to |
Thank you for clarifying! Should the
In both cases CMake would fail but with different messages:
What do you think ? |
Thanks for the heads up, Tom. Maybe also @rncbc could be interested. It is my fault that this issue was left behind. I've felt (and I still feel the same) that there is no clean solution for the libfluidsynth static library use case. The main reason for exporting targets was to enable downstream projects to use On the other hand, when using |
I hear you, on Windows specifically where having Unfortunately, the canonical way to avoid using For this to work, every dependency of FluidSynth would need to export their own CMake config which should track their own dependency or have a Find module so the library can be found through a Another option would be to list out the libraries in While I agree that the proposed solution is not perfect by far, it would at least provide parity between using |
Exactly. Let's do it.
For instance, libsndfile 1.2 is almost ready |
Okay, I've been working on it for the past few days and I am quite happy with the results. Here is some insight with how I implemented it: Firstly, for the "easy" ones, ALSA, DBUS, oboe, PulseAudio, and SDL2 did not need any custom find modules. ALSA, similarly to Threads, has a module that ships with CMake. As for the others, they have had an upstream config shipped for a while. Secondly, there were libraries that have an official CMake config sometimes. Libraries such as sndfile and its dependencies do ship CMake configs, but only when built with CMake. The issue is that not every package manager does, most notably on macOS Homebrew builds most of them with autotools, which results in no config installed. For such libraries, their Find module creates the same variables and targets to be as compatible as possible with upstream. Lastly, there were libraries that export no CMake config whatsoever, most notably GLib2, old libraries such as LASH or MidiShare, or even libinstpatch (which uses CMake as a build system). For such libraries, I had to make a find module from scratch. One thing I should mention, you may notice that in many Find modules, pkg-config is still used. But its use is fully optional! When available, it provides a lot of valuable information that is not necessarily accessible, such as the version of the package and its dependencies. If it is not available, then the modules try to work off what the library headers may expose. Similarly, I made sure the provided Find modules are fully interchangeable with the upstream CMake config files. If a developer or a consumer sets Testing played a big part in ensuring things were worked as intended. So here were the tests that were successfully conducted:
What I was not able to test:
I know this is suddenly a much bigger PR, but as it stands, this makes the project now able to be configured and consumed without pkg-config, yet still benefit from it if it is available! Let me know if you have any question regarding the implementation and if you need any change! |
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.
Ok, wow. Much bigger than expected. So I see a few new things here:
- Some dependency libraries now require newer versions
- The dependencies now have to be tracked in two different places (
CMakeLists.txt
andFluidSynthConfig.cmake.in
)
I'm fine with 1. in general, I'm just asking myself whether it's fine to release this change with the next bugfix release (2.3.2) or if we better wait until next minor bump (2.4.0).
Regarding 2.: Would it make sense to store the versions of the dependencies in separate variables, so that we can get rid of keeping them in sync at two different places? I mean, the FluidSynthConfig.cmake.in
is sourced anyway, so it should be possible to e.g. set( GLIB_VERSION 2.6.5)
in CMakeLists.txt
which is then expanded in FluidSynthConfig.cmake.in
to the desired version. Instead of defining a sparate variable, we could also think about directly consuming the version variable set by the find modules, so in this case GLib2_VERSION
.
Additionally, I'd like to ask you for two more things:
- Pls. merge the recent master into your changes (I've just fixed the Android CI pipeline, and Carlo has made some CYGWIN specific cmake changes).
- And pls., put a small README into the
cmake_admin/
folder that briefly explains why all these Find modules suddenly exist now. (This is just for some future contributors to explain, why the previous dependency handling with pkg_config has been replaced with custom cmake find modules.)
I'm leaving the technical review to @pedrolcl :)
EDIT: Oh, and if there is any simple test case that you or Pedro could think of, you're welcome to add it to one of the CI pipelines as well.
This fixes errors when linking `FluidSynth::libfluidsynth-OBJ` as the targets listed in `INTERFACE_LINK_LIBRARIES` must be available for the consumer.
Only targets need to be imported.
CMake will not fail on Windows, instead the target `Threads::Threads` is a no-op. Similarly, we want a `MATH_LIBRARY` for future Find modules.
This avoids requiring pkg-config to find dependencies.
mpghip is not always built, and not necessary for sndfile.
The wrong variable was passed to find_package_handle_standard_args.
Starting 1.1.1, the suffix ends in `-2`, while on 1.1.0, the directory ends in `-1`. Since we allow 1.1.0, check for both.
Commit da7e0d1 changed `WITH_READLINE` to `READLINE_SUPPORT`, but the generated config.h did not reflect this change.
This PR is not yet ready for production. I could not test many scenarios, but some of my tests have been unsuccessful. I've made my tests on a Fedora 37 box, using a patched
I've not tried the next level: installing libfluidsynth at the $HOME directory, and trying to build a test project using similar scenarios: using In short: even when the upstream projects seem to provide cmake exported targets, they may be broken. And writing custom FindXXXX cmake modules is more difficult than it seems. |
This lets the version be defined once and without risking the config and CMakeLists to be out of sync.
Detail the use of find modules in place of `pkg_check_modules`.
- CI versions of libsndfile and libsdl2 are too old for the new version. - Manually check version for SDL and use SDL2_LIBRARIES. Prior to 2.0.12, the version and targets were not exported. - LASH's latest version is 0.5.0, not 5.0.
This is needed to consume the project from the build directory when building statically.
Use a simple CMake project to test a call to find_package on the build directory and the installed location.
- Fix clang-tidy detection. Only `clang-tidy` installs the unversioned executable. - Fix installed packages: - ladspa was requested in CMake but not installed. - libglib2.0-dev should be insalled instead of the runtime. - Use Ninja to build. Makefiles were systematically failing. - Set bash as the default for all steps.
Not doing so breaks libsndfile's upstream config.
This new function gets the appropriate linker flags for a library depending on whether it is static or not.
- Only vcpkg patches pc files in static builds to make all private dependencies public. So we take the link based on the library type. - The `_LDFLAGS` are taken specifically as using `_LIBRARIES` may fail when the library is installed in a non-standard prefix, even when `INTERFACE_LINK_DIRECTORIES` is set.
2f7085a
to
51937c2
Compare
Thank you everyone for your feedback!
I went with the option of setting On the topic of version, I reverted the changes of minimum version for SDL2 and libsndfile as the Linux CI does not have a recent enough version for each.
Rebased this branch on
I updated the README.cmake.md at the top of the file tree so it no longer uses
I added a test case under In aef4eb9, I also updated the rest of that workflow. There were issues with the installed packages (e.g. ladspa was enabled but not installed,
Thank you for pointing this out, I was able to reproduce your issues and partially come up with solutions. Firstly, there was an issue with Findmp3lame introduced in 9214277. In theory, The second and third issues are somewhat tied. With the static-only build of libsndfile living outside of standard compiler search paths, when using the find module instead of the config file, linking the fluidsynth executable would fail with the message It appears that the My idea to solve these two issues was to use either the I did notice that linking |
It seems like Pedro was the last one who changed it to private linkage. However, the CMake docs suggest public linkage. Bumping CMake minimum version to 3.12 seems to be required as well. I would be fine with that. |
Do you mean in commit 21aca08 ? It was already private before. But yes, I believe that changing the linkage to For instance, this is what we get on the shared library when using
If now we change it to:
|
This prevents our find modules to "leak" into other projects.
This policy fixes issues in static builds when a dependency pulled from pkg-config has a dependency outside of default compiler search paths.
This replaces the `get_linker_flags_from_pkg_config` function with the `get_target_properties_from_pkg_config` function. Using raw LDFLAGS was not compatible with MSVC.
It appears that this issue is not related to the indirection from using Because of that, if:
Linking an executable against As an alternative, I attempted making and linking against an imported target. Through adding The only solution I found that fixed the issues is the if(POLICY CMP0099)
cmake_policy(SET CMP0099 NEW)
elseif(NOT BUILD_SHARED_LIBS)
message(WARNING "Your version of CMake is very old. This may cause linking issues if your dependencies are not in your compiler's default search paths.")
endif() For reference, Debian stable (bullseye) ships CMake 3.18, and this version is also available on oldstable (buster) through backports. |
Great finding, thanks! We are almost there. One very special MacOS build has failed: I just made a quick diff of the longish call to whereas they are now missing, however we got a new rpath: |
That failure seems to be related to the selection of libraries for that build, below that long command there are the following statements:
I assume the universal libraries are located in
I will try including EDIT: While this worked, it seems to be preferable to use
|
This should help CMake to select libraries with the correct architecture
This should fix the macOS universal CI.
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
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.
Ok, I'd would be fine with this change. Thanks! @pedrolcl What about you?
I agree. Let's go ahead. |
This PR addresses the issue of consuming FluidSynth through CMake.
Existing Issue
When linking against a static
FluidSynth::libfluidsynth
, CMake returns the following error:If fixed manually through a
find_package
call, the error repeats itself forPkgConfig::GLIB
and every other CMake target listed in theINTERFACE_LINK_LIBRARIES
of theFluidSynth::libfluidsynth-OBJ
target.Proposed Solution
This PR addresses this issue by searching for the dependencies in the generated
FluidSynthConfig.cmake
.Firstly, we save optional dependencies in
FLUIDSYNTH_<lib>_SUPPORT
variables using the<lib>_SUPPORT
variables from the configure step.Then, for every dependency we need, we call
pkg_check_modules
orfind_dependency
(in place offind_package
) with the same arguments as the mainCMakeLists
.Additionally, we now need to install the custom
Find<lib>.cmake
modules along the CMake config.Any feedback is appreciated!