dep-protobuf/cmake/install.cmake

200 lines
7.8 KiB
CMake
Raw Normal View History

2015-08-22 18:25:48 -07:00
include(GNUInstallDirs)
foreach(_target IN LISTS protobuf_ABSL_USED_TARGETS)
# shared abseil on windows breaks the absl::foo -> absl_foo replacement logic -
# preempt this by a more specific replace (harmless if it doesn't apply); see GH-15883
string(REPLACE "absl::abseil_dll" "abseil_dll" _modified_target ${_target})
string(REPLACE :: _ _modified_target ${_modified_target})
list(APPEND _pc_targets ${_modified_target})
endforeach()
list(APPEND _pc_targets "utf8_range")
set(_protobuf_PC_REQUIRES "")
set(_sep "")
foreach (_target IN LISTS _pc_targets)
string(CONCAT _protobuf_PC_REQUIRES "${_protobuf_PC_REQUIRES}" "${_sep}" "${_target}")
set(_sep " ")
endforeach ()
set(_protobuf_PC_CFLAGS)
if (protobuf_BUILD_SHARED_LIBS)
set(_protobuf_PC_CFLAGS -DPROTOBUF_USE_DLLS)
endif ()
if(CMAKE_BUILD_TYPE STREQUAL Debug)
# attach debug postfix only in debug mode
set(protobuf_LIBRARY_POSTFIX ${protobuf_DEBUG_POSTFIX})
endif()
cmake: support narrowly constrained lite-only runtime builds (#27407) ## Summary Implements the narrowly constrained lite-only runtime build discussed in #27231. This adds one new CMake option: ```cmake option(protobuf_BUILD_LIBPROTOBUF "Build libprotobuf" ON) ``` The default behavior remains unchanged. With defaults, Protobuf still builds and installs both `libprotobuf-lite` and `libprotobuf`. When `protobuf_BUILD_LIBPROTOBUF=OFF`, the build is only accepted in a strict target-side lite-only configuration: - `protobuf_BUILD_PROTOC_BINARIES=OFF` - `protobuf_BUILD_LIBPROTOC=OFF` - `protobuf_BUILD_LIBUPB=OFF` - `protobuf_BUILD_TESTS=OFF` - `protobuf_BUILD_CONFORMANCE=OFF` - `protobuf_BUILD_EXAMPLES=OFF` In that mode, CMake still builds, installs, and exports `protobuf::libprotobuf-lite`, but does not build/install/export `protobuf::libprotobuf`, `libprotoc`, `protoc`, or `libupb`. ## Motivation Some downstream/package-manager workflows use host `protoc` for code generation while the target package only needs the lite C++ runtime. For example, generated C++ sources may use: ```proto option optimize_for = LITE_RUNTIME; ``` and the target consumer only links: ```cmake target_link_libraries(app PRIVATE protobuf::libprotobuf-lite) ``` This PR does not try to support every possible CMake combination. It only adds a strict lite-only target-runtime mode where the full runtime and compiler-side artifacts are explicitly disabled. ## Scope This PR intentionally does not: - change Bazel; - change C++ runtime sources; - prune installed headers; - add `protobuf_BUILD_LIBPROTOBUF_LITE`; - add telemetry/devtools/docs from the local PoC; - support full-runtime consumers in lite-only mode; - support `protoc`, `libprotoc`, tests, conformance, examples, or `libupb` when `protobuf_BUILD_LIBPROTOBUF=OFF`. CONFIG mode is the primary validated contract: ```cmake find_package(protobuf CONFIG REQUIRED) target_link_libraries(app PRIVATE protobuf::libprotobuf-lite) ``` ## Implementation notes ### `CMakeLists.txt` - Adds `protobuf_BUILD_LIBPROTOBUF`, defaulting to `ON`. - Keeps `libprotobuf-lite` included whenever `protobuf_BUILD_PROTOBUF_BINARIES=ON`. - Includes `libprotobuf.cmake` only when `protobuf_BUILD_LIBPROTOBUF=ON`. - Rejects unsupported lite-only combinations with explicit `FATAL_ERROR` messages. ### `cmake/install.cmake` - Installs/exports only targets that actually exist. - Generates/installs `protobuf-lite.pc` only when `libprotobuf-lite` exists. - Generates/installs `protobuf.pc` only when `libprotobuf` exists. - Generates/installs `upb.pc` only when `libupb` exists. ## Validation Validated locally on Windows/MSVC. ### Default build ```powershell cmake -S . -B build-default -Dprotobuf_BUILD_TESTS=OFF cmake --build build-default --config Release --parallel 1 cmake --install build-default --config Release --prefix install-default ``` Default install contained: - `libprotobuf` - `libprotobuf-lite` - `libprotoc` - `protoc` - `libupb` - `protobuf.pc` - `protobuf-lite.pc` - `upb.pc` ### Lite-only build ```powershell cmake -S . -B build-lite-only ` -Dprotobuf_BUILD_TESTS=OFF ` -Dprotobuf_BUILD_CONFORMANCE=OFF ` -Dprotobuf_BUILD_EXAMPLES=OFF ` -Dprotobuf_BUILD_PROTOC_BINARIES=OFF ` -Dprotobuf_BUILD_LIBPROTOC=OFF ` -Dprotobuf_BUILD_LIBUPB=OFF ` -Dprotobuf_BUILD_LIBPROTOBUF=OFF cmake --build build-lite-only --config Release --parallel 1 cmake --install build-lite-only --config Release --prefix install-lite-only ``` Lite-only install contained: - `libprotobuf-lite` - `protobuf-lite.pc` Lite-only install did not contain: - `libprotobuf` - `libprotoc` - `protoc` - `libupb` - `protobuf.pc` ### CONFIG consumer A minimal external consumer passed with: ```cmake find_package(protobuf CONFIG REQUIRED) if(NOT TARGET protobuf::libprotobuf-lite) message(FATAL_ERROR "protobuf::libprotobuf-lite was not exported") endif() if(TARGET protobuf::libprotobuf) message(FATAL_ERROR "protobuf::libprotobuf should not exist in lite-only install") endif() add_executable(protobuf_lite_consumer main.cc) target_link_libraries(protobuf_lite_consumer PRIVATE protobuf::libprotobuf-lite) ``` The consumer included: ```cpp #include <google/protobuf/message_lite.h> #include <google/protobuf/stubs/common.h> int main() { google::protobuf::ShutdownProtobufLibrary(); return 0; } ``` ### Invalid configuration checks All expected invalid combinations failed at configure time with clear `FATAL_ERROR` messages: - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_PROTOC_BINARIES=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_TESTS=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_CONFORMANCE=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_EXAMPLES=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_LIBUPB=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_LIBPROTOC=ON` ## Local PoC measurements The earlier local PoC measured the following on Windows/MSVC: | Variant | Configure | Build | Install | Install size | |---|---:|---:|---:|---:| | Default | 21.299s | 508.063s | 7.699s | 113754 KB | | Lite-only | 49.902s | 55.648s | 4.363s | 21579 KB | The lite-only configure step was slower in that local run, but the build step dominated the total time and dropped from `508.063s` to `55.648s`. ## Related Resolves #27231 Closes #27407 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/27407 from dudantas:dudantas/cmake-lite-only-runtime-pr 2c146c1aacb7453c61895898ef1ab660b9149294 PiperOrigin-RevId: 925038366
2026-06-01 19:01:31 -07:00
if (TARGET libprotobuf)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf.pc.cmake
${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc @ONLY)
endif ()
if (TARGET libprotobuf-lite)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf-lite.pc.cmake
${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc @ONLY)
endif ()
if (TARGET libupb)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/upb.pc.cmake
${CMAKE_CURRENT_BINARY_DIR}/upb.pc @ONLY)
endif ()
cmake: support narrowly constrained lite-only runtime builds (#27407) ## Summary Implements the narrowly constrained lite-only runtime build discussed in #27231. This adds one new CMake option: ```cmake option(protobuf_BUILD_LIBPROTOBUF "Build libprotobuf" ON) ``` The default behavior remains unchanged. With defaults, Protobuf still builds and installs both `libprotobuf-lite` and `libprotobuf`. When `protobuf_BUILD_LIBPROTOBUF=OFF`, the build is only accepted in a strict target-side lite-only configuration: - `protobuf_BUILD_PROTOC_BINARIES=OFF` - `protobuf_BUILD_LIBPROTOC=OFF` - `protobuf_BUILD_LIBUPB=OFF` - `protobuf_BUILD_TESTS=OFF` - `protobuf_BUILD_CONFORMANCE=OFF` - `protobuf_BUILD_EXAMPLES=OFF` In that mode, CMake still builds, installs, and exports `protobuf::libprotobuf-lite`, but does not build/install/export `protobuf::libprotobuf`, `libprotoc`, `protoc`, or `libupb`. ## Motivation Some downstream/package-manager workflows use host `protoc` for code generation while the target package only needs the lite C++ runtime. For example, generated C++ sources may use: ```proto option optimize_for = LITE_RUNTIME; ``` and the target consumer only links: ```cmake target_link_libraries(app PRIVATE protobuf::libprotobuf-lite) ``` This PR does not try to support every possible CMake combination. It only adds a strict lite-only target-runtime mode where the full runtime and compiler-side artifacts are explicitly disabled. ## Scope This PR intentionally does not: - change Bazel; - change C++ runtime sources; - prune installed headers; - add `protobuf_BUILD_LIBPROTOBUF_LITE`; - add telemetry/devtools/docs from the local PoC; - support full-runtime consumers in lite-only mode; - support `protoc`, `libprotoc`, tests, conformance, examples, or `libupb` when `protobuf_BUILD_LIBPROTOBUF=OFF`. CONFIG mode is the primary validated contract: ```cmake find_package(protobuf CONFIG REQUIRED) target_link_libraries(app PRIVATE protobuf::libprotobuf-lite) ``` ## Implementation notes ### `CMakeLists.txt` - Adds `protobuf_BUILD_LIBPROTOBUF`, defaulting to `ON`. - Keeps `libprotobuf-lite` included whenever `protobuf_BUILD_PROTOBUF_BINARIES=ON`. - Includes `libprotobuf.cmake` only when `protobuf_BUILD_LIBPROTOBUF=ON`. - Rejects unsupported lite-only combinations with explicit `FATAL_ERROR` messages. ### `cmake/install.cmake` - Installs/exports only targets that actually exist. - Generates/installs `protobuf-lite.pc` only when `libprotobuf-lite` exists. - Generates/installs `protobuf.pc` only when `libprotobuf` exists. - Generates/installs `upb.pc` only when `libupb` exists. ## Validation Validated locally on Windows/MSVC. ### Default build ```powershell cmake -S . -B build-default -Dprotobuf_BUILD_TESTS=OFF cmake --build build-default --config Release --parallel 1 cmake --install build-default --config Release --prefix install-default ``` Default install contained: - `libprotobuf` - `libprotobuf-lite` - `libprotoc` - `protoc` - `libupb` - `protobuf.pc` - `protobuf-lite.pc` - `upb.pc` ### Lite-only build ```powershell cmake -S . -B build-lite-only ` -Dprotobuf_BUILD_TESTS=OFF ` -Dprotobuf_BUILD_CONFORMANCE=OFF ` -Dprotobuf_BUILD_EXAMPLES=OFF ` -Dprotobuf_BUILD_PROTOC_BINARIES=OFF ` -Dprotobuf_BUILD_LIBPROTOC=OFF ` -Dprotobuf_BUILD_LIBUPB=OFF ` -Dprotobuf_BUILD_LIBPROTOBUF=OFF cmake --build build-lite-only --config Release --parallel 1 cmake --install build-lite-only --config Release --prefix install-lite-only ``` Lite-only install contained: - `libprotobuf-lite` - `protobuf-lite.pc` Lite-only install did not contain: - `libprotobuf` - `libprotoc` - `protoc` - `libupb` - `protobuf.pc` ### CONFIG consumer A minimal external consumer passed with: ```cmake find_package(protobuf CONFIG REQUIRED) if(NOT TARGET protobuf::libprotobuf-lite) message(FATAL_ERROR "protobuf::libprotobuf-lite was not exported") endif() if(TARGET protobuf::libprotobuf) message(FATAL_ERROR "protobuf::libprotobuf should not exist in lite-only install") endif() add_executable(protobuf_lite_consumer main.cc) target_link_libraries(protobuf_lite_consumer PRIVATE protobuf::libprotobuf-lite) ``` The consumer included: ```cpp #include <google/protobuf/message_lite.h> #include <google/protobuf/stubs/common.h> int main() { google::protobuf::ShutdownProtobufLibrary(); return 0; } ``` ### Invalid configuration checks All expected invalid combinations failed at configure time with clear `FATAL_ERROR` messages: - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_PROTOC_BINARIES=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_TESTS=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_CONFORMANCE=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_EXAMPLES=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_LIBUPB=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_LIBPROTOC=ON` ## Local PoC measurements The earlier local PoC measured the following on Windows/MSVC: | Variant | Configure | Build | Install | Install size | |---|---:|---:|---:|---:| | Default | 21.299s | 508.063s | 7.699s | 113754 KB | | Lite-only | 49.902s | 55.648s | 4.363s | 21579 KB | The lite-only configure step was slower in that local run, but the build step dominated the total time and dropped from `508.063s` to `55.648s`. ## Related Resolves #27231 Closes #27407 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/27407 from dudantas:dudantas/cmake-lite-only-runtime-pr 2c146c1aacb7453c61895898ef1ab660b9149294 PiperOrigin-RevId: 925038366
2026-06-01 19:01:31 -07:00
set(_protobuf_libraries)
foreach (_library libprotobuf-lite libprotobuf libprotoc libupb)
if (TARGET ${_library})
list(APPEND _protobuf_libraries ${_library})
endif()
endforeach()
foreach(_library ${_protobuf_libraries})
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()
2015-08-22 18:25:48 -07:00
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)
set(_protobuf_binaries protoc)
install(TARGETS protoc EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
if (protobuf_BUILD_LIBUPB)
foreach (generator upb upbdefs upb_minitable)
list(APPEND _protobuf_binaries protoc-gen-${generator})
install(TARGETS protoc-gen-${generator} EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT upb-generators
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT upb-generators)
endforeach ()
endif ()
foreach (binary IN LISTS _protobuf_binaries)
if (UNIX AND NOT APPLE)
set_property(TARGET ${binary}
PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
elseif (APPLE)
set_property(TARGET ${binary}
PROPERTY INSTALL_RPATH "@loader_path/../lib")
endif ()
endforeach ()
cmake: support narrowly constrained lite-only runtime builds (#27407) ## Summary Implements the narrowly constrained lite-only runtime build discussed in #27231. This adds one new CMake option: ```cmake option(protobuf_BUILD_LIBPROTOBUF "Build libprotobuf" ON) ``` The default behavior remains unchanged. With defaults, Protobuf still builds and installs both `libprotobuf-lite` and `libprotobuf`. When `protobuf_BUILD_LIBPROTOBUF=OFF`, the build is only accepted in a strict target-side lite-only configuration: - `protobuf_BUILD_PROTOC_BINARIES=OFF` - `protobuf_BUILD_LIBPROTOC=OFF` - `protobuf_BUILD_LIBUPB=OFF` - `protobuf_BUILD_TESTS=OFF` - `protobuf_BUILD_CONFORMANCE=OFF` - `protobuf_BUILD_EXAMPLES=OFF` In that mode, CMake still builds, installs, and exports `protobuf::libprotobuf-lite`, but does not build/install/export `protobuf::libprotobuf`, `libprotoc`, `protoc`, or `libupb`. ## Motivation Some downstream/package-manager workflows use host `protoc` for code generation while the target package only needs the lite C++ runtime. For example, generated C++ sources may use: ```proto option optimize_for = LITE_RUNTIME; ``` and the target consumer only links: ```cmake target_link_libraries(app PRIVATE protobuf::libprotobuf-lite) ``` This PR does not try to support every possible CMake combination. It only adds a strict lite-only target-runtime mode where the full runtime and compiler-side artifacts are explicitly disabled. ## Scope This PR intentionally does not: - change Bazel; - change C++ runtime sources; - prune installed headers; - add `protobuf_BUILD_LIBPROTOBUF_LITE`; - add telemetry/devtools/docs from the local PoC; - support full-runtime consumers in lite-only mode; - support `protoc`, `libprotoc`, tests, conformance, examples, or `libupb` when `protobuf_BUILD_LIBPROTOBUF=OFF`. CONFIG mode is the primary validated contract: ```cmake find_package(protobuf CONFIG REQUIRED) target_link_libraries(app PRIVATE protobuf::libprotobuf-lite) ``` ## Implementation notes ### `CMakeLists.txt` - Adds `protobuf_BUILD_LIBPROTOBUF`, defaulting to `ON`. - Keeps `libprotobuf-lite` included whenever `protobuf_BUILD_PROTOBUF_BINARIES=ON`. - Includes `libprotobuf.cmake` only when `protobuf_BUILD_LIBPROTOBUF=ON`. - Rejects unsupported lite-only combinations with explicit `FATAL_ERROR` messages. ### `cmake/install.cmake` - Installs/exports only targets that actually exist. - Generates/installs `protobuf-lite.pc` only when `libprotobuf-lite` exists. - Generates/installs `protobuf.pc` only when `libprotobuf` exists. - Generates/installs `upb.pc` only when `libupb` exists. ## Validation Validated locally on Windows/MSVC. ### Default build ```powershell cmake -S . -B build-default -Dprotobuf_BUILD_TESTS=OFF cmake --build build-default --config Release --parallel 1 cmake --install build-default --config Release --prefix install-default ``` Default install contained: - `libprotobuf` - `libprotobuf-lite` - `libprotoc` - `protoc` - `libupb` - `protobuf.pc` - `protobuf-lite.pc` - `upb.pc` ### Lite-only build ```powershell cmake -S . -B build-lite-only ` -Dprotobuf_BUILD_TESTS=OFF ` -Dprotobuf_BUILD_CONFORMANCE=OFF ` -Dprotobuf_BUILD_EXAMPLES=OFF ` -Dprotobuf_BUILD_PROTOC_BINARIES=OFF ` -Dprotobuf_BUILD_LIBPROTOC=OFF ` -Dprotobuf_BUILD_LIBUPB=OFF ` -Dprotobuf_BUILD_LIBPROTOBUF=OFF cmake --build build-lite-only --config Release --parallel 1 cmake --install build-lite-only --config Release --prefix install-lite-only ``` Lite-only install contained: - `libprotobuf-lite` - `protobuf-lite.pc` Lite-only install did not contain: - `libprotobuf` - `libprotoc` - `protoc` - `libupb` - `protobuf.pc` ### CONFIG consumer A minimal external consumer passed with: ```cmake find_package(protobuf CONFIG REQUIRED) if(NOT TARGET protobuf::libprotobuf-lite) message(FATAL_ERROR "protobuf::libprotobuf-lite was not exported") endif() if(TARGET protobuf::libprotobuf) message(FATAL_ERROR "protobuf::libprotobuf should not exist in lite-only install") endif() add_executable(protobuf_lite_consumer main.cc) target_link_libraries(protobuf_lite_consumer PRIVATE protobuf::libprotobuf-lite) ``` The consumer included: ```cpp #include <google/protobuf/message_lite.h> #include <google/protobuf/stubs/common.h> int main() { google::protobuf::ShutdownProtobufLibrary(); return 0; } ``` ### Invalid configuration checks All expected invalid combinations failed at configure time with clear `FATAL_ERROR` messages: - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_PROTOC_BINARIES=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_TESTS=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_CONFORMANCE=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_EXAMPLES=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_LIBUPB=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_LIBPROTOC=ON` ## Local PoC measurements The earlier local PoC measured the following on Windows/MSVC: | Variant | Configure | Build | Install | Install size | |---|---:|---:|---:|---:| | Default | 21.299s | 508.063s | 7.699s | 113754 KB | | Lite-only | 49.902s | 55.648s | 4.363s | 21579 KB | The lite-only configure step was slower in that local run, but the build step dominated the total time and dropped from `508.063s` to `55.648s`. ## Related Resolves #27231 Closes #27407 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/27407 from dudantas:dudantas/cmake-lite-only-runtime-pr 2c146c1aacb7453c61895898ef1ab660b9149294 PiperOrigin-RevId: 925038366
2026-06-01 19:01:31 -07:00
endif ()
2015-08-22 18:25:48 -07:00
cmake: support narrowly constrained lite-only runtime builds (#27407) ## Summary Implements the narrowly constrained lite-only runtime build discussed in #27231. This adds one new CMake option: ```cmake option(protobuf_BUILD_LIBPROTOBUF "Build libprotobuf" ON) ``` The default behavior remains unchanged. With defaults, Protobuf still builds and installs both `libprotobuf-lite` and `libprotobuf`. When `protobuf_BUILD_LIBPROTOBUF=OFF`, the build is only accepted in a strict target-side lite-only configuration: - `protobuf_BUILD_PROTOC_BINARIES=OFF` - `protobuf_BUILD_LIBPROTOC=OFF` - `protobuf_BUILD_LIBUPB=OFF` - `protobuf_BUILD_TESTS=OFF` - `protobuf_BUILD_CONFORMANCE=OFF` - `protobuf_BUILD_EXAMPLES=OFF` In that mode, CMake still builds, installs, and exports `protobuf::libprotobuf-lite`, but does not build/install/export `protobuf::libprotobuf`, `libprotoc`, `protoc`, or `libupb`. ## Motivation Some downstream/package-manager workflows use host `protoc` for code generation while the target package only needs the lite C++ runtime. For example, generated C++ sources may use: ```proto option optimize_for = LITE_RUNTIME; ``` and the target consumer only links: ```cmake target_link_libraries(app PRIVATE protobuf::libprotobuf-lite) ``` This PR does not try to support every possible CMake combination. It only adds a strict lite-only target-runtime mode where the full runtime and compiler-side artifacts are explicitly disabled. ## Scope This PR intentionally does not: - change Bazel; - change C++ runtime sources; - prune installed headers; - add `protobuf_BUILD_LIBPROTOBUF_LITE`; - add telemetry/devtools/docs from the local PoC; - support full-runtime consumers in lite-only mode; - support `protoc`, `libprotoc`, tests, conformance, examples, or `libupb` when `protobuf_BUILD_LIBPROTOBUF=OFF`. CONFIG mode is the primary validated contract: ```cmake find_package(protobuf CONFIG REQUIRED) target_link_libraries(app PRIVATE protobuf::libprotobuf-lite) ``` ## Implementation notes ### `CMakeLists.txt` - Adds `protobuf_BUILD_LIBPROTOBUF`, defaulting to `ON`. - Keeps `libprotobuf-lite` included whenever `protobuf_BUILD_PROTOBUF_BINARIES=ON`. - Includes `libprotobuf.cmake` only when `protobuf_BUILD_LIBPROTOBUF=ON`. - Rejects unsupported lite-only combinations with explicit `FATAL_ERROR` messages. ### `cmake/install.cmake` - Installs/exports only targets that actually exist. - Generates/installs `protobuf-lite.pc` only when `libprotobuf-lite` exists. - Generates/installs `protobuf.pc` only when `libprotobuf` exists. - Generates/installs `upb.pc` only when `libupb` exists. ## Validation Validated locally on Windows/MSVC. ### Default build ```powershell cmake -S . -B build-default -Dprotobuf_BUILD_TESTS=OFF cmake --build build-default --config Release --parallel 1 cmake --install build-default --config Release --prefix install-default ``` Default install contained: - `libprotobuf` - `libprotobuf-lite` - `libprotoc` - `protoc` - `libupb` - `protobuf.pc` - `protobuf-lite.pc` - `upb.pc` ### Lite-only build ```powershell cmake -S . -B build-lite-only ` -Dprotobuf_BUILD_TESTS=OFF ` -Dprotobuf_BUILD_CONFORMANCE=OFF ` -Dprotobuf_BUILD_EXAMPLES=OFF ` -Dprotobuf_BUILD_PROTOC_BINARIES=OFF ` -Dprotobuf_BUILD_LIBPROTOC=OFF ` -Dprotobuf_BUILD_LIBUPB=OFF ` -Dprotobuf_BUILD_LIBPROTOBUF=OFF cmake --build build-lite-only --config Release --parallel 1 cmake --install build-lite-only --config Release --prefix install-lite-only ``` Lite-only install contained: - `libprotobuf-lite` - `protobuf-lite.pc` Lite-only install did not contain: - `libprotobuf` - `libprotoc` - `protoc` - `libupb` - `protobuf.pc` ### CONFIG consumer A minimal external consumer passed with: ```cmake find_package(protobuf CONFIG REQUIRED) if(NOT TARGET protobuf::libprotobuf-lite) message(FATAL_ERROR "protobuf::libprotobuf-lite was not exported") endif() if(TARGET protobuf::libprotobuf) message(FATAL_ERROR "protobuf::libprotobuf should not exist in lite-only install") endif() add_executable(protobuf_lite_consumer main.cc) target_link_libraries(protobuf_lite_consumer PRIVATE protobuf::libprotobuf-lite) ``` The consumer included: ```cpp #include <google/protobuf/message_lite.h> #include <google/protobuf/stubs/common.h> int main() { google::protobuf::ShutdownProtobufLibrary(); return 0; } ``` ### Invalid configuration checks All expected invalid combinations failed at configure time with clear `FATAL_ERROR` messages: - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_PROTOC_BINARIES=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_TESTS=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_CONFORMANCE=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_EXAMPLES=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_LIBUPB=ON` - `protobuf_BUILD_LIBPROTOBUF=OFF + protobuf_BUILD_LIBPROTOC=ON` ## Local PoC measurements The earlier local PoC measured the following on Windows/MSVC: | Variant | Configure | Build | Install | Install size | |---|---:|---:|---:|---:| | Default | 21.299s | 508.063s | 7.699s | 113754 KB | | Lite-only | 49.902s | 55.648s | 4.363s | 21579 KB | The lite-only configure step was slower in that local run, but the build step dominated the total time and dropped from `508.063s` to `55.648s`. ## Related Resolves #27231 Closes #27407 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/27407 from dudantas:dudantas/cmake-lite-only-runtime-pr 2c146c1aacb7453c61895898ef1ab660b9149294 PiperOrigin-RevId: 925038366
2026-06-01 19:01:31 -07:00
if (TARGET libprotobuf-lite)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif ()
if (TARGET libprotobuf)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif ()
if (TARGET libupb)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif ()
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
set(protobuf_HEADERS
${libprotobuf_hdrs}
${libprotoc_public_hdrs}
${plugin_proto_proto_srcs}
${release_all_options_protos_files}
)
if (protobuf_BUILD_LIBUPB)
list(APPEND protobuf_HEADERS ${libupb_hdrs})
# Manually install the bootstrap headers
install(
FILES
${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/descriptor.upb.h
${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/descriptor.upb_minitable.h
${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb.h
${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb_minitable.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/google/protobuf
COMPONENT protobuf-headers
)
endif ()
set(protobuf_STRIP_PREFIXES
"/src"
"/java/core/src/main/resources"
"/csharp"
"/go"
"/"
)
foreach(_header ${protobuf_HEADERS})
foreach(_strip_prefix ${protobuf_STRIP_PREFIXES})
string(FIND ${_header} "${protobuf_SOURCE_DIR}${_strip_prefix}" _find_src)
if(_find_src GREATER -1)
set(_from_dir "${protobuf_SOURCE_DIR}${_strip_prefix}")
break()
endif()
endforeach()
# Escape _from_dir for regex special characters in the directory name.
string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" _from_dir_regexp "${_from_dir}")
# On some platforms `_form_dir` ends up being just "protobuf", which can
# easily match multiple times in our paths. We force it to only replace
# prefixes to avoid this case.
string(REGEX REPLACE "^${_from_dir_regexp}" "" _header ${_header})
get_filename_component(_extract_from "${_from_dir}/${_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}")
2016-05-26 18:04:32 -07:00
endforeach()
2015-08-22 18:25:48 -07:00
# 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")
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}")
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)
2015-08-22 18:25:48 -07:00
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()
if (protobuf_INSTALL_TESTS)
install(TARGETS gmock EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()