blob: 28cb36fca8c54b57d843c456cff6fd0b04b86be2 (
plain) (
tree)
|
|
# ~~~
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ~~~
#[=======================================================================[.rst:
FindProtobufTargets
-------------------
A module to use `Protobuf` with less complications.
Using ``find_package(Protobuf)`` should be simple, but it is not.
CMake provides a ``FindProtobuf`` module. Unfortunately it does not generate
`protobuf::*` targets until CMake-3.9, and `protobuf::protoc` does not
appear until CMake-3.10.
The CMake-config files generated by `protobuf` always create these targets,
but on some Linux distributions (e.g. Fedora>=29, and openSUSE-Tumbleweed) there
are system packages for protobuf, but these packages are installed without the
CMake-config files. One must either use the ``FindProtobuf`` module, find the
libraries via `pkg-config`, or find the libraries manually.
When the CMake-config files are installed they produce the same targets as
recent versions of ``FindProtobuf``. However, they do not produce the
`Protobuf_LIBRARY`, `Protobuf_INCLUDE_DIR`, etc. that are generated by the
module. Furthermore, the `protobuf::protoc` library is not usable when loaded
from the CMake-config files: its ``IMPORTED_LOCATION`` variable is not defined.
This module is designed to provide a single, uniform, ``find_package()``
module that always produces the same outputs:
- It always generates the ``protobuf::*`` targets.
- It always defines ``ProtobufTargets_FOUND`` and ``ProtobufTargets_VERSION``.
- It *prefers* using the CMake config files if they are available.
- It fallsback on the ``FindProtobuf`` module if the config files are not found.
- It populates any missing targets and their properties.
The following :prop_tgt:`IMPORTED` targets are defined:
``protobuf::libprotobuf``
The protobuf library.
``protobuf::libprotobuf-lite``
The protobuf lite library.
``protobuf::libprotoc``
The protoc library.
``protobuf::protoc``
The protoc compiler.
Example:
.. code-block:: cmake
find_package(ProtobufTargets REQUIRED)
add_executable(bar bar.cc)
target_link_libraries(bar PRIVATE protobuf::libprotobuf)
#]=======================================================================]
if (protobuf_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"protobuf_USE_STATIC_LIBS = ${protobuf_USE_STATIC_LIBS}"
" ProtobufTargets = ${ProtobufTargets_FOUND}")
endif ()
# Always load thread support, even on Windows.
find_package(Threads REQUIRED)
# First try to use the ``protobufConfig.cmake`` or ``protobuf-config.cmake``
# file if it was installed. This is common on systems (or package managers)
# where protobuf was compiled and installed with `CMake`. Note that on Linux
# this *must* be all lowercase ``protobuf``, while on Windows it does not
# matter.
find_package(protobuf CONFIG)
if (protobuf_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"protobuf_FOUND = ${protobuf_FOUND}"
" protobuf_VERSION = ${protobuf_VERSION}")
endif ()
if (protobuf_FOUND)
set(ProtobufTargets_FOUND 1)
set(ProtobufTargets_VERSION ${protobuf_VERSION})
if (protobuf_DEBUG)
message(
STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"ProtobufTargets_FOUND = ${ProtobufTargets_FOUND}"
" ProtobufTargets_VERSION = ${ProtobufTargets_VERSION}")
endif ()
else ()
find_package(Protobuf QUIET)
if (Protobuf_FOUND)
set(ProtobufTargets_FOUND 1)
set(ProtobufTargets_VERSION ${Protobuf_VERSION})
if (NOT TARGET protobuf::libprotobuf)
add_library(protobuf::libprotobuf IMPORTED INTERFACE)
set_property(TARGET protobuf::libprotobuf
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${Protobuf_INCLUDE_DIR})
set_property(TARGET protobuf::libprotobuf
APPEND
PROPERTY INTERFACE_LINK_LIBRARIES ${Protobuf_LIBRARY}
Threads::Threads)
endif ()
if (NOT TARGET protobuf::libprotobuf-lite)
add_library(protobuf::libprotobuf-lite IMPORTED INTERFACE)
set_property(TARGET protobuf::libprotobuf-lite
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${Protobuf_INCLUDE_DIR})
set_property(TARGET protobuf::libprotobuf-lite
APPEND
PROPERTY INTERFACE_LINK_LIBRARIES
${Protobuf_LITE_LIBRARY} Threads::Threads)
endif ()
if (NOT TARGET protobuf::libprotoc)
add_library(protobuf::libprotoc IMPORTED INTERFACE)
set_property(TARGET protobuf::libprotoc
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${Protobuf_INCLUDE_DIR})
set_property(TARGET protobuf::libprotoc
APPEND
PROPERTY INTERFACE_LINK_LIBRARIES
${Protobuf_PROTOC_LIBRARY} Threads::Threads)
endif ()
endif ()
endif ()
if (protobuf_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"ProtobufTargets_FOUND = ${ProtobufTargets_FOUND}"
" ProtobufTargets_VERSION = ${ProtobufTargets_VERSION}")
endif ()
# We also should try to find the protobuf C++ plugin for the protocol buffers
# compiler.
if (ProtobufTargets_FOUND AND NOT TARGET protobuf::protoc)
add_executable(protobuf::protoc IMPORTED)
# Discover the protoc compiler location.
find_program(_protobuf_PROTOC_EXECUTABLE
NAMES protoc
DOC "The Google Protocol Buffers Compiler")
if (protobuf_DEBUG)
message(
STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"ProtobufTargets_FOUND = ${ProtobufTargets_FOUND}"
" ProtobufTargets_VERSION = ${ProtobufTargets_VERSION}"
" EXE = ${_protobuf_PROTOC_EXECUTABLE}")
endif ()
set_property(TARGET protobuf::protoc
PROPERTY IMPORTED_LOCATION ${_protobuf_PROTOC_EXECUTABLE})
set_property(
TARGET protobuf::protoc
PROPERTY IMPORTED_LOCATION_DEBUG ${_protobuf_PROTOC_EXECUTABLE})
set_property(TARGET protobuf::protoc
PROPERTY IMPORTED_LOCATION_RELEASE
${_protobuf_PROTOC_EXECUTABLE})
unset(_protobuf_PROTOC_EXECUTABLE)
if (protobuf_DEBUG)
get_target_property(_protobuf_PROTOC_EXECUTABLE protobuf::protoc
IMPORTED_LOCATION)
message(
STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"LOCATION=${_protobuf_PROTOC_EXECUTABLE}")
endif ()
endif ()
if (protobuf_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"ProtobufTargets_FOUND = ${ProtobufTargets_FOUND}"
" ProtobufTargets_VERSION = ${ProtobufTargets_VERSION}")
if (ProtobufTargets_FOUND)
foreach (_target
protobuf::libprotobuf
protobuf::libprotobuf-lite
protobuf::libprotoc)
if (NOT TARGET ${_target})
message(
STATUS
"[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"target=${_target} is NOT a target")
endif ()
endforeach ()
unset(_target)
endif ()
endif ()
find_package_handle_standard_args(ProtobufTargets
REQUIRED_VARS
ProtobufTargets_FOUND
ProtobufTargets_VERSION)
|