I have been using protobuf with static linking for years and moved to cmake
a few months ago.
Since I always cross-compile I never use the system installed library and
tools so my flow is this
1 - Build, using cmake anything that must be using the local compiler (in
the case of protobuf because protoc is needed for later). ATM it is only
protobuf
2 - Build all the dependencies, also using cmake
3 - Build my project, including internal libraries.
For the first step, ie building protobuf and produce a static archive (a
file ending with .a) I use this excerpt from the corresponding cmake:
include(ExternalProject)
ExternalProject_Add(
protobuf
GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
GIT_TAG v3.20.3
SOURCE_SUBDIR cmake
CMAKE_ARGS
-Dprotobuf_BUILD_TESTS=OFF
-Dprotobuf_BUILD_EXAMPLES=OFF
-DCMAKE_INSTALL_PREFIX=$ENV{INSTALL}/protobuf
-Dprotobuf_BUILD_CONFORMANCE=OFF
-Dprotobuf_BUILD_EXAMPLES=OFF
-Dprotobuf_BUILD_LIBPROTOC=ON
-Dprotobuf_BUILD_SHARED_LIBS=OFF
-Dprotobuf_MSVC_STATIC_RUNTIME=OFF
-Dprotobuf_WITH_ZLIB=OFF
BUILD_BYPRODUCTS
$ENV{INSTALL}/lib/libprotobuf.a
$ENV{INSTALL}/bin/protoc
)
Note that the install prefix comes from an environment variable. It is
normally set to ./build In other word, protobuf and the cmake files are in
a child directory off the main build location (which is used by step 3
above). Also, SHARED_LIBS is Off meaning that a static library is created.
And then in my main project (so step 3 above), I use this to process my
proto files (I use to only deal with c++ hence the name; I added python at
a later stage):
set(GLOBAL_PROTO_FILES "" CACHE INTERNAL "")
# Define the append function used by other CMakeList files
function(append_proto_file filename)
set(GLOBAL_PROTO_FILES ${GLOBAL_PROTO_FILES} ${filename} CACHE INTERNAL
"")
endfunction()
#
# The proto file processing function
#
function(CREATE_CPP_PROTO SRCS HDRS)
list(REMOVE_DUPLICATES GLOBAL_PROTO_FILES)
set(${SRCS})
set(${HDRS})
#printList(VAR ${PROTO_SRC_TREE} TITLE "Proto location location")
#printList(VAR ${GLOBAL_PROTO_FILES} TITLE "Proto files")
add_library(proto-objects OBJECT ${GLOBAL_PROTO_FILES})
target_link_libraries(proto-objects PUBLIC protobuf::libprotobuf)
target_include_directories(proto-objects PUBLIC
"$<BUILD_INTERFACE:$ENV{GENERATED}>")
make_directory($ENV{GENERATED})
make_directory($ENV{GENERATED}/python)
# This is a function provided by the cmake binding for protobuf
# C++
protobuf_generate(
TARGET proto-objects
LANGUAGE cpp
PROTOC_OUT_DIR $ENV{GENERATED}
IMPORT_DIRS ${MODELS_DIR};${PROTO_SRC_TREE}
#IMPORT_DIRS ${MODELS_DIR}
#PROTOC_OPTIONS "--cpp_opt=paths=source_relative"
#PROTOC_OPTIONS "--proto_path=${MODELS_DIR}"
)
# Python
protobuf_generate(
TARGET proto-objects
LANGUAGE python
PROTOC_OUT_DIR $ENV{GENERATED}/python
IMPORT_DIRS ${MODELS_DIR};${PROTO_SRC_TREE}
)
target_include_directories(proto-objects PRIVATE $ENV{GENERATED})
# Probably useless but other targets depends on it, so we keep it but
it does nothing. In future we could probably remove
# reference to it.
add_custom_target(PROTO_FILES_READY
COMMENT "Moving .pb.h and _pb2.py files to replicate source directory
structure"
)
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED
TRUE)
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()
On Monday, August 19, 2024 at 2:32:25 a.m. UTC-4 Marcin Lewandowski wrote:
> Hello,
>
> I am working on a library where I would use protobuf.
>
> I need to link it statically. The target platform is macOS.
>
> The usual way of fetching dependencies (brew install protobuf) is no go,
> as it comes only with shared libraries.
>
> I tried forcing homebrew to rebuild protobuf (brew install protobuf
> --build-from-source) but it fails as some tests are not passing (logs [1]
> at the end of this message).
>
> I fetched the source code (27.3) release from github, run
>
> bazel build :portico :protobuf
>
> inside the source directory, but while it compiles protoc compiler,
> there's no CMake/protobuf-lite library in the output.
>
> Apparently the runtime is based on CMake, so I run
>
> cmake -S . -B build -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_CXX_STANDARD=17
> -Dprotobuf_ABSL_PROVIDER=package -Dprotobuf_JSONCPP_PROVIDER=package
>
> and then issued compilation in build/ dir, and yay, it compiled protobuf.
>
> However, when I added the build/cmake to CMAKE_PREFIX_PATH it complains
> about missing build/cmake/protobuf/protobuf-targets.cmake
>
> So I tried adding the repository as git submodule, and adding it via
> add_subdirectory CMake command, then it fails with
>
> CMake Error: install(EXPORT "protobuf-targets" ...) includes target
> "libprotobuf-lite" which requires target "absl_absl_check" that is not in
> any export set.
> CMake Error: install(EXPORT "protobuf-targets" ...) includes target
> "libprotobuf-lite" which requires target "absl_absl_log" that is not in any
> export set.
> CMake Error: install(EXPORT "protobuf-targets" ...) includes target
> "libprotobuf-lite" which requires target "absl_algorithm" that is not in
> any export set.
> CMake Error: install(EXPORT "protobuf-targets" ...) includes target
> "libprotobuf-lite" which requires target "absl_base" that is not in any
> export set.
> ...
>
> abseil is added as add_subdirectory as well.
>
> I run into conclusion that I must be doing something fundamentally wrong,
> as I don't expect such popular piece of code to be so hard to integrate.
>
> Any suggestions on how to properly embed protobuf within such a project?
>
> Thanks in advance,
>
> Marcin
>
> [1] Failed tests:
>
> 2: [ RUN ] TextFormatParserTest.ParseFieldValueFromString
> 2: E0000 00:00:1723926116.158054 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected integer, got: a
> 2: E0000 00:00:1723926116.158063 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Integer out of range
> (999999999999999999999999999999999999)
> 2: E0000 00:00:1723926116.158079 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected integer, got: a
> 2: E0000 00:00:1723926116.158082 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Integer out of range
> (999999999999999999999999999999999999)
> 2: E0000 00:00:1723926116.158084 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected integer, got: -
> 2: E0000 00:00:1723926116.158085 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected integer, got: a
> 2: E0000 00:00:1723926116.158087 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Integer out of range
> (999999999999999999999999999999999999)
> 2: E0000 00:00:1723926116.158089 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected integer, got: -
> 2: E0000 00:00:1723926116.158090 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected integer, got: a
> 2: E0000 00:00:1723926116.158092 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Integer out of range
> (999999999999999999999999999999999999)
> 2: E0000 00:00:1723926116.158094 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected integer, got: -
> 2: E0000 00:00:1723926116.158095 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected integer, got: a
> 2: E0000 00:00:1723926116.158097 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Integer out of range
> (999999999999999999999999999999999999)
> 2: E0000 00:00:1723926116.158101 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:5: Invalid value for boolean
> field "optional_bool". Value: "tRue".
> 2: E0000 00:00:1723926116.158106 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:6: Invalid value for boolean
> field "optional_bool". Value: "faLse".
> 2: E0000 00:00:1723926116.158108 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Integer out of range (2)
> 2: E0000 00:00:1723926116.158109 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected identifier, got: -
> 2: E0000 00:00:1723926116.158111 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:3: Invalid value for boolean
> field "optional_bool". Value: "on".
> 2: E0000 00:00:1723926116.158113 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:2: Invalid value for boolean
> field "optional_bool". Value: "a".
> 2: E0000 00:00:1723926116.158130 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected double, got: a
> 2: E0000 00:00:1723926116.158132 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected double, got: a
> 2: E0000 00:00:1723926116.158134 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expect a decimal number,
> got: 0xf
> 2: E0000 00:00:1723926116.158136 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expect a decimal number,
> got: 012
> 2: E0000 00:00:1723926116.158138 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected string, got: hello
> 2: E0000 00:00:1723926116.158141 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:7: Unknown enumeration value
> of "FOOBAR" for field "optional_nested_enum".
> 2: E0000 00:00:1723926116.158143 5519321 text_format.cc:417] Error parsing
> text-format protobuf_unittest.TestAllTypes: 1:1: Expected "{", found "any".
>
>
--
You received this message because you are subscribed to the Google Groups
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/protobuf/61576afe-d401-432c-98ab-f56c32f0af89n%40googlegroups.com.