I have committed both of your suggestions (hopefully correctly). Thanks!

Thanks, I just tested this and it works correctly when building directly against liblzma via CMake, both with config and module mode.

I noticed however, that there is still an issue when building against a library that was built against liblzma due to using ALIAS (e.g., testproject -> LibXml2 -> LibLZMA): CMake will resolve the alias to include "liblzma::liblzma" instead of "LibLZMA::LibLZMA" in the LibXml2 link dependencies. When another library does not set CMAKE_FIND_PACKAGE_PREFER_CONFIG, it will however still use FindLibLZMA and is then not able to resolve the "liblzma::liblzma" dependency.

With the following alternative (that is also used in the CMake exported target files), LibXml2 will continue to use "LibLZMA::LibLZMA" in its dependencies when linking against this target:
add_library(LibLZMA::LibLZMA INTERFACE IMPORTED)
set_target_properties(LibLZMA::LibLZMA PROPERTIES INTERFACE_LINK_LIBRARIES liblzma::liblzma)

   - FindLibLZMA doesn't #define LZMA_API_STATIC when building against
     static liblzma. LZMA_API_STATIC omits __declspec(dllimport) from
     liblzma function declarations on Windows.

The FindLibLZMA module cannot easily determine if a detected library was built as shared or static library (there is an open issue for this [1]) without looking at header or config files. autotools seems to build both at the same time and FindLibLZMA will link the shared version if it is available.

CMake builds either static or shared via BUILD_SHARED_LIBS, but includes the correct compiler definition in the exported target.

   - FindLibLZMA sets a few CMake cache variables that the config file
     doesn't, for example, LIBLZMA_HAS_EASY_ENCODER. I have no idea if
     there are packages that care about this.

This seems to be due to the autotools options for enabling/disabling certain encoders and decoders. If there is no equivalent CMake option for modifying this you could add variables to the config files that are always set to ON:
set(LIBLZMA_HAS_AUTO_DECODER ON)
set(LIBLZMA_HAS_EASY_ENCODER ON)
set(LIBLZMA_HAS_LZMA_PRESET ON)

The entries for LIBLZMA_VERSION_MAJOR etc. can also be easily added to the file:
set(LIBLZMA_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(LIBLZMA_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(LIBLZMA_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(LIBLZMA_VERSION_STRING \"${PROJECT_VERSION}\")

   - The config file has find_dependency(Threads) while FindLibLZMA
     doesn't. This can affect the linker flags.

Other find modules have similar issues. FindLibXml2 for instance also does not link against dependencies such as Iconv or LibLZMA. For link-only dependencies this issue only shows up in static builds. The config file should still include the correct dependencies.

Perhaps there are other details affecting compatiblity. I just wonder
how big mistake it was to use liblzma::liblzma in the config file. I
guess it's too late to change it now.

By using the same principle as above, you should still be able to change this if you prefer. In that case, liblzma::liblzma can be an alias for LibLZMA::LibLZMA in the config file. I think the CMake build files also were not yet included in any official release.

You can add an alias for target "liblzma" to target "LibLZMA" in the CMakeLists.txt file (after the target definition in add_library, line 193) for users that embed the xz project as a subdirectory:
add_library(LibLZMA::LibLZMA ALIAS LibLZMA)
add_library(liblzma ALIAS LibLZMA::LibLZMA)
add_library(liblzma::liblzma ALIAS LibLZMA::LibLZMA)

With CMake >3.17, you can further set a deprecation message for the old target name (works only on INTERFACE IMPORTED, not on ALIAS):
if(NOT CMAKE_VERSION VERSION_LESS 3.17)
set_property(TARGET liblzma::liblzma PROPERTY DEPRECATION "Deprecated target. Please use LibLZMA::LibLZMA instead.")
endif()

Best regards,

Markus Rickert

[1] https://gitlab.kitware.com/cmake/cmake/-/issues/18564

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to