Closed hhassoubi closed 3 weeks ago
The cmake rules already set CMAKE_PREFIX_PATH
for any CMake based dependencies; its quite possible that this logic is not quite picking the correct path though so if that's what you're seeing I'd suggest that the correct path should be added to a provider that is generated by the CMake build rules that can then be consumed by downstream CMake rules.
That will work for lagacy CMake project. Here is an example of Modern CMake
# lib A using cmake
# ...
add_library(A, ...)
install(TARGETS A EXPORT "A-targets" ...)
install(EXPORT ${targets_export_name} DESTINATION "share/A/A-config.cmake" )
# ...
# lib B using cmake and depends on A
# ...
find_package(A) # this step will look for "A-config.cmake" and will fail if not found
add_executable(B, ...)
target_link_libraries(B A ...)
for example here is the install output of a cmake project "fmt" https://github.com/fmtlib/fmt
cmake --install . --prefix=/tmp/z
-- Install configuration: "Release"
-- Installing: /tmp/z/lib/libfmt.so.9.1.0
-- Installing: /tmp/z/lib/libfmt.so.9
-- Installing: /tmp/z/lib/libfmt.so
-- Installing: /tmp/z/include/fmt/args.h
-- Installing: /tmp/z/include/fmt/chrono.h
-- Installing: /tmp/z/include/fmt/color.h
-- Installing: /tmp/z/include/fmt/compile.h
-- Installing: /tmp/z/include/fmt/core.h
-- Installing: /tmp/z/include/fmt/format.h
-- Installing: /tmp/z/include/fmt/format-inl.h
-- Installing: /tmp/z/include/fmt/os.h
-- Installing: /tmp/z/include/fmt/ostream.h
-- Installing: /tmp/z/include/fmt/printf.h
-- Installing: /tmp/z/include/fmt/ranges.h
-- Installing: /tmp/z/include/fmt/std.h
-- Installing: /tmp/z/include/fmt/xchar.h
-- Installing: /tmp/z/lib/cmake/fmt/fmt-config.cmake
-- Installing: /tmp/z/lib/cmake/fmt/fmt-config-version.cmake
-- Installing: /tmp/z/lib/cmake/fmt/fmt-targets.cmake
-- Installing: /tmp/z/lib/cmake/fmt/fmt-targets-release.cmake
-- Installing: /tmp/z/lib/pkgconfig/fmt.pc
Could you put together a simple example in the examples folder that shows how it breaks with the modern cmake style? We can then work out what we need to pass in a provider to correctly allow downstream invocations of CMake to find the right config files.
Hello, I realized that the issue is related to my code. I was using a different target name for the Bazel target than what CMake is expecting for a package name. In the example below, building @spdlog//:spdlog
will fail unless you rename the target bzl-fmt
to fmt
. The reason is that the .ext_build_deps
uses the name of the Bazel target as a prefix to the install dir
Thank you for your time. Please close the issue at your convenience.
http_archive(
name = "fmt",
sha256 = "312151a2d13c8327f5c9c586ac6cf7cddc1658e8f53edae0ec56509c8fa516c9",
strip_prefix = "fmt-10.2.1",
url = "https://github.com/fmtlib/fmt/releases/download/10.2.1/fmt-10.2.1.zip",
build_file_content = """
load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake")
filegroup(
name = "fmt_all",
srcs = glob(["**"]),
)
cmake (
name = "bzl-fmt",
lib_source = ":fmt_all",
out_static_libs = ["libfmt.a"],
cache_entries = {
"FMT_TEST":"OFF",
"FMT_DOC":"OFF"
},
visibility = ["//visibility:public"]
)
"""
)
http_archive(
name = "spdlog",
sha256 = "429a6b73ade8285cb21f83bacf89e2821dd1720ea7faa3cb518ffe04b4e00efc",
strip_prefix = "spdlog-1.14.0",
url = "https://github.com/gabime/spdlog/archive/refs/tags/v1.14.0.tar.gz",
build_file_content = """
load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake")
filegroup(
name = "spdlog_all",
srcs = glob(["**"]),
)
cmake (
name = "spdlog",
generate_args = ["--debug-find"],
lib_source = ":spdlog_all",
out_static_libs = ["libspdlog.a"],
cache_entries = {
"SPDLOG_FMT_EXTERNAL": "ON",
"SPDLOG_INSTALL": "ON",
"SPDLOG_BUILD_EXAMPLE": "OFF"
},
deps = ["@fmt//:bzl-fmt"],
visibility = ["//visibility:public"]
)
"""
)```
Ok, great to know.
BTW in case you weren't aware there are native build files available in the BCR for fmt and spdlog: https://registry.bazel.build/modules/spdlog and https://registry.bazel.build/modules/fmt
I'd always recommend using native build files whenever possible as bazel will be more efficient this way.
In modern CMake, an export file(s) are created during the build. Dependent external targets use these files to find and configure the package by name. The location of the exported files varies by project. The common location is
It is preferred to normalize the output location and use
share/<package-name>/
(this is used in vcpkg). Thepackage-name
could be passed as an argument or use the rule name if empty.If approved I could write it and send a PR.