Squashed 'libs/protobuf/' content from commit fcd3b9a85

git-subtree-dir: libs/protobuf
git-subtree-split: fcd3b9a85ef36e46643dc30176cea1a7ad62e02b
This commit is contained in:
Henry Winkel
2022-10-22 14:46:58 +02:00
commit 36bca61764
2186 changed files with 838730 additions and 0 deletions

9
cmake/CMakeLists.txt Normal file
View File

@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.5)
message(WARNING "Calling of cmake with source directory set to \"cmake\" subdirectory of Protocol Buffers project is deprecated. Top-level directory of Protocol Buffers project should be used instead.")
project(protobuf C CXX)
set(protobuf_DEPRECATED_CMAKE_SUBDIRECTORY_USAGE TRUE)
include(../CMakeLists.txt)

395
cmake/README.md Normal file
View File

@@ -0,0 +1,395 @@
This directory contains *CMake* files that can be used to build protobuf.
You need to have [CMake](http://www.cmake.org) and
[Git](http://git-scm.com) installed on your computer before proceeding. We
currently support CMake 3.5 and newer on both [Windows](#windows-builds) and
[Linux](#linux-builds).
Most of the instructions will be given using CMake's command-line interface, but
the same actions can be performed using appropriate GUI tools.
# Windows Builds
On Windows, you can build the project from *Command Prompt* and using an
*Visual Studio* IDE. You will also need to have
[Visual Studio](https://www.visualstudio.com) installed on your computer before
proceeding.
## Environment Setup
Open the appropriate *Command Prompt* from the *Start* menu.
For example *x86 Native Tools Command Prompt for VS 2019*:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional>
Change to your working directory:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional>cd C:\Path\to
C:\Path\to>
Where *C:\Path\to* is path to your real working directory.
Create a folder where protobuf headers/libraries/binaries will be installed after built:
C:\Path\to>mkdir install
If *cmake* command is not available from *Command Prompt*, add it to system *PATH* variable:
C:\Path\to>set PATH=%PATH%;C:\Program Files (x86)\CMake\bin
If *git* command is not available from *Command Prompt*, add it to system *PATH* variable:
C:\Path\to>set PATH=%PATH%;C:\Program Files\Git\cmd
Optionally, you will want to download [ninja](https://ninja-build.org/) and add it to your *PATH* variable.
C:\Path\to>set PATH=%PATH%;C:\tools\ninja
Good. Now you are ready to continue.
## Getting Sources
You can get the latest stable source packages from the release page:
https://github.com/protocolbuffers/protobuf/releases/latest
For example: if you only need C++, download `protobuf-cpp-[VERSION].tar.gz`; if
you need C++ and Java, download `protobuf-java-[VERSION].tar.gz` (every package
contains C++ source already); if you need C++ and multiple other languages,
download `protobuf-all-[VERSION].tar.gz`.
Or you can use git to clone from protobuf git repository.
C:\Path\to> mkdir src & cd src
C:\Path\to\src> git clone -b [release_tag] https://github.com/protocolbuffers/protobuf.git
Where *[release_tag]* is a git tag like *v3.0.0-beta-1* or a branch name like *main*
if you want to get the latest code.
Go to the project folder:
C:\Path\to\src> cd protobuf
C:\Path\to\src\protobuf>
Remember to update any submodules if you are using git clone (you can skip this
step if you are using a release .tar.gz or .zip package):
```console
C:\Path\to\src\protobuf> git submodule update --init --recursive
```
Good. Now you are ready for *CMake* configuration.
## CMake Configuration
*CMake* supports a lot of different
[generators](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html)
for various native build systems.
Of most interest to Windows programmers are the following:
* [Visual Studio](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators)
This generates a Visual Studio solution for the project.
* [Ninja](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#ninja-generator)
This uses the external tool [Ninja](https://ninja-build.org/) to build. It is the fastest solution available.
Note that as of Visual Studio 2015, Visual Studio includes
[support for opening directly CMake-based projects](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio).
It is considered good practice not to build CMake projects in the source tree but in a separate folder.
Create a temporary *build* folder and change your working directory to it:
mkdir C:\Path\to\build\protobuf
cd C:\Path\to\build\protobuf
C:\Path\to\build\protobuf>
The *Makefile* and *Ninja* generators can build the project in only one configuration, so you need to build
a separate folder for each configuration.
To use *Debug* configuration using *Ninja*:
C:\Path\to\build\protobuf>mkdir debug & cd debug
C:\Path\to\build\protobuf\debug>cmake -G "Ninja" ^
-DCMAKE_BUILD_TYPE=Debug ^
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^
C:\Path\to\src\protobuf
It will generate *Ninja* build scripts in current directory.
The *Visual Studio* generator is multi-configuration: it will generate a single *.sln* file that can be used for both *Debug* and *Release*:
C:\Path\to\build\protobuf>mkdir solution & cd solution
C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^
C:\Path\to\src\protobuf
It will generate *Visual Studio* solution file *protobuf.sln* in current directory.
### Unit Tests
Unit tests are being built along with the rest of protobuf. The unit tests require Google Mock (now a part of Google Test).
A copy of [Google Test](https://github.com/google/googletest) is included as a Git submodule in the `third-party/googletest` folder.
(You do need to initialize the Git submodules as explained above.)
Alternately, you may want to use protobuf in a larger set-up, you may want to use that standard CMake approach where
you build and install a shared copy of Google Test.
After you've built and installed your Google Test copy, you need add the following definition to your *cmake* command line
during the configuration step: `-Dprotobuf_USE_EXTERNAL_GTEST=ON`.
This will cause the standard CMake `find_package(GTest REQUIRED)` to be used.
[find_package](https://cmake.org/cmake/help/latest/command/find_package.html) will search in a default location,
which on Windows is *C:\Program Files*. This is most likely not what you want. You will want instead to search for
Google Test in your project's root directory (i.e. the same directory you've passed to `CMAKE_INSTALL_PREFIX` when
building Google Test). For this, you need to set the `CMAKE_PREFIX_PATH` CMake variable. (There are other ways in CMake,
see the [manual](https://cmake.org/cmake/help/latest/command/find_package.html) for details.)
For example:
C:\Path\to\build\protobuf>mkdir solution & cd solution
C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^
-DCMAKE_PREFIX_PATH=C:\Path\to\my_big_project ^
-Dprotobuf_USE_EXTERNAL_GTEST=ON ^
C:\Path\to\src\protobuf
In most cases, `CMAKE_PREFIX_PATH` and `CMAKE_INSTALL_PREFIX` will point to the same directory.
To disable testing completely, you need to add the following argument to you *cmake* command line: `-Dprotobuf_BUILD_TESTS=OFF`.
For example:
C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^
-Dprotobuf_BUILD_TESTS=OFF ^
C:\Path\to\src\protobuf
## Compiling
The standard way to compile a *CMake* project is `cmake --build <directory>`.
Note that if your generator supports multiple configurations, you will probably want to specify which one to build:
cmake --build C:\Path\to\build\protobuf\solution --config Release
You can also run directly the build tool you've configured:
C:\Path\to\build\protobuf\debug>ninja
And wait for the compilation to finish.
If you prefer to use the IDE:
* Open the generated protobuf.sln file in Microsoft Visual Studio.
* Choose "Debug" or "Release" configuration as desired.
* From the Build menu, choose "Build Solution".
And wait for the compilation to finish.
## Testing
To run unit-tests, first you must compile protobuf as described above.
Then run:
C:\Path\to\protobuf\cmake\build\release>ctest --progress --output-on-failure
You can also build the `check` target (not idiomatic CMake usage, though):
C:\Path\to\protobuf\cmake\build\release>cmake --build . --target check
or
C:\Path\to\build\protobuf\release>ninja check
You can also build project *check* from Visual Studio solution.
Yes, it may sound strange, but it works.
You should see output similar to:
Running main() from gmock_main.cc
[==========] Running 1546 tests from 165 test cases.
...
[==========] 1546 tests from 165 test cases ran. (2529 ms total)
[ PASSED ] 1546 tests.
To run specific tests, you need to pass some command line arguments to the test program itself:
C:\Path\to\build\protobuf\release>tests.exe --gtest_filter=AnyTest*
Running main() from gmock_main.cc
Note: Google Test filter = AnyTest*
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from AnyTest
[ RUN ] AnyTest.TestPackAndUnpack
[ OK ] AnyTest.TestPackAndUnpack (0 ms)
[ RUN ] AnyTest.TestPackAndUnpackAny
[ OK ] AnyTest.TestPackAndUnpackAny (0 ms)
[ RUN ] AnyTest.TestIs
[ OK ] AnyTest.TestIs (0 ms)
[----------] 3 tests from AnyTest (1 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (2 ms total)
[ PASSED ] 3 tests.
Note that the tests must be run from the source folder.
If all tests are passed, safely continue.
## Installing
To install protobuf to the *install* folder you've specified in the configuration step, you need to build the `install` target:
cmake --build C:\Path\to\build\protobuf\solution --config Release --target install
Or if you prefer:
C:\Path\to\build\protobuf\debug>ninja install
You can also build project *INSTALL* from Visual Studio solution.
It sounds not so strange and it works.
This will create the following folders under the *install* location:
* bin - that contains protobuf *protoc.exe* compiler;
* include - that contains C++ headers and protobuf *.proto files;
* lib - that contains linking libraries and *CMake* configuration files for *protobuf* package.
Now you can if needed:
* Copy the contents of the include directory to wherever you want to put headers.
* Copy protoc.exe wherever you put build tools (probably somewhere in your PATH).
* Copy linking libraries libprotobuf[d].lib, libprotobuf-lite[d].lib, and libprotoc[d].lib wherever you put libraries.
To avoid conflicts between the MSVC debug and release runtime libraries, when
compiling a debug build of your application, you may need to link against a
debug build of libprotobufd.lib with "d" postfix. Similarly, release builds should link against
release libprotobuf.lib library.
## DLLs vs. static linking
Static linking is now the default for the Protocol Buffer libraries. Due to
issues with Win32's use of a separate heap for each DLL, as well as binary
compatibility issues between different versions of MSVC's STL library, it is
recommended that you use static linkage only. However, it is possible to
build libprotobuf and libprotoc as DLLs if you really want. To do this,
do the following:
* Add an additional flag `-Dprotobuf_BUILD_SHARED_LIBS=ON` when invoking cmake
* Follow the same steps as described in the above section.
* When compiling your project, make sure to `#define PROTOBUF_USE_DLLS`.
When distributing your software to end users, we strongly recommend that you
do NOT install libprotobuf.dll or libprotoc.dll to any shared location.
Instead, keep these libraries next to your binaries, in your application's
own install directory. C++ makes it very difficult to maintain binary
compatibility between releases, so it is likely that future versions of these
libraries will *not* be usable as drop-in replacements.
If your project is itself a DLL intended for use by third-party software, we
recommend that you do NOT expose protocol buffer objects in your library's
public interface, and that you statically link protocol buffers into your
library.
## ZLib support
If you want to include GzipInputStream and GzipOutputStream
(google/protobuf/io/gzip_stream.h) in libprotobuf, you will need to do a few
additional steps.
Obtain a copy of the zlib library. The pre-compiled DLL at zlib.net works.
You need prepare it:
* Make sure zlib's two headers are in your `C:\Path\to\install\include` path
* Make sure zlib's linking libraries (*.lib file) is in your
`C:\Path\to\install\lib` library path.
You can also compile it from source by yourself.
Getting sources:
C:\Path\to\src>git clone -b v1.2.8 https://github.com/madler/zlib.git
C:\Path\to\src>cd zlib
Compiling and Installing:
C:\Path\to\src\zlib>mkdir C:\Path\to\build\zlib & cd C:\Path\to\build\zlib
C:\Path\to\build\zlib>mkdir release & cd release
C:\Path\to\build\zlib\release>cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install C:\Path\to\src\zlib
C:\Path\to\src\zlib\build\release>cmake --build . --target install
You can make *debug* version or use *Visual Studio* generator also as before for the
protobuf project.
Now add *bin* folder from *install* to system *PATH*:
C:\Path\to>set PATH=%PATH%;C:\Path\to\install\bin
You need reconfigure protobuf with flag `-Dprotobuf_WITH_ZLIB=ON` when invoking cmake.
Note that if you have compiled ZLIB yourself, as stated above,
further disable the option `-Dprotobuf_MSVC_STATIC_RUNTIME=OFF`.
If it reports NOTFOUND for zlib_include or zlib_lib, you might haven't put
the headers or the .lib file in the right directory.
If you already have ZLIB library and headers at some other location on your system then alternatively you can define following configuration flags to locate them:
-DZLIB_INCLUDE_DIR=<path to dir containing zlib headers>
-DZLIB_LIB=<path to dir containing zlib>
Build and testing protobuf as usual.
## Notes on Compiler Warnings
The following warnings have been disabled while building the protobuf libraries
and compiler. You may have to disable some of them in your own project as
well, or live with them.
* C4244 - Conversion from 'type1' to 'type2', possible loss of data.
* C4251 - 'identifier' : class 'type' needs to have dll-interface to be used by
clients of class 'type2'
* C4267 - Conversion from 'size_t' to 'type', possible loss of data.
* C4305 - 'identifier' : truncation from 'type1' to 'type2'
* C4355 - 'this' : used in base member initializer list
* C4800 - 'type' : forcing value to bool 'true' or 'false' (performance warning)
* C4996 - 'function': was declared deprecated
C4251 is of particular note, if you are compiling the Protocol Buffer library
as a DLL (see previous section). The protocol buffer library uses templates in
its public interfaces. MSVC does not provide any reasonable way to export
template classes from a DLL. However, in practice, it appears that exporting
templates is not necessary anyway. Since the complete definition of any
template is available in the header files, anyone importing the DLL will just
end up compiling instances of the templates into their own binary. The
Protocol Buffer implementation does not rely on static template members being
unique, so there should be no problem with this, but MSVC prints warning
nevertheless. So, we disable it. Unfortunately, this warning will also be
produced when compiling code which merely uses protocol buffers, meaning you
may have to disable it in your code too.
# Linux Builds
Building with CMake works very similarly on Linux. Instead of Visual Studio,
you will need to have gcc or clang installed to handle the C++ builds. CMake
will generate Makefiles by default, but can also be configured to use Ninja. To
build Protobuf, you will need to run (from the source directory):
cmake .
cmake --build . --parallel 10
Protobuf can be tested and installed with CMake:
ctest --verbose
sudo cmake --install .
or directly with the generated Makefiles:
make VERBOSE=1 test
sudo make install

58
cmake/abseil-cpp.cmake Normal file
View File

@@ -0,0 +1,58 @@
# Setup our dependency on Abseil.
set(ABSL_PROPAGATE_CXX_STD ON)
if(TARGET absl::strings)
# If Abseil is included already, skip including it.
# (https://github.com/protocolbuffers/protobuf/issues/10435)
elseif(protobuf_ABSL_PROVIDER STREQUAL "module")
if(NOT ABSL_ROOT_DIR)
set(ABSL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp)
endif()
if(EXISTS "${ABSL_ROOT_DIR}/CMakeLists.txt")
if(protobuf_INSTALL)
# When protobuf_INSTALL is enabled and Abseil will be built as a module,
# Abseil will be installed along with protobuf for convenience.
set(ABSL_ENABLE_INSTALL ON)
endif()
add_subdirectory(${ABSL_ROOT_DIR} third_party/abseil-cpp)
else()
message(WARNING "protobuf_ABSL_PROVIDER is \"module\" but ABSL_ROOT_DIR is wrong")
endif()
if(protobuf_INSTALL AND NOT _protobuf_INSTALL_SUPPORTED_FROM_MODULE)
message(WARNING "protobuf_INSTALL will be forced to FALSE because protobuf_ABSL_PROVIDER is \"module\" and CMake version (${CMAKE_VERSION}) is less than 3.13.")
set(protobuf_INSTALL FALSE)
endif()
elseif(protobuf_ABSL_PROVIDER STREQUAL "package")
# Use "CONFIG" as there is no built-in cmake module for absl.
find_package(absl REQUIRED CONFIG)
endif()
set(_protobuf_FIND_ABSL "if(NOT TARGET absl::strings)\n find_package(absl CONFIG)\nendif()")
set(protobuf_ABSL_USED_TARGETS
absl::algorithm
absl::base
absl::bind_front
absl::bits
absl::cleanup
absl::cord
absl::core_headers
absl::debugging
absl::dynamic_annotations
absl::flags
absl::flat_hash_map
absl::flat_hash_set
absl::function_ref
absl::hash
absl::layout
absl::memory
absl::optional
absl::span
absl::status
absl::statusor
absl::strings
absl::synchronization
absl::time
absl::utility
absl::variant
)

89
cmake/conformance.cmake Normal file
View File

@@ -0,0 +1,89 @@
if (NOT EXISTS "${protobuf_SOURCE_DIR}/third_party/jsoncpp/CMakeLists.txt")
message(FATAL_ERROR
"Cannot find third_party/jsoncpp directory that's needed to "
"build conformance tests. If you use git, make sure you have cloned "
"submodules:\n"
" git submodule update --init --recursive\n"
"If instead you want to skip them, run cmake with:\n"
" cmake -Dprotobuf_BUILD_CONFORMANCE=OFF\n")
endif()
add_custom_command(
OUTPUT
${protobuf_SOURCE_DIR}/conformance/conformance.pb.h
${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc
DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/conformance/conformance.proto
COMMAND ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/conformance/conformance.proto
--proto_path=${protobuf_SOURCE_DIR}/conformance
--cpp_out=${protobuf_SOURCE_DIR}/conformance
)
add_custom_command(
OUTPUT
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.h
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.h
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc
DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto
${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto
COMMAND ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto
--proto_path=${protobuf_SOURCE_DIR}/src
--cpp_out=${protobuf_SOURCE_DIR}/src
)
add_executable(conformance_test_runner
${protobuf_SOURCE_DIR}/conformance/binary_json_conformance_suite.cc
${protobuf_SOURCE_DIR}/conformance/binary_json_conformance_suite.h
${protobuf_SOURCE_DIR}/conformance/conformance.pb.h
${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc
${protobuf_SOURCE_DIR}/conformance/conformance_test.cc
${protobuf_SOURCE_DIR}/conformance/conformance_test_runner.cc
${protobuf_SOURCE_DIR}/conformance/conformance_test_main.cc
${protobuf_SOURCE_DIR}/conformance/text_format_conformance_suite.cc
${protobuf_SOURCE_DIR}/conformance/text_format_conformance_suite.h
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.h
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.h
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc
)
add_executable(conformance_cpp
${protobuf_SOURCE_DIR}/conformance/conformance.pb.h
${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc
${protobuf_SOURCE_DIR}/conformance/conformance_cpp.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.h
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.h
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc
)
target_include_directories(
conformance_test_runner
PUBLIC ${protobuf_SOURCE_DIR} ${protobuf_SOURCE_DIR}/conformance)
target_include_directories(
conformance_cpp
PUBLIC ${protobuf_SOURCE_DIR})
target_include_directories(conformance_test_runner PRIVATE ${ABSL_ROOT_DIR})
target_include_directories(conformance_cpp PRIVATE ${ABSL_ROOT_DIR})
target_link_libraries(conformance_test_runner ${protobuf_LIB_PROTOBUF})
target_link_libraries(conformance_test_runner ${protobuf_ABSL_USED_TARGETS})
target_link_libraries(conformance_cpp ${protobuf_LIB_PROTOBUF})
target_link_libraries(conformance_cpp ${protobuf_ABSL_USED_TARGETS})
add_test(NAME conformance_cpp_test
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/conformance_test_runner
--failure_list ${protobuf_SOURCE_DIR}/conformance/failure_list_cpp.txt
--text_format_failure_list ${protobuf_SOURCE_DIR}/conformance/text_format_failure_list_cpp.txt
--output_dir ${protobuf_TEST_XML_OUTDIR}
${CMAKE_CURRENT_BINARY_DIR}/conformance_cpp
DEPENDS conformance_test_runner conformance_cpp)
set(JSONCPP_WITH_TESTS OFF CACHE BOOL "Disable tests")
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/jsoncpp third_party/jsoncpp)
target_include_directories(conformance_test_runner PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/jsoncpp/include)
target_link_libraries(conformance_test_runner jsoncpp_lib)

57
cmake/examples.cmake Normal file
View File

@@ -0,0 +1,57 @@
if(protobuf_VERBOSE)
message(STATUS "Protocol Buffers Examples Configuring...")
endif()
get_filename_component(examples_dir "${protobuf_SOURCE_DIR}/examples" ABSOLUTE)
if(protobuf_VERBOSE)
message(STATUS "Protocol Buffers Examples Configuring done")
endif()
include(ExternalProject)
# Internal utility function: Create a custom target representing a build of examples with custom options.
function(add_examples_build NAME)
ExternalProject_Add(${NAME}
PREFIX ${NAME}
SOURCE_DIR "${examples_dir}"
BINARY_DIR ${NAME}
STAMP_DIR ${NAME}/logs
INSTALL_COMMAND "" #Skip
LOG_CONFIGURE 1
CMAKE_CACHE_ARGS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
"-Dprotobuf_VERBOSE:BOOL=${protobuf_VERBOSE}"
${ARGN}
)
set_property(TARGET ${NAME} PROPERTY FOLDER "Examples")
set_property(TARGET ${NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
endfunction()
# Add examples as an external project.
# sub_directory cannot be used because the find_package(protobuf) call would cause failures with redefined targets.
add_examples_build(examples "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}")
add_dependencies(examples ${protobuf_LIB_PROTOBUF} ${protobuf_PROTOC_EXE})
option(protobuf_BUILD_EXAMPLES_MULTITEST "Build Examples in multiple configurations. Useful for testing." OFF)
mark_as_advanced(protobuf_BUILD_EXAMPLES_MULTITEST)
if(protobuf_BUILD_EXAMPLES_MULTITEST)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
#Build using the legacy compatibility module.
add_examples_build(examples-legacy
"-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}"
"-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
)
add_dependencies(examples-legacy ${protobuf_LIB_PROTOBUF} ${protobuf_PROTOC_EXE})
#Build using the installed library.
add_examples_build(examples-installed
"-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
)
#Build using the installed library in legacy compatibility mode.
add_examples_build(examples-installed-legacy
"-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
"-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
)
endif()

115
cmake/install.cmake Normal file
View File

@@ -0,0 +1,115 @@
include(GNUInstallDirs)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf.pc.cmake
${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf-lite.pc.cmake
${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc @ONLY)
set(_protobuf_libraries libprotobuf-lite libprotobuf)
if (protobuf_BUILD_LIBPROTOC)
list(APPEND _protobuf_libraries libprotoc)
endif (protobuf_BUILD_LIBPROTOC)
foreach(_library ${_protobuf_libraries})
set_property(TARGET ${_library}
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
$<BUILD_INTERFACE:${protobuf_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
if (UNIX AND NOT APPLE)
set_property(TARGET ${_library}
PROPERTY INSTALL_RPATH "$ORIGIN")
elseif (APPLE)
set_property(TARGET ${_library}
PROPERTY INSTALL_RPATH "@loader_path")
endif()
install(TARGETS ${_library} EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${_library}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${_library}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${_library})
endforeach()
if (protobuf_BUILD_PROTOC_BINARIES)
install(TARGETS protoc EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
if (UNIX AND NOT APPLE)
set_property(TARGET protoc
PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
elseif (APPLE)
set_property(TARGET protoc
PROPERTY INSTALL_RPATH "@loader_path/../lib")
endif()
endif (protobuf_BUILD_PROTOC_BINARIES)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
set(protobuf_HEADERS
${libprotobuf_hdrs}
${libprotoc_hdrs}
${wkt_protos_files}
${descriptor_proto_proto_srcs}
${plugin_proto_proto_srcs}
)
foreach(_header ${protobuf_HEADERS})
string(REPLACE "${protobuf_SOURCE_DIR}/src" "" _header ${_header})
get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/src/${_header}" ABSOLUTE)
get_filename_component(_extract_name ${_header} NAME)
get_filename_component(_extract_to "${CMAKE_INSTALL_INCLUDEDIR}/${_header}" DIRECTORY)
install(FILES "${_extract_from}"
DESTINATION "${_extract_to}"
COMPONENT protobuf-headers
RENAME "${_extract_name}")
endforeach()
# Install configuration
set(_install_cmakedir_desc "Directory relative to CMAKE_INSTALL to install the cmake configuration files")
set(_build_cmakedir_desc "Directory relative to CMAKE_CURRENT_BINARY_DIR for cmake configuration files")
set(_exampledir_desc "Directory relative to CMAKE_INSTALL_DATA to install examples")
set(_protobuf_subdir_desc "Subdirectory in which to install cmake configuration files")
if(NOT MSVC)
set(protobuf_CMAKE_SUBDIR "cmake/protobuf" CACHE STRING "${_protobuf_subdir_desc}")
set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/${protobuf_CMAKE_SUBDIR}" CACHE STRING "${_install_cmakedir_desc}")
set(CMAKE_INSTALL_EXAMPLEDIR "${CMAKE_INSTALL_DATADIR}/protobuf/examples" CACHE STRING "${_exampledir_desc}")
else()
set(protobuf_CMAKE_SUBDIR "cmake" CACHE STRING "${_protobuf_subdir_desc}")
set(CMAKE_INSTALL_CMAKEDIR "cmake" CACHE STRING "${_cmakedir_desc}")
set(CMAKE_INSTALL_EXAMPLEDIR "examples" CACHE STRING "${_exampledir_desc}")
endif()
set(CMAKE_BUILD_CMAKEDIR "${CMAKE_CURRENT_BINARY_DIR}/${protobuf_CMAKE_SUBDIR}" CACHE STRING "${_build_cmakedir_desc}")
mark_as_advanced(protobuf_CMAKE_SUBDIR)
mark_as_advanced(CMAKE_BUILD_CMAKEDIR)
mark_as_advanced(CMAKE_INSTALL_CMAKEDIR)
mark_as_advanced(CMAKE_INSTALL_EXAMPLEDIR)
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-config.cmake.in
${CMAKE_BUILD_CMAKEDIR}/protobuf-config.cmake @ONLY)
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-config-version.cmake.in
${CMAKE_BUILD_CMAKEDIR}/protobuf-config-version.cmake @ONLY)
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-module.cmake.in
${CMAKE_BUILD_CMAKEDIR}/protobuf-module.cmake @ONLY)
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-options.cmake
${CMAKE_BUILD_CMAKEDIR}/protobuf-options.cmake @ONLY)
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-generate.cmake
${CMAKE_BUILD_CMAKEDIR}/protobuf-generate.cmake @ONLY)
# Allows the build directory to be used as a find directory.
install(EXPORT protobuf-targets
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
NAMESPACE protobuf::
COMPONENT protobuf-export
)
install(DIRECTORY ${CMAKE_BUILD_CMAKEDIR}/
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
COMPONENT protobuf-export
PATTERN protobuf-targets.cmake EXCLUDE
)
option(protobuf_INSTALL_EXAMPLES "Install the examples folder" OFF)
if(protobuf_INSTALL_EXAMPLES)
install(DIRECTORY examples/
DESTINATION "${CMAKE_INSTALL_EXAMPLEDIR}"
COMPONENT protobuf-examples)
endif()

View File

@@ -0,0 +1,36 @@
# CMake definitions for libprotobuf_lite (the "lite" C++ protobuf runtime).
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
add_library(libprotobuf-lite ${protobuf_SHARED_OR_STATIC}
${libprotobuf_lite_srcs}
${libprotobuf_lite_hdrs}
${protobuf_version_rc_file})
if(protobuf_HAVE_LD_VERSION_SCRIPT)
if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13)
target_link_options(libprotobuf-lite PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map)
elseif(protobuf_BUILD_SHARED_LIBS)
target_link_libraries(libprotobuf-lite PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map)
endif()
set_target_properties(libprotobuf-lite PROPERTIES
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map)
endif()
target_link_libraries(libprotobuf-lite PRIVATE ${CMAKE_THREAD_LIBS_INIT})
if(protobuf_LINK_LIBATOMIC)
target_link_libraries(libprotobuf-lite PRIVATE atomic)
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
target_link_libraries(libprotobuf-lite PRIVATE log)
endif()
target_include_directories(libprotobuf-lite PUBLIC ${protobuf_SOURCE_DIR}/src)
target_link_libraries(libprotobuf-lite PUBLIC ${protobuf_ABSL_USED_TARGETS})
if(protobuf_BUILD_SHARED_LIBS)
target_compile_definitions(libprotobuf-lite
PUBLIC PROTOBUF_USE_DLLS
PRIVATE LIBPROTOBUF_EXPORTS)
endif()
set_target_properties(libprotobuf-lite PROPERTIES
VERSION ${protobuf_VERSION}
OUTPUT_NAME ${LIB_PREFIX}protobuf-lite
DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}")
add_library(protobuf::libprotobuf-lite ALIAS libprotobuf-lite)

39
cmake/libprotobuf.cmake Normal file
View File

@@ -0,0 +1,39 @@
# CMake definitions for libprotobuf (the "full" C++ protobuf runtime).
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
add_library(libprotobuf ${protobuf_SHARED_OR_STATIC}
${libprotobuf_srcs}
${libprotobuf_hdrs}
${protobuf_version_rc_file})
if(protobuf_HAVE_LD_VERSION_SCRIPT)
if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13)
target_link_options(libprotobuf PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf.map)
elseif(protobuf_BUILD_SHARED_LIBS)
target_link_libraries(libprotobuf PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf.map)
endif()
set_target_properties(libprotobuf PROPERTIES
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotobuf.map)
endif()
target_link_libraries(libprotobuf PRIVATE ${CMAKE_THREAD_LIBS_INIT})
if(protobuf_WITH_ZLIB)
target_link_libraries(libprotobuf PRIVATE ${ZLIB_LIBRARIES})
endif()
if(protobuf_LINK_LIBATOMIC)
target_link_libraries(libprotobuf PRIVATE atomic)
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
target_link_libraries(libprotobuf PRIVATE log)
endif()
target_include_directories(libprotobuf PUBLIC ${protobuf_SOURCE_DIR}/src)
target_link_libraries(libprotobuf PUBLIC ${protobuf_ABSL_USED_TARGETS})
if(protobuf_BUILD_SHARED_LIBS)
target_compile_definitions(libprotobuf
PUBLIC PROTOBUF_USE_DLLS
PRIVATE LIBPROTOBUF_EXPORTS)
endif()
set_target_properties(libprotobuf PROPERTIES
VERSION ${protobuf_VERSION}
OUTPUT_NAME ${LIB_PREFIX}protobuf
DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}")
add_library(protobuf::libprotobuf ALIAS libprotobuf)

30
cmake/libprotoc.cmake Normal file
View File

@@ -0,0 +1,30 @@
# CMake definitions for libprotoc (the protobuf compiler library).
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
add_library(libprotoc ${protobuf_SHARED_OR_STATIC}
${libprotoc_srcs}
${libprotoc_hdrs}
${protobuf_version_rc_file})
if(protobuf_HAVE_LD_VERSION_SCRIPT)
if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13)
target_link_options(libprotoc PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotoc.map)
elseif(protobuf_BUILD_SHARED_LIBS)
target_link_libraries(libprotoc PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotoc.map)
endif()
set_target_properties(libprotoc PROPERTIES
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotoc.map)
endif()
target_link_libraries(libprotoc PRIVATE libprotobuf)
target_link_libraries(libprotoc PUBLIC ${protobuf_ABSL_USED_TARGETS})
if(protobuf_BUILD_SHARED_LIBS)
target_compile_definitions(libprotoc
PUBLIC PROTOBUF_USE_DLLS
PRIVATE LIBPROTOC_EXPORTS)
endif()
set_target_properties(libprotoc PROPERTIES
COMPILE_DEFINITIONS LIBPROTOC_EXPORTS
VERSION ${protobuf_VERSION}
OUTPUT_NAME ${LIB_PREFIX}protoc
DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}")
add_library(protobuf::libprotoc ALIAS libprotoc)

View File

@@ -0,0 +1,60 @@
set(PACKAGE_VERSION "@protobuf_VERSION@")
set(${PACKAGE_FIND_NAME}_VERSION_PRERELEASE "@protobuf_VERSION_PRERELEASE@" PARENT_SCOPE)
# Prerelease versions cannot be passed in directly via the find_package command,
# so we allow users to specify it in a variable
if(NOT DEFINED "${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE")
set("${${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE}" "")
else()
set(PACKAGE_FIND_VERSION ${PACKAGE_FIND_VERSION}-${${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE})
endif()
set(PACKAGE_FIND_VERSION_PRERELEASE "${${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE}")
# VERSION_EQUAL ignores the prerelease strings, so we use STREQUAL.
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
set(PACKAGE_VERSION_COMPATIBLE TRUE) #Assume true until shown otherwise
if(PACKAGE_FIND_VERSION) #Only perform version checks if one is given
if(NOT PACKAGE_FIND_VERSION_MAJOR EQUAL "@protobuf_VERSION_MAJOR@")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
elseif(PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
elseif(PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
# Do not match prerelease versions to non-prerelease version requests.
if(NOT "@protobuf_VERSION_PRERELEASE@" STREQUAL "" AND PACKAGE_FIND_VERSION_PRERELEASE STREQUAL "")
message(AUTHOR_WARNING "To use this prerelease version of ${PACKAGE_FIND_NAME}, set ${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE to '@protobuf_VERSION_PRERELEASE@' or greater.")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()
# Not robustly SemVer compliant, but protobuf never uses '.' separated prerelease identifiers.
if(PACKAGE_FIND_VERSION_PRERELEASE STRGREATER "@protobuf_VERSION_PRERELEASE@")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()
endif()
endif()
# Check and save build options used to create this package
macro(_check_and_save_build_option OPTION VALUE)
if(DEFINED ${PACKAGE_FIND_NAME}_${OPTION} AND
NOT ${PACKAGE_FIND_NAME}_${OPTION} STREQUAL ${VALUE})
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
set(${PACKAGE_FIND_NAME}_${OPTION} ${VALUE} PARENT_SCOPE)
endmacro()
_check_and_save_build_option(WITH_ZLIB @protobuf_WITH_ZLIB@)
_check_and_save_build_option(MSVC_STATIC_RUNTIME @protobuf_MSVC_STATIC_RUNTIME@)
_check_and_save_build_option(BUILD_SHARED_LIBS @protobuf_BUILD_SHARED_LIBS@)
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if(CMAKE_SIZEOF_VOID_P AND "@CMAKE_SIZEOF_VOID_P@")
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P EQUAL "@CMAKE_SIZEOF_VOID_P@")
math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
endif()

View File

@@ -0,0 +1,17 @@
# User options
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-options.cmake")
# Depend packages
@_protobuf_FIND_ZLIB@
@_protobuf_FIND_ABSL@
# Imported targets
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake")
# protobuf-generate function
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-generate.cmake")
# CMake FindProtobuf module compatible file
if(protobuf_MODULE_COMPATIBLE)
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake")
endif()

View File

@@ -0,0 +1,155 @@
function(protobuf_generate)
include(CMakeParseArguments)
set(_options APPEND_PATH)
set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS DEPENDENCIES)
if(COMMAND target_sources)
list(APPEND _singleargs TARGET)
endif()
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS)
cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}")
if(NOT protobuf_generate_PROTOS AND NOT protobuf_generate_TARGET)
message(SEND_ERROR "Error: protobuf_generate called without any targets or source files")
return()
endif()
if(NOT protobuf_generate_OUT_VAR AND NOT protobuf_generate_TARGET)
message(SEND_ERROR "Error: protobuf_generate called without a target or output variable")
return()
endif()
if(NOT protobuf_generate_LANGUAGE)
set(protobuf_generate_LANGUAGE cpp)
endif()
string(TOLOWER ${protobuf_generate_LANGUAGE} protobuf_generate_LANGUAGE)
if(NOT protobuf_generate_PROTOC_OUT_DIR)
set(protobuf_generate_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif()
if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp)
set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}")
endif()
foreach(_option ${_dll_export_decl} ${protobuf_generate_PLUGIN_OPTIONS})
# append comma - not using CMake lists and string replacement as users
# might have semicolons in options
if(_plugin_options)
set( _plugin_options "${_plugin_options},")
endif()
set(_plugin_options "${_plugin_options}${_option}")
endforeach()
if(protobuf_generate_PLUGIN)
set(_plugin "--plugin=${protobuf_generate_PLUGIN}")
endif()
if(NOT protobuf_generate_GENERATE_EXTENSIONS)
if(protobuf_generate_LANGUAGE STREQUAL cpp)
set(protobuf_generate_GENERATE_EXTENSIONS .pb.h .pb.cc)
elseif(protobuf_generate_LANGUAGE STREQUAL python)
set(protobuf_generate_GENERATE_EXTENSIONS _pb2.py)
else()
message(SEND_ERROR "Error: protobuf_generate given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS")
return()
endif()
endif()
if(protobuf_generate_TARGET)
get_target_property(_source_list ${protobuf_generate_TARGET} SOURCES)
foreach(_file ${_source_list})
if(_file MATCHES "proto$")
list(APPEND protobuf_generate_PROTOS ${_file})
endif()
endforeach()
endif()
if(NOT protobuf_generate_PROTOS)
message(SEND_ERROR "Error: protobuf_generate could not find any .proto files")
return()
endif()
if(protobuf_generate_APPEND_PATH)
# Create an include path for each file specified
foreach(_file ${protobuf_generate_PROTOS})
get_filename_component(_abs_file ${_file} ABSOLUTE)
get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
list(FIND _protobuf_include_path ${_abs_dir} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${_abs_dir})
endif()
endforeach()
endif()
foreach(DIR ${protobuf_generate_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
if(NOT _protobuf_include_path)
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
set(_generated_srcs_all)
foreach(_proto ${protobuf_generate_PROTOS})
get_filename_component(_abs_file ${_proto} ABSOLUTE)
get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
get_filename_component(_file_full_name ${_proto} NAME)
string(FIND "${_file_full_name}" "." _file_last_ext_pos REVERSE)
string(SUBSTRING "${_file_full_name}" 0 ${_file_last_ext_pos} _basename)
set(_suitable_include_found FALSE)
foreach(DIR ${_protobuf_include_path})
if(NOT DIR STREQUAL "-I")
file(RELATIVE_PATH _rel_dir ${DIR} ${_abs_dir})
string(FIND "${_rel_dir}" "../" _is_in_parent_folder)
if (NOT ${_is_in_parent_folder} EQUAL 0)
set(_suitable_include_found TRUE)
break()
endif()
endif()
endforeach()
if(NOT _suitable_include_found)
message(SEND_ERROR "Error: protobuf_generate could not find any correct proto include directory.")
return()
endif()
set(_generated_srcs)
foreach(_ext ${protobuf_generate_GENERATE_EXTENSIONS})
list(APPEND _generated_srcs "${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}${_ext}")
endforeach()
list(APPEND _generated_srcs_all ${_generated_srcs})
set(_comment "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}")
if(protobuf_generate_PROTOC_OPTIONS)
set(_comment "${_comment}, protoc-options: ${protobuf_generate_PROTOC_OPTIONS}")
endif()
if(_plugin_options)
set(_comment "${_comment}, plugin-options: ${_plugin_options}")
endif()
add_custom_command(
OUTPUT ${_generated_srcs}
COMMAND protobuf::protoc
ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_plugin_options}:${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file}
DEPENDS ${_abs_file} protobuf::protoc ${protobuf_generate_DEPENDENCIES}
COMMENT ${_comment}
VERBATIM )
endforeach()
set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE)
if(protobuf_generate_OUT_VAR)
set(${protobuf_generate_OUT_VAR} ${_generated_srcs_all} PARENT_SCOPE)
endif()
if(protobuf_generate_TARGET)
target_sources(${protobuf_generate_TARGET} PRIVATE ${_generated_srcs_all})
endif()
endfunction()

View File

@@ -0,0 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
Name: Protocol Buffers
Description: Google's Data Interchange Format
Version: @protobuf_VERSION@
Libs: -L${libdir} -lprotobuf-lite @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir}
Conflicts: protobuf

View File

@@ -0,0 +1,189 @@
# This file contains backwards compatibility patches for various legacy functions and variables
# Functions
function(PROTOBUF_GENERATE_CPP SRCS HDRS)
cmake_parse_arguments(protobuf_generate_cpp "" "EXPORT_MACRO" "" ${ARGN})
set(_proto_files "${protobuf_generate_cpp_UNPARSED_ARGUMENTS}")
if(NOT _proto_files)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
return()
endif()
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
set(_append_arg APPEND_PATH)
endif()
if(DEFINED Protobuf_IMPORT_DIRS)
set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS})
endif()
set(_outvar)
protobuf_generate(${_append_arg} LANGUAGE cpp EXPORT_MACRO ${protobuf_generate_cpp_EXPORT_MACRO} OUT_VAR _outvar ${_import_arg} PROTOS ${_proto_files})
set(${SRCS})
set(${HDRS})
foreach(_file ${_outvar})
if(_file MATCHES "cc$")
list(APPEND ${SRCS} ${_file})
else()
list(APPEND ${HDRS} ${_file})
endif()
endforeach()
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()
function(PROTOBUF_GENERATE_PYTHON SRCS)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
return()
endif()
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
set(_append_arg APPEND_PATH)
endif()
if(DEFINED Protobuf_IMPORT_DIRS)
set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS})
endif()
set(_outvar)
protobuf_generate(${_append_arg} LANGUAGE python OUT_VAR _outvar ${_import_arg} PROTOS ${ARGN})
set(${SRCS} ${_outvar} PARENT_SCOPE)
endfunction()
# Environment
# Backwards compatibility
# Define camel case versions of input variables
foreach(UPPER
PROTOBUF_SRC_ROOT_FOLDER
PROTOBUF_IMPORT_DIRS
PROTOBUF_DEBUG
PROTOBUF_LIBRARY
PROTOBUF_PROTOC_LIBRARY
PROTOBUF_INCLUDE_DIR
PROTOBUF_PROTOC_EXECUTABLE
PROTOBUF_LIBRARY_DEBUG
PROTOBUF_PROTOC_LIBRARY_DEBUG
PROTOBUF_LITE_LIBRARY
PROTOBUF_LITE_LIBRARY_DEBUG
)
if (DEFINED ${UPPER})
string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER})
if (NOT DEFINED ${Camel})
set(${Camel} ${${UPPER}})
endif()
endif()
endforeach()
if(DEFINED Protobuf_SRC_ROOT_FOLDER)
message(AUTHOR_WARNING "Variable Protobuf_SRC_ROOT_FOLDER defined, but not"
" used in CONFIG mode")
endif()
include(SelectLibraryConfigurations)
# Internal function: search for normal library as well as a debug one
# if the debug one is specified also include debug/optimized keywords
# in *_LIBRARIES variable
function(_protobuf_find_libraries name filename)
if(${name}_LIBRARIES)
# Use result recorded by a previous call.
elseif(${name}_LIBRARY)
# Honor cache entry used by CMake 3.5 and lower.
set(${name}_LIBRARIES "${${name}_LIBRARY}" PARENT_SCOPE)
elseif(TARGET protobuf::lib${filename})
get_target_property(${name}_LIBRARY_RELEASE protobuf::lib${filename}
LOCATION_RELEASE)
get_target_property(${name}_LIBRARY_RELWITHDEBINFO protobuf::lib${filename}
LOCATION_RELWITHDEBINFO)
get_target_property(${name}_LIBRARY_MINSIZEREL protobuf::lib${filename}
LOCATION_MINSIZEREL)
get_target_property(${name}_LIBRARY_DEBUG protobuf::lib${filename}
LOCATION_DEBUG)
select_library_configurations(${name})
set(${name}_LIBRARY ${${name}_LIBRARY} PARENT_SCOPE)
set(${name}_LIBRARIES ${${name}_LIBRARIES} PARENT_SCOPE)
endif()
endfunction()
#
# Main.
#
# By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc
# for each directory where a proto file is referenced.
if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH)
set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE)
endif()
# The Protobuf library
_protobuf_find_libraries(Protobuf protobuf)
# The Protobuf Lite library
_protobuf_find_libraries(Protobuf_LITE protobuf-lite)
# The Protobuf Protoc Library
_protobuf_find_libraries(Protobuf_PROTOC protoc)
# Set the include directory
get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf
INTERFACE_INCLUDE_DIRECTORIES)
# Set the protoc Executable
if(NOT Protobuf_PROTOC_EXECUTABLE AND TARGET protobuf::protoc)
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
IMPORTED_LOCATION_RELEASE)
if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
IMPORTED_LOCATION_RELWITHDEBINFO)
endif()
if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
IMPORTED_LOCATION_MINSIZEREL)
endif()
if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
IMPORTED_LOCATION_DEBUG)
endif()
if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
IMPORTED_LOCATION_NOCONFIG)
endif()
endif()
# Version info variable
set(Protobuf_VERSION "@protobuf_VERSION@")
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Protobuf
REQUIRED_VARS Protobuf_PROTOC_EXECUTABLE Protobuf_LIBRARIES Protobuf_INCLUDE_DIRS
VERSION_VAR Protobuf_VERSION
)
# Backwards compatibility
# Define upper case versions of output variables
foreach(Camel
Protobuf_VERSION
Protobuf_SRC_ROOT_FOLDER
Protobuf_IMPORT_DIRS
Protobuf_DEBUG
Protobuf_INCLUDE_DIRS
Protobuf_LIBRARIES
Protobuf_PROTOC_LIBRARIES
Protobuf_LITE_LIBRARIES
Protobuf_LIBRARY
Protobuf_PROTOC_LIBRARY
Protobuf_INCLUDE_DIR
Protobuf_PROTOC_EXECUTABLE
Protobuf_LIBRARY_DEBUG
Protobuf_PROTOC_LIBRARY_DEBUG
Protobuf_LITE_LIBRARY
Protobuf_LITE_LIBRARY_DEBUG
)
string(TOUPPER ${Camel} UPPER)
set(${UPPER} ${${Camel}})
endforeach()

View File

@@ -0,0 +1,7 @@
# Verbose output
option(protobuf_VERBOSE "Enable for verbose output" OFF)
mark_as_advanced(protobuf_VERBOSE)
# FindProtobuf module compatible
option(protobuf_MODULE_COMPATIBLE "CMake built-in FindProtobuf.cmake module compatible" OFF)
mark_as_advanced(protobuf_MODULE_COMPATIBLE)

11
cmake/protobuf.pc.cmake Normal file
View File

@@ -0,0 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
Name: Protocol Buffers
Description: Google's Data Interchange Format
Version: @protobuf_VERSION@
Libs: -L${libdir} -lprotobuf @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir}
Conflicts: protobuf-lite

14
cmake/protoc.cmake Normal file
View File

@@ -0,0 +1,14 @@
set(protoc_files
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/main.cc
)
add_executable(protoc ${protoc_files} ${protobuf_version_rc_file})
target_link_libraries(protoc
libprotoc
libprotobuf
${protobuf_ABSL_USED_TARGETS}
)
add_executable(protobuf::protoc ALIAS protoc)
set_target_properties(protoc PROPERTIES
VERSION ${protobuf_VERSION})

41
cmake/push_auto_update.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
# This script updates the CMake file lists (i.e. src/file_lists.cmake), commits
# the resulting change, and pushes it. This does not do anything useful when
# run manually, but should be run by our GitHub action instead.
set -ex
# Exit early if the previous commit was made by the bot. This reduces the risk
# of a bug causing an infinite loop of auto-generated commits.
if (git log -1 --pretty=format:'%an' | grep -q "Protobuf Team Bot"); then
echo "Previous commit was authored by bot"
exit 0
fi
$(dirname -- "$0")/update_file_lists.sh
# Try to determine the most recent pull request number.
title=$(git log -1 --pretty='%s')
pr_from_merge=$(echo "$title" | sed -n 's/^Merge pull request #\([0-9]\+\).*/\1/p')
pr_from_squash=$(echo "$title" | sed -n 's/^.*(#\([0-9]\+\))$/\1/p')
pr=""
if [ ! -z "$pr_from_merge" ]; then
pr="$pr_from_merge"
elif [ ! -z "$pr_from_squash" ]; then
pr="$pr_from_squash"
fi
if [ ! -z "$pr" ]; then
commit_message="Auto-generate CMake file lists after PR #$pr"
else
# If we are unable to determine the pull request number, we fall back on this
# default commit message. Typically this should not occur, but could happen
# if a pull request was merged via a rebase.
commit_message="Auto-generate CMake file lists"
fi
git add -A
git diff --staged --quiet || git commit -am "$commit_message"
git push

209
cmake/tests.cmake Normal file
View File

@@ -0,0 +1,209 @@
option(protobuf_USE_EXTERNAL_GTEST "Use external Google Test (i.e. not the one in third_party/googletest)" OFF)
option(protobuf_REMOVE_INSTALLED_HEADERS
"Remove local headers so that installed ones are used instead" OFF)
option(protobuf_ABSOLUTE_TEST_PLUGIN_PATH
"Using absolute test_plugin path in tests" ON)
mark_as_advanced(protobuf_ABSOLUTE_TEST_PLUGIN_PATH)
if (protobuf_USE_EXTERNAL_GTEST)
find_package(GTest REQUIRED)
else()
if (NOT EXISTS "${protobuf_SOURCE_DIR}/third_party/googletest/CMakeLists.txt")
message(FATAL_ERROR
"Cannot find third_party/googletest directory that's needed to "
"build tests. If you use git, make sure you have cloned submodules:\n"
" git submodule update --init --recursive\n"
"If instead you want to skip tests, run cmake with:\n"
" cmake -Dprotobuf_BUILD_TESTS=OFF\n")
endif()
set(googlemock_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googlemock")
set(googletest_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googletest")
include_directories(
${googlemock_source_dir}
${googletest_source_dir}
${googletest_source_dir}/include
${googlemock_source_dir}/include
)
add_library(gmock STATIC
"${googlemock_source_dir}/src/gmock-all.cc"
"${googletest_source_dir}/src/gtest-all.cc"
)
target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT})
add_library(gmock_main STATIC "${googlemock_source_dir}/src/gmock_main.cc")
target_link_libraries(gmock_main gmock)
add_library(GTest::gmock ALIAS gmock)
add_library(GTest::gmock_main ALIAS gmock_main)
endif()
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
set(lite_test_protos
${protobuf_lite_test_protos_files}
)
set(tests_protos
${protobuf_test_protos_files}
${compiler_test_protos_files}
${util_test_protos_files}
)
macro(compile_proto_file filename)
string(REPLACE .proto .pb.h pb_hdr ${filename})
string(REPLACE .proto .pb.cc pb_src ${filename})
add_custom_command(
OUTPUT ${pb_hdr} ${pb_src}
DEPENDS ${protobuf_PROTOC_EXE} ${filename}
COMMAND ${protobuf_PROTOC_EXE} ${filename}
--proto_path=${protobuf_SOURCE_DIR}/src
--cpp_out=${protobuf_SOURCE_DIR}/src
--experimental_allow_proto3_optional
)
endmacro(compile_proto_file)
set(lite_test_proto_files)
foreach(proto_file ${lite_test_protos})
compile_proto_file(${proto_file})
set(lite_test_proto_files ${lite_test_proto_files} ${pb_src} ${pb_hdr})
endforeach(proto_file)
set(tests_proto_files)
foreach(proto_file ${tests_protos})
compile_proto_file(${proto_file})
set(tests_proto_files ${tests_proto_files} ${pb_src} ${pb_hdr})
endforeach(proto_file)
add_library(protobuf-lite-test-common STATIC
${lite_test_util_srcs} ${lite_test_proto_files})
target_include_directories(protobuf-lite-test-common PRIVATE ${ABSL_ROOT_DIR})
target_link_libraries(protobuf-lite-test-common
${protobuf_LIB_PROTOBUF_LITE} ${protobuf_ABSL_USED_TARGETS} GTest::gmock)
set(common_test_files
${test_util_hdrs}
${test_util_srcs}
${common_test_hdrs}
${common_test_srcs}
)
add_library(protobuf-test-common STATIC
${common_test_files} ${tests_proto_files})
target_include_directories(protobuf-test-common PRIVATE ${ABSL_ROOT_DIR})
target_link_libraries(protobuf-test-common
${protobuf_LIB_PROTOBUF} ${protobuf_ABSL_USED_TARGETS} GTest::gmock)
set(tests_files
${protobuf_test_files}
${compiler_test_files}
${annotation_test_util_srcs}
${io_test_files}
${util_test_files}
${stubs_test_files}
)
if(protobuf_ABSOLUTE_TEST_PLUGIN_PATH)
add_compile_options(-DGOOGLE_PROTOBUF_TEST_PLUGIN_PATH="$<TARGET_FILE:test_plugin>")
endif()
if(MINGW)
set_source_files_properties(${tests_files} PROPERTIES COMPILE_FLAGS "-Wno-narrowing")
# required for tests on MinGW Win64
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--stack,16777216")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj")
endif()
endif()
if(protobuf_TEST_XML_OUTDIR)
if(NOT "${protobuf_TEST_XML_OUTDIR}" MATCHES "[/\\]$")
string(APPEND protobuf_TEST_XML_OUTDIR "/")
endif()
set(protobuf_GTEST_ARGS "--gtest_output=xml:${protobuf_TEST_XML_OUTDIR}")
else()
set(protobuf_GTEST_ARGS)
endif()
add_executable(tests ${tests_files})
if (MSVC)
target_compile_options(tests PRIVATE
/wd4146 # unary minus operator applied to unsigned type, result still unsigned
)
endif()
target_link_libraries(tests protobuf-lite-test-common protobuf-test-common ${protobuf_LIB_PROTOC} ${protobuf_LIB_PROTOBUF} GTest::gmock_main)
set(test_plugin_files
${test_plugin_files}
${common_test_hdrs}
${common_test_srcs}
)
add_executable(test_plugin ${test_plugin_files})
target_include_directories(test_plugin PRIVATE ${ABSL_ROOT_DIR})
target_link_libraries(test_plugin
${protobuf_LIB_PROTOC}
${protobuf_LIB_PROTOBUF}
${protobuf_ABSL_USED_TARGETS}
GTest::gmock
)
add_executable(lite-test ${protobuf_lite_test_files})
target_link_libraries(lite-test protobuf-lite-test-common ${protobuf_LIB_PROTOBUF_LITE} GTest::gmock_main)
add_test(NAME lite-test
COMMAND lite-test ${protobuf_GTEST_ARGS})
add_custom_target(check
COMMAND tests
DEPENDS tests lite-test test_plugin
WORKING_DIRECTORY ${protobuf_SOURCE_DIR})
add_test(NAME check
COMMAND tests ${protobuf_GTEST_ARGS})
# For test purposes, remove headers that should already be installed. This
# prevents accidental conflicts and also version skew (since local headers take
# precedence over installed headers).
add_custom_target(save-installed-headers)
add_custom_target(remove-installed-headers)
add_custom_target(restore-installed-headers)
file(GLOB_RECURSE _local_hdrs
"${PROJECT_SOURCE_DIR}/src/*.h"
"${PROJECT_SOURCE_DIR}/src/*.inc")
# Exclude the bootstrapping that are directly used by tests.
set(_exclude_hdrs
"${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.pb.h"
"${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h")
# Exclude test library headers.
list(APPEND _exclude_hdrs ${test_util_hdrs} ${lite_test_util_hdrs} ${common_test_hdrs}
${compiler_test_utils_hdrs})
foreach(_hdr ${_exclude_hdrs})
list(REMOVE_ITEM _local_hdrs ${_hdr})
endforeach()
foreach(_hdr ${_local_hdrs})
string(REPLACE "${protobuf_SOURCE_DIR}/src" "" _file ${_hdr})
set(_tmp_file "${CMAKE_BINARY_DIR}/tmp-install-test/${_file}")
add_custom_command(TARGET remove-installed-headers PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E remove -f "${_hdr}")
add_custom_command(TARGET save-installed-headers PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E
copy "${_hdr}" "${_tmp_file}" || true)
add_custom_command(TARGET restore-installed-headers PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E
copy "${_tmp_file}" "${_hdr}")
endforeach()
add_dependencies(remove-installed-headers save-installed-headers)
if(protobuf_REMOVE_INSTALLED_HEADERS)
# Make sure we remove all the headers *before* any codegen occurs.
add_dependencies(${protobuf_PROTOC_EXE} remove-installed-headers)
endif()

8
cmake/update_file_lists.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash -u
# This script generates file lists from Bazel for CMake.
set -e
bazel build //pkg:gen_src_file_lists
cp -v bazel-bin/pkg/src_file_lists.cmake src/file_lists.cmake

45
cmake/version.rc.in Normal file
View File

@@ -0,0 +1,45 @@
#define VS_FF_DEBUG 0x1L
#define VS_VERSION_INFO 0x1L
#define VS_FFI_FILEFLAGSMASK 0x17L
#define VER_PRIVATEBUILD 0x0L
#define VER_PRERELEASE 0x0L
#define VOS__WINDOWS32 0x4L
#define VFT_DLL 0x2L
#define VFT2_UNKNOWN 0x0L
#ifndef DEBUG
#define VER_DEBUG 0
#else
#define VER_DEBUG VS_FF_DEBUG
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION @protobuf_RC_FILEVERSION@
PRODUCTVERSION @protobuf_RC_FILEVERSION@
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS VER_DEBUG
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
BEGIN
BLOCK "VarFileInfo"
BEGIN
// English language (0x409) and the Windows Unicode codepage (1200)
VALUE "Translation", 0x409, 1200
END
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Compiled with @CMAKE_CXX_COMPILER_ID@ @CMAKE_CXX_COMPILER_VERSION@\0"
VALUE "ProductVersion", "@protobuf_VERSION@\0"
VALUE "FileVersion", "@protobuf_VERSION@\0"
VALUE "InternalName", "protobuf\0"
VALUE "ProductName", "Protocol Buffers - Google's Data Interchange Format\0"
VALUE "CompanyName", "Google Inc.\0"
VALUE "LegalCopyright", "Copyright 2008 Google Inc. All rights reserved.\0"
VALUE "Licence", "BSD\0"
VALUE "Info", "https://developers.google.com/protocol-buffers/\0"
END
END
END