Skip to content

Commit a357529

Browse files
authored
Merge pull request mfontanini#204 from accelerated/cmake
Add CMake configuration file and export installed targets
2 parents 18d0b0c + dd6ec44 commit a357529

File tree

12 files changed

+236
-88
lines changed

12 files changed

+236
-88
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ script:
3737
- ./configure --prefix=./install && make libs && make install
3838
- cd ..
3939
- mkdir build && cd build
40-
- cmake .. -DRDKAFKA_ROOT_DIR=../librdkafka/install/ -DKAFKA_TEST_INSTANCE=localhost:9092
40+
- cmake .. -DCPPKAFKA_CMAKE_VERBOSE=ON -DRDKAFKA_ROOT=./librdkafka/install -DKAFKA_TEST_INSTANCE=localhost:9092
4141
- make examples
4242
- make tests
4343
- ./tests/cppkafka_tests

CMakeLists.txt

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1-
cmake_minimum_required(VERSION 2.8.1)
2-
project(cppkafka)
1+
cmake_minimum_required(VERSION 3.9.2)
2+
project(CppKafka)
3+
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0")
4+
# Use <package>_ROOT variable to find configuration files
5+
cmake_policy(SET CMP0074 NEW)
6+
endif()
7+
8+
include(GNUInstallDirs)
9+
include(CMakePackageConfigHelpers)
310

411
# Set the version number.
512
set(CPPKAFKA_VERSION_MAJOR 0)
613
set(CPPKAFKA_VERSION_MINOR 3)
714
set(CPPKAFKA_VERSION_REVISION 1)
815
set(CPPKAFKA_VERSION "${CPPKAFKA_VERSION_MAJOR}.${CPPKAFKA_VERSION_MINOR}.${CPPKAFKA_VERSION_REVISION}")
9-
set(RDKAFKA_MIN_VERSION 0x00090400)
16+
set(RDKAFKA_MIN_VERSION "0.9.4")
17+
set(RDKAFKA_MIN_VERSION_HEX 0x00090400)
1018

1119
if (NOT CMAKE_CXX_FLAGS)
1220
# Set default compile flags for the project
@@ -23,7 +31,6 @@ if (NOT CMAKE_CXX_FLAGS)
2331
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall")
2432
endif()
2533
endif()
26-
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
2734

2835
# Set output directories
2936
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
@@ -37,16 +44,35 @@ option(CPPKAFKA_DISABLE_EXAMPLES "Disable build of cppkafka examples." OFF)
3744
option(CPPKAFKA_BOOST_STATIC_LIBS "Link with Boost static libraries." ON)
3845
option(CPPKAFKA_BOOST_USE_MULTITHREADED "Use Boost multithreaded libraries." ON)
3946
option(CPPKAFKA_RDKAFKA_STATIC_LIB "Link with Rdkafka static library." OFF)
47+
option(CPPKAFKA_EXPORT_PKGCONFIG "Generate 'cppkafka.pc' file" ON)
48+
option(CPPKAFKA_EXPORT_CMAKE_CONFIG "Generate CMake config, target and version files." ON)
49+
50+
# Add FindRdKafka.cmake
51+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
4052

41-
math(EXPR BITS "8*${CMAKE_SIZEOF_VOID_P}")
53+
if (NOT CPPKAFKA_CONFIG_DIR)
54+
set(CPPKAFKA_CONFIG_DIR lib/cmake/${PROJECT_NAME})
55+
endif()
56+
57+
# Maintain previous compatibility
58+
if (RDKAFKA_ROOT_DIR)
59+
set(RdKafka_ROOT ${RDKAFKA_ROOT_DIR})
60+
elseif (RDKAFKA_ROOT)
61+
set(RdKafka_ROOT ${RDKAFKA_ROOT})
62+
endif()
63+
64+
if (RdKafka_ROOT)
65+
if (NOT IS_ABSOLUTE ${RdKafka_ROOT})
66+
set(RdKafka_ROOT "${CMAKE_SOURCE_DIR}/${RdKafka_ROOT}")
67+
endif()
68+
endif()
4269

43-
# Properly set the output directory
44-
#if (${BITS} EQUAL 64)
45-
# set(LIBDIR "lib64")
46-
#else()
47-
# set(LIBDIR "lib")
48-
#endif()
49-
set(LIBDIR "lib")
70+
if (RDKAFKA_DIR)
71+
set(RdKafka_DIR ${RDKAFKA_DIR}) # For older versions of find_package
72+
if (NOT IS_ABSOLUTE ${RdKafka_ROOT})
73+
set(RdKafka_DIR "${CMAKE_SOURCE_DIR}/${RdKafka_DIR}")
74+
endif()
75+
endif()
5076

5177
# Disable output from find_package macro
5278
if (NOT CPPKAFKA_CMAKE_VERBOSE)
@@ -61,19 +87,23 @@ else()
6187
message(STATUS "Build will generate a static library.")
6288
set(CPPKAFKA_LIBRARY_TYPE STATIC)
6389
add_definitions("-DCPPKAFKA_STATIC=1")
90+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
6491
endif()
6592

6693
if (CPPKAFKA_RDKAFKA_STATIC_LIB)
6794
add_definitions("-DLIBRDKAFKA_STATICLIB")
6895
endif()
6996

97+
if (NOT CPPKAFKA_CONFIG_DIR)
98+
set(CPPKAFKA_CONFIG_DIR lib/cmake/${PROJECT_NAME})
99+
endif()
100+
70101
if (NOT CPPKAFKA_PKGCONFIG_DIR)
71102
set(CPPKAFKA_PKGCONFIG_DIR share/pkgconfig)
72103
endif()
73104

74105
# Look for Boost (just need boost.optional headers here)
75106
find_package(Boost REQUIRED ${FIND_PACKAGE_QUIET})
76-
find_package(RdKafka REQUIRED ${FIND_PACKAGE_QUIET})
77107

78108
if (Boost_FOUND)
79109
find_package(Boost COMPONENTS program_options ${FIND_PACKAGE_QUIET})
@@ -90,8 +120,24 @@ if (Boost_FOUND)
90120
endif()
91121
endif()
92122

123+
# Try to find the RdKafka configuration file if present.
124+
# This will search default system locations as well as RdKafka_ROOT and RdKafka_Dir paths if specified.
125+
find_package(RdKafka ${FIND_PACKAGE_QUIET} CONFIG)
126+
set(RDKAFKA_TARGET_IMPORTS ${RdKafka_FOUND})
127+
if (NOT RdKafka_FOUND)
128+
message(STATUS "RdKafkaConfig.cmake not found. Attempting to find module instead...")
129+
find_package(RdKafka REQUIRED ${FIND_PACKAGE_QUIET} MODULE)
130+
if (NOT RdKafka_FOUND)
131+
message(FATAL_ERROR "RdKafka module not found. Please set RDKAFKA_ROOT to the install path or RDKAFKA_DIR pointing to the RdKafka configuration file location.")
132+
else()
133+
message(STATUS "RdKafka module found.")
134+
endif()
135+
else()
136+
message(STATUS "RdKafka configuration file found: ${RdKafka_CONFIG}")
137+
endif()
138+
93139
add_subdirectory(src)
94-
add_subdirectory(include)
140+
add_subdirectory(include/cppkafka)
95141

96142
# Examples target
97143
if (NOT CPPKAFKA_DISABLE_EXAMPLES AND Boost_PROGRAM_OPTIONS_FOUND)

README.md

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,9 @@ int main() {
5454
In order to compile _cppkafka_ you need:
5555

5656
* _librdkafka >= 0.9.4_
57-
* _CMake_
58-
* A compiler with good C++11 support (e.g. gcc >= 4.8). This was tested successfully on
59-
_g++ 4.8.3_.
60-
* The boost library.
57+
* _CMake >= 3.9.2_
58+
* A compiler with good C++11 support (e.g. gcc >= 4.8). This was tested successfully on _g++ 4.8.3_.
59+
* The boost library (for boost::optional)
6160

6261
Now, in order to build, just run:
6362

@@ -66,12 +65,14 @@ mkdir build
6665
cd build
6766
cmake <OPTIONS> ..
6867
make
68+
make install
6969
```
7070

7171
## CMake options
7272

7373
The following cmake options can be specified:
74-
* `RDKAFKA_ROOT_DIR` : Specify a different librdkafka install directory.
74+
* `RDKAFKA_ROOT` : Specify a different librdkafka install directory.
75+
* `RDKAFKA_DIR` : Specify a different directory where the RdKafkaConfig.cmake is installed.
7576
* `BOOST_ROOT` : Specify a different Boost install directory.
7677
* `CPPKAFKA_CMAKE_VERBOSE` : Generate verbose output. Default is `OFF`.
7778
* `CPPKAFKA_BUILD_SHARED` : Build cppkafka as a shared library. Default is `ON`.
@@ -80,25 +81,14 @@ The following cmake options can be specified:
8081
* `CPPKAFKA_BOOST_STATIC_LIBS` : Link with Boost static libraries. Default is `ON`.
8182
* `CPPKAFKA_BOOST_USE_MULTITHREADED` : Use Boost multi-threaded libraries. Default is `ON`.
8283
* `CPPKAFKA_RDKAFKA_STATIC_LIB` : Link to Rdkafka static library. Default is `OFF`.
84+
* `CPPKAFKA_CONFIG_DIR` : Install location of the cmake configuration files. Default is `lib/cmake/cppkafka`.
8385
* `CPPKAFKA_PKGCONFIG_DIR` : Install location of the .pc file. Default is `share/pkgconfig`.
86+
* `CPPKAFKA_EXPORT_PKGCONFIG` : Generate `cppkafka.pc` file. Default is `ON`.
87+
* `CPPKAFKA_EXPORT_CMAKE_CONFIG` : Generate CMake config, target and version files. Default is `ON`.
8488

8589
Example:
8690
```Shell
87-
cmake -DRDKAFKA_ROOT_DIR=/some/other/dir -DCPPKAFKA_BUILD_SHARED=OFF ...
88-
```
89-
90-
The `RDKAFKA_ROOT_DIR` must contain the following structure. If the system
91-
architecture is 64-bit and both `lib` and `lib64` folders are available, the `lib64`
92-
folder location will be selected by cmake.
93-
94-
```Shell
95-
${RDKAFKA_ROOT_DIR}/
96-
|
97-
+ include/librdkafka/rdkafka.h
98-
|
99-
+ lib/librdkafka.a
100-
|
101-
+ lib64/librdkafka.a (optional)
91+
cmake -DRDKAFKA_ROOT=/some/other/dir -DCPPKAFKA_BUILD_SHARED=OFF ...
10292
```
10393

10494
# Using
@@ -108,6 +98,13 @@ If you want to use _cppkafka_, you'll need to link your application with:
10898
* _cppkafka_
10999
* _rdkafka_
110100

101+
If using CMake, this is simplified by doing:
102+
```cmake
103+
find_package(CppKafka REQUIRED)
104+
105+
target_link_libraries(<YourLibrary> CppKafka::cppkafka)
106+
```
107+
111108
# Documentation
112109

113110
You can generate the documentation by running `make docs` inside the build directory. This requires

cmake/FindRdKafka.cmake

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,80 @@
1-
# Override default CMAKE_FIND_LIBRARY_SUFFIXES
2-
# (Allows optional prioritization of static libraries during resolution)
1+
# This find module helps find the RdKafka module. It exports the following variables:
2+
# - RdKafka_INCLUDE_DIR : The directory where rdkafka.h is located.
3+
# - RdKafka_LIBNAME : The name of the library, i.e. librdkafka.a, librdkafka.so, etc.
4+
# - RdKafka_LIBRARY_DIR : The directory where the library is located.
5+
# - RdKafka_LIBRARY_PATH : The full library path i.e. ${RdKafka_LIBRARY_DIR}/${RdKafka_LIBNAME}
6+
# - RdKafka::rdkafka : Imported library containing all above properties set.
7+
38
if (CPPKAFKA_RDKAFKA_STATIC_LIB)
49
set(RDKAFKA_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX})
510
set(RDKAFKA_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
11+
set(RDKAFKA_LIBRARY_TYPE STATIC)
612
else()
713
set(RDKAFKA_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
814
set(RDKAFKA_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
15+
set(RDKAFKA_LIBRARY_TYPE SHARED)
916
endif()
1017

11-
find_path(RDKAFKA_ROOT_DIR
12-
NAMES include/librdkafka/rdkafka.h
13-
)
18+
set(RdKafka_LIBNAME ${RDKAFKA_PREFIX}rdkafka${RDKAFKA_SUFFIX})
1419

15-
find_path(RDKAFKA_INCLUDE_DIR
20+
find_path(RdKafka_INCLUDE_DIR
1621
NAMES librdkafka/rdkafka.h
17-
HINTS ${RDKAFKA_ROOT_DIR}/include
22+
HINTS ${RdKafka_ROOT}/include
23+
)
24+
25+
find_path(RdKafka_LIBRARY_DIR
26+
NAMES ${RdKafka_LIBNAME} rdkafka
27+
HINTS ${RdKafka_ROOT}/lib ${RdKafka_ROOT}/lib64
28+
)
29+
30+
find_library(RdKafka_LIBRARY_PATH
31+
NAMES ${RdKafka_LIBNAME} rdkafka
32+
HINTS ${RdKafka_LIBRARY_DIR}
1833
)
1934

2035
# Check lib paths
2136
if (CPPKAFKA_CMAKE_VERBOSE)
2237
get_property(FIND_LIBRARY_32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS)
2338
get_property(FIND_LIBRARY_64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
24-
MESSAGE(STATUS "RDKAFKA search 32-bit library paths: ${FIND_LIBRARY_32}")
25-
MESSAGE(STATUS "RDKAFKA search 64-bit library paths: ${FIND_LIBRARY_64}")
39+
message(STATUS "RDKAFKA search 32-bit library paths: ${FIND_LIBRARY_32}")
40+
message(STATUS "RDKAFKA search 64-bit library paths: ${FIND_LIBRARY_64}")
41+
message(STATUS "RdKafka_ROOT = ${RdKafka_ROOT}")
42+
message(STATUS "RdKafka_INCLUDE_DIR = ${RdKafka_INCLUDE_DIR}")
43+
message(STATUS "RdKafka_LIBNAME = ${RdKafka_LIBNAME}")
44+
message(STATUS "RdKafka_LIBRARY_PATH = ${RdKafka_LIBRARY_PATH}")
45+
message(STATUS "RdKafka_LIBRARY_DIR = ${RdKafka_LIBRARY_DIR}")
2646
endif()
2747

28-
find_library(RDKAFKA_LIBRARY
29-
NAMES ${RDKAFKA_PREFIX}rdkafka${RDKAFKA_SUFFIX} rdkafka
30-
HINTS ${RDKAFKA_ROOT_DIR}/lib
31-
)
32-
3348
include(FindPackageHandleStandardArgs)
3449
find_package_handle_standard_args(RDKAFKA DEFAULT_MSG
35-
RDKAFKA_LIBRARY
36-
RDKAFKA_INCLUDE_DIR
50+
RdKafka_LIBNAME
51+
RdKafka_LIBRARY_DIR
52+
RdKafka_LIBRARY_PATH
53+
RdKafka_INCLUDE_DIR
3754
)
3855

39-
set(CONTENTS "#include <librdkafka/rdkafka.h>\n #if RD_KAFKA_VERSION >= ${RDKAFKA_MIN_VERSION}\n int main() { }\n #endif")
40-
set(FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/rdkafka_version_test.c)
56+
set(CONTENTS "#include <librdkafka/rdkafka.h>\n #if RD_KAFKA_VERSION >= ${RDKAFKA_MIN_VERSION_HEX}\n int main() { }\n #endif")
57+
set(FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/rdkafka_version_test.cpp)
4158
file(WRITE ${FILE_NAME} ${CONTENTS})
4259

43-
try_compile(HAVE_VALID_KAFKA_VERSION ${CMAKE_CURRENT_BINARY_DIR}
60+
try_compile(RdKafka_FOUND ${CMAKE_CURRENT_BINARY_DIR}
4461
SOURCES ${FILE_NAME}
45-
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${RDKAFKA_INCLUDE_DIR}")
62+
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${RdKafka_INCLUDE_DIR}")
4663

47-
if (HAVE_VALID_KAFKA_VERSION)
64+
if (RdKafka_FOUND)
65+
add_library(RdKafka::rdkafka ${RDKAFKA_LIBRARY_TYPE} IMPORTED GLOBAL)
66+
set(RDKAFKA_DEPENDENCIES pthread rt ssl crypto dl z)
67+
set_target_properties(RdKafka::rdkafka PROPERTIES
68+
IMPORTED_NAME RdKafka
69+
IMPORTED_LOCATION "${RdKafka_LIBRARY_PATH}"
70+
INTERFACE_INCLUDE_DIRECTORIES "${RdKafka_INCLUDE_DIR}"
71+
INTERFACE_LINK_DIRECTORIES "${RdKafka_LIBRARY_DIR}"
72+
INTERFACE_LINK_LIBRARIES "${RDKAFKA_DEPENDENCIES}")
4873
message(STATUS "Found valid rdkafka version")
4974
mark_as_advanced(
50-
RDKAFKA_ROOT_DIR
51-
RDKAFKA_INCLUDE_DIR
5275
RDKAFKA_LIBRARY
76+
RdKafka_LIBRARY_DIR
77+
RdKafka_INCLUDE_DIR
5378
)
5479
else()
5580
message(FATAL_ERROR "Failed to find valid rdkafka version")

cmake/config.cmake.in

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
@PACKAGE_INIT@
2+
3+
include(CMakeFindDependencyMacro)
4+
5+
# Add FindRdKafka.cmake
6+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}")
7+
8+
set(RDKAFKA_MIN_VERSION_HEX "@RDKAFKA_MIN_VERSION_HEX@")
9+
10+
# Find boost optional
11+
find_dependency(Boost REQUIRED)
12+
13+
# Try to find the RdKafka configuration file if present.
14+
# This will search default system locations as well as RdKafka_ROOT and RdKafka_DIR paths if specified.
15+
find_package(RdKafka QUIET CONFIG)
16+
set(RDKAFKA_TARGET_IMPORTS ${RdKafka_FOUND})
17+
if (NOT RdKafka_FOUND)
18+
find_dependency(RdKafka REQUIRED MODULE)
19+
endif()
20+
21+
include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_EXPORT_NAME@.cmake")
22+
23+
# Export 'CppKafka_ROOT'
24+
set_and_check(@PROJECT_NAME@_ROOT "@PACKAGE_CMAKE_INSTALL_PREFIX@")
25+
26+
# Export 'CppKafka_INSTALL_INCLUDE_DIR'
27+
set_and_check(@PROJECT_NAME@_INSTALL_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
28+
29+
# Export 'CppKafka_INSTALL_LIB_DIR'
30+
set_and_check(@PROJECT_NAME@_INSTALL_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
31+
32+
# Validate installed components
33+
check_required_components("@PROJECT_NAME@")
File renamed without changes.

cppkafka.pc.in renamed to cmake/cppkafka.pc.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
prefix=@CMAKE_INSTALL_PREFIX@
22
exec_prefix=${prefix}
3-
libdir=${prefix}/@LIBDIR@
4-
sharedlibdir=${prefix}/@LIBDIR@
3+
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
4+
sharedlibdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
55
includedir=${prefix}/include
66

77
Name: cppkafka

examples/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
link_libraries(cppkafka ${RDKAFKA_LIBRARY} ${Boost_LIBRARIES} pthread rt ssl crypto dl z)
21
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
3-
include_directories(SYSTEM ${RDKAFKA_INCLUDE_DIR})
42

53
add_custom_target(examples)
64
macro(create_example example_name)
75
string(REPLACE "_" "-" sanitized_name ${example_name})
86
add_executable(${sanitized_name} EXCLUDE_FROM_ALL "${example_name}_example.cpp")
7+
target_link_libraries(${sanitized_name} cppkafka RdKafka::rdkafka Boost::boost Boost::program_options)
98
add_dependencies(examples ${sanitized_name})
109
endmacro()
1110

include/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

include/cppkafka/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function(make_cppkafka_header)
1010
endforeach()
1111

1212
#create file from template
13-
configure_file(${PROJECT_SOURCE_DIR}/cppkafka.h.in ${CPPKAFKA_HEADER} @ONLY)
13+
configure_file(${PROJECT_SOURCE_DIR}/cmake/cppkafka.h.in ${CPPKAFKA_HEADER} @ONLY)
1414
endfunction()
1515

1616
# Run file generation function

0 commit comments

Comments
 (0)