Closed alejandro-colomar closed 3 years ago
Hey,
this is not a bug in prometheus-cpp, but an expected behavior of packages found in conan-center. Since Conan aims to be build-system agnostic, it requires recipes in conan-center to remove all build-system specific files such as prometheus-cpp-config.cmake
from the resulting packages. Instead, how those packages are meant to be used is through generators that create these integration files themselves. In your case, you used the cmake_find_package
generator which created the Findprometheus-cpp.cmake
file that gets loaded when you do find_package(prometheus-cpp REQUIRED)
(the default mode is MODULE
). If you want to use the CONFIG
approach, then the cmake_find_package_multi
should be the one that's used, since that's the one that generates prometheus-cpp-config.cmake
. You can read more about the mentioned conan-center constraint here and about the available CMake generators here.
P.S. You might also want to change the compiler.libcxx
in your Conan profile to libstdc++11
, since libstdc++
denotes the old gcc ABI used before version 5.1.
Hmmm, it's not that I want to use the CONFIG
approach, but the default MODULE
is not working for me. If there's any way I can fix that, I guess it'll be better than using CONFIG
, ain't it? Would you mind helping me fix that? Maybe I should open a separate issue for that?
Thanks! (and thanks too for the remark about libstdc++11
:)
Alex
Can you share the rest of your CMakeLists.txt file? Specifically the part where you create the library that contains xxx.cpp
.
As for the approaches, as far as I can tell they are all evolving, so just use what works for you. I currently use a custom recipe that doesn't delete the original prometheus-cpp-config.cmake
file and use the cmake_paths
generator to help CMake find it, but last I saw using that generator is a bit discouraged by the Conan devs.
add_library(xxx SHARED
xxx.cpp
asio.cpp
time.cpp
xxxxxx.cpp
metrics/server.cpp
kafka/producer.cpp
)
There's not much there, and between find_package(prometheus-cpp ...) and that, there's 0 code affecting prometheus, there's only code calling other dependencies, similar to how I used prometheus-cpp before trying conan.
I'll show you the diff of my attempt to use conan, so you can see what I had before (which worked) (you'll see here prometheus-cpp 0.11.0, because that's what I use, but I made sure that with 0.12.1 I have the same exact problem):
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bd99679..3e220d2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,10 +9,12 @@ set(THIRDPARTY_DIR "${CMAKE_SOURCE_DIR}/thirdparty")
set(CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
+ ${CMAKE_BINARY_DIR}
${CMAKE_MODULE_PATH}
"${THIRDPARTY_DIR}/catch2/cmake"
"${THIRDPARTY_DIR}/CMake-codecov/cmake"
)
+set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR} ${CMAKE_PREFIX_PATH})
include(Version)
diff --git a/conanfile.txt b/conanfile.txt
new file mode 100644
index 0000000..a1bd07b
--- /dev/null
+++ b/conanfile.txt
@@ -0,0 +1,11 @@
+[requires]
+ openssl/1.1.1k
+ prometheus-cpp/0.11.0
+
+[generators]
+ cmake_find_package
+
+[options]
+ prometheus-cpp:shared=False
+ prometheus-cpp:with_pull=True
+ prometheus-cpp:with_push=False
diff --git a/src/xxx/CMakeLists.txt b/src/xxx/CMakeLists.txt
index ece54d3..ce5e25b 100644
--- a/src/xxx/CMakeLists.txt
+++ b/src/xxx/CMakeLists.txt
@@ -92,31 +92,7 @@ if(NOT asio_POPULATED)
set(asio_INCLUDE_DIR ${asio_SOURCE_DIR}/asio/include)
endif()
-ExternalProject_Add(prometheus
- PREFIX ${THIRDPARTY_DIR}/prometheus
- GIT_REPOSITORY git@xxxxxxxxxxxxxxxxxx/dependencies/prometheus-cpp.git
- GIT_TAG v0.11.0
- GIT_REMOTE_NAME xxxxxxxxx
- #GIT_PROGRESS ON
- #GIT_SHALLOW ON # this project cannot be shallow-cloned
- #INSTALL_COMMAND ""
- EXCLUDE_FROM_ALL ON
- CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF --log-level=WARNING -DCMAKE_POSITION_INDEPENDENT_CODE=ON
- -DENABLE_TESTING=OFF
- -DENABLE_PULL=ON
- -DENABLE_PUSH=OFF
- -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
- )
-ExternalProject_Get_property(prometheus SOURCE_DIR)
-ExternalProject_Get_property(prometheus BINARY_DIR)
-set(prometheus_INCLUDE_DIRS ${SOURCE_DIR}/core/include)
-# TODO: Review the prometheus build configurations, this structure seems a bit strange.
-list(APPEND prometheus_INCLUDE_DIRS
- ${BINARY_DIR}/core/include
- ${SOURCE_DIR}/pull/include
- ${BINARY_DIR}/pull/include
- )
-set(prometheus_LIBRARY_DIR ${BINARY_DIR}/lib)
+find_package(prometheus-cpp 0.11.0 REQUIRED)
ExternalProject_Add(rdkafka
PREFIX ${THIRDPARTY_DIR}/rdkafka
@@ -195,7 +171,6 @@ endif()
add_dependencies(xxx
spdlog
rdkafka
- prometheus
)
target_include_directories(xxx PRIVATE
Do you have a target_link_libraries(xxx prometheus-cpp::core prometheus-cpp::pull)
line anywhere? Your compiler can't find prometheus-cpp include dirs so somehow it's not being put on the xxx
target compile line. Where were prometheus_INCLUDE_DIRS
and prometheus_LIBRARY_DIR
used in your CMakeLists.txt before?
Ahhh, yes, it was to the end of the file:
$ find -type f | grep -i cmake | xargs pcregrep -Mn '(?s)target_link_libraries.*?\)';
./src/xxx/CMakeLists.txt:200:
target_link_libraries(xxx PRIVATE
libavrocpp_s.a
${json_LIBRARY}
librdkafka++.a librdkafka.a
${OPENSSL_LIBRARIES}
prometheus-cpp-pull prometheus-cpp-core
${spdlog_LIBRARY}
stdc++fs
)
I'm new to this project where I need to move the current implementation to use conan; I've always used make & pkg-config & simple POSIX tools, so all this is new to me :).
Thanks for the help!
prometheus_INCLUDE_DIR
was/is being used here:
$ find -type f | grep -i cmake | xargs pcregrep -Mn '(?s)target_include_directories.*?\)';
./src/xxx/CMakeLists.txt:176:
target_include_directories(xxx PRIVATE
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/xxxxxx
${asio_INCLUDE_DIR}
${avro_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${json_INCLUDE_DIR}
${prometheus_INCLUDE_DIRS}
${rdkafka_INCLUDE_DIR}
${span_INCLUDE_DIR}
${spdlog_INCLUDE_DIR}
)
prometheus_LIBRARY_DIR
was/is being used here:
$ find -type f | grep -i cmake | xargs pcregrep -Mn '(?s)target_link_directories.*?\)'
./src/xxx/CMakeLists.txt:190:
target_link_directories(xxx PRIVATE
${avro_LIBRARY_DIR}
${json_LIBRARY_DIR}
${prometheus_LIBRARY_DIR} #libprometheus-cpp-core.a && pull.a
${rdkafka_LIBRARY_DIR}/src-cpp #librdkafka++.a
${rdkafka_LIBRARY_DIR}/src #librdkafka.a
${spdlog_LIBRARY_DIR}
)
A couple of things I see:
prometheus-cpp-pull
and prometheus-cpp-core
targets were only available to you when you used ExternalProject, since they are defined internally in prometheus-cpp and not exported. When using find_package you should use prometheus-cpp::pull
and prometheus-cpp::core
.prometheus_INCLUDE_DIRS
and prometheus_LIBRARY_DIR
are not set anymore, so they will be empty. Instead of using those variables, you should use the prometheus-cpp::core
and prometheus-cpp::pull
targets in target_link_libraries
, they will make sure all the prometheus-cpp libs/include paths (+transitives) are propagated to the compiler line.In general, modern CMake advises always using targets instead of variables. Here's one great talk about all of that if you're relatively new to CMake.
Great!
After removing prometheus_*_DIR[S]
and replacing prometheus-cpp-*
by prometheus-cpp::*
, it started finding the headers, and gave a new error in the linking stage.
Then, after replacing compiler.libcxx=libstdc++
by compiler.libcxx=libstdc++11
, those linker errors disappeared, and now it works!!
:-)
I'm trying to consume prometheus-cpp using conan.
For the configuration I need, there isn't a binary in conan-center:
So I built it myself:
But it generates
Findprometheus-cpp.cmake
, and notprometheus-cpp-config.cmake
.So, if I use the cmake configuration that you suggest in your example , it fails to find it:
And if I use
It correctly finds
Findprometheus-cpp.cmake
, but then it fails later:eventhough I know that header file does exist on my machine:
Am I missing something, or is it a bug in prometheus-cpp?