Skip to content

Commit

Permalink
Make sure to export the FindProtobuf config after using FetchContent.…
Browse files Browse the repository at this point in the history
… Build protoc from scratch.
  • Loading branch information
fruffy committed Nov 27, 2023
1 parent ab11c7f commit 3b2b974
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 56 deletions.
2 changes: 1 addition & 1 deletion backends/dpdk/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ add_custom_target (dpdk_runtime_dir
# placed in the build directory inside `control-plane` directory
add_custom_command(
OUTPUT ${DPDK_P4RUNTIME_INFO_GEN_SRCS} ${DPDK_P4RUNTIME_INFO_GEN_HDRS}
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
COMMAND ${Protobuf_PROTOC_EXECUTABLE}
--proto_path ${DPDK_P4RUNTIME_DIR}
--proto_path ${P4RUNTIME_STD_DIR}
--cpp_out ${CMAKE_CURRENT_BINARY_DIR}/p4/config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,21 @@ endmacro(check_bmv2_with_ptf)
# - testfolder is target folder of the test.
function(validate_protobuf testfile testfolder)
# Find all the proto tests generated for this P4 file and validate their correctness.
file(APPEND ${testfile} "txtpbfiles=($(find ${testfolder} -name \"*.txtpb\" | sort -n ))\n")
file(APPEND ${testfile} "for item in \${txtpbfiles[@]}\n")
file(APPEND ${testfile} "do\n")
file(APPEND ${testfile} "\techo \"Found \${item}\"\n")
file(APPEND ${testfile} "\t${PROTOBUF_PROTOC_EXECUTABLE} --proto_path=${CMAKE_CURRENT_LIST_DIR}/../proto --proto_path=${P4RUNTIME_STD_DIR} --proto_path=${P4C_SOURCE_DIR}/control-plane --encode=p4testgen.TestCase p4testgen.proto < \${item}\n")
file(APPEND ${testfile} "done\n")
file(
GENERATE
OUTPUT ${testfile}
CONTENT
"txtpbfiles=($(find ${testfolder} -name \"*.txtpb\" | sort -n ))
for item in \${txtpbfiles[@]}
do
echo \"Found \${item}\"
${Protobuf_PROTOC_EXECUTABLE} --proto_path=${CMAKE_CURRENT_LIST_DIR}/../proto --proto_path=${P4RUNTIME_STD_DIR} --proto_path=${P4C_SOURCE_DIR}/control-plane --encode=p4testgen.TestCase p4testgen.proto < \${item}
done"
)
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0")
# TODO: With CMake version 3.20 this can be part of file(GENERATE).
file(CHMOD ${testfile} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE)
endif()
endfunction(validate_protobuf)

# Write the script to validate whether a given protobuf file has a valid format.
Expand Down
119 changes: 73 additions & 46 deletions cmake/Protobuf.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,81 +13,108 @@ macro(p4c_obtain_protobuf)
endif()
find_package(Protobuf CONFIG)
if(NOT Protobuf_FOUND)
find_package(Protobuf REQUIRED)
find_package(Protobuf REQUIRED)
endif()
# 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(ENABLE_PROTOBUF_STATIC)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${SAVED_CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
set(PROTOBUF_LIBRARY "protobuf::libprotobuf")
set(PROTOBUF_PROTOC_EXECUTABLE "protobuf::protoc")
else()
# Google introduced another breaking change with protobuf 22.x by adding abseil as a new
# dependency. https://protobuf.dev/news/2022-08-03/#abseil-dep We do not want abseil, so we stay
# with 21.x for now.
set(P4C_PROTOBUF_VERSION "21.12")
message("Fetching Protobuf version ${P4C_PROTOBUF_VERSION} for P4C...")

# Unity builds do not work for Protobuf...
set(CMAKE_UNITY_BUILD_PREV ${CMAKE_UNITY_BUILD})
set(CMAKE_UNITY_BUILD OFF)
# Print out download state while setting up Protobuf.
set(FETCHCONTENT_QUIET_PREV ${FETCHCONTENT_QUIET})
set(FETCHCONTENT_QUIET OFF)
# Build Protobuf with position-independent code.
set(CMAKE_POSITION_INDEPENDENT_CODE_PREV ${CMAKE_POSITION_INDEPENDENT_CODE})
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

set(protobuf_BUILD_TESTS OFF CACHE BOOL "Build tests.")
set(protobuf_BUILD_PROTOC_BINARIES OFF CACHE BOOL "Build libprotoc and protoc compiler.")
set(protobuf_BUILD_PROTOC_BINARIES ON CACHE BOOL "Build libprotoc and protoc compiler.")
# Only ever build the static library. It is not safe to link with a local dynamic version.
set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "Build Shared Libraries")
# Unity builds do not work for Protobuf...
set(SAVED_CMAKE_UNITY_BUILD ${CMAKE_UNITY_BUILD})
set(CMAKE_UNITY_BUILD OFF)
fetchcontent_declare(
protobuf
URL https://github.com/protocolbuffers/protobuf/releases/download/v${P4C_PROTOBUF_VERSION}/protobuf-cpp-3.${P4C_PROTOBUF_VERSION}.tar.gz
URL_HASH SHA256=4eab9b524aa5913c6fffb20b2a8abf5ef7f95a80bc0701f3a6dbb4c607f73460
USES_TERMINAL_DOWNLOAD TRUE
GIT_PROGRESS TRUE
# This is necessary to be able to call FindPackage.
set(protobuf_INSTALL ON CACHE BOOL "Install Protobuf")
# Derive the target architecture in order to build the right architecture.
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL
"arm64"
)

# Derive the target architecture in order to download the right zip.
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
set(protobuf_ARCH "aarch_64")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "amd64")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL
"amd64"
)
set(protobuf_ARCH "x86_64")
else()
MESSAGE(FATAL_ERROR "Unsupported host architecture `${CMAKE_HOST_SYSTEM_PROCESSOR}`")
message(FATAL_ERROR "Unsupported host architecture `${CMAKE_HOST_SYSTEM_PROCESSOR}`")
endif()

# Pull a different protoc binary for MacOS.
# TODO: Should we build from scratch?
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
fetchcontent_declare(
protoc
URL https://github.com/protocolbuffers/protobuf/releases/download/v${P4C_PROTOBUF_VERSION}/protoc-${P4C_PROTOBUF_VERSION}-osx-${protobuf_ARCH}.zip
USES_TERMINAL_DOWNLOAD TRUE
GIT_PROGRESS TRUE
)
else()
fetchcontent_declare(
protoc
URL https://github.com/protocolbuffers/protobuf/releases/download/v${P4C_PROTOBUF_VERSION}/protoc-${P4C_PROTOBUF_VERSION}-linux-${protobuf_ARCH}.zip
USES_TERMINAL_DOWNLOAD TRUE
GIT_PROGRESS TRUE
)
# Workaround for a bug in building protoc statically
# https://github.com/protocolbuffers/protobuf/issues/4958#issuecomment-510760038
if (BUILD_STATIC_RELEASE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread -Wl,--no-as-needed")
endif()

fetchcontent_makeavailable(protoc)
fetchcontent_declare(
protobuf
URL https://github.com/protocolbuffers/protobuf/releases/download/v${P4C_PROTOBUF_VERSION}/protobuf-cpp-3.${P4C_PROTOBUF_VERSION}.tar.gz
URL_HASH SHA256=4eab9b524aa5913c6fffb20b2a8abf5ef7f95a80bc0701f3a6dbb4c607f73460
USES_TERMINAL_DOWNLOAD TRUE
GIT_PROGRESS TRUE
)

# Exclude Protobuf from the main make install step. We only want to use it locally.
fetchcontent_makeavailable_but_exclude_install(protobuf)

# Reset unity builds to the previous state...
set(CMAKE_UNITY_BUILD ${SAVED_CMAKE_UNITY_BUILD})
set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV})

set(PROTOBUF_PROTOC_EXECUTABLE ${protoc_SOURCE_DIR}/bin/protoc CACHE STRING
"Protoc executable."
)
set(Protobuf_INCLUDE_DIR ${protobuf_SOURCE_DIR}/src/ CACHE STRING "Protobuf include directory.")
set(PROTOBUF_LIBRARY libprotobuf)
# Protobuf source code may trigger warnings which we need to ignore.
# Protobuf and protoc source code may trigger warnings which we need to ignore.
set_target_properties(libprotobuf PROPERTIES COMPILE_FLAGS "-Wno-error")
set_target_properties(libprotoc PROPERTIES COMPILE_FLAGS "-Wno-error")

# Add the Protobuf directory to our module path for module builds.
list(APPEND CMAKE_MODULE_PATH "${protobuf_BINARY_DIR}/cmake/protobuf")

message("Done with setting up Protobuf for P4C.")
# Set some Protobuf variables manually until we are able to call FindPackage directly.
set(Protobuf_FOUND TRUE)
set(Protobuf_LIBRARY "protobuf::libprotobuf")
set(Protobuf_PROTOC_LIBRARY "protobuf::libprotoc")
set(Protobuf_PROTOC_EXECUTABLE $<TARGET_FILE:protoc>)
set(Protobuf_INCLUDE_DIR "${protobuf_SOURCE_DIR}/src/")

# Reset temporary variable modifications.
set(CMAKE_UNITY_BUILD ${CMAKE_UNITY_BUILD_PREV})
set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV})
set(CMAKE_POSITION_INDEPENDENT_CODE ${CMAKE_POSITION_INDEPENDENT_CODE_PREV})
endif()


message("Done with setting up Protobuf for P4C.")
endmacro(p4c_obtain_protobuf)
6 changes: 3 additions & 3 deletions control-plane/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ set (P4RUNTIME_GEN_PYTHON "control-plane")
add_custom_target (mkP4configdir
${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/p4/config)
add_custom_command(OUTPUT ${P4RUNTIME_GEN_SRCS} ${P4RUNTIME_GEN_HDRS}
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
-I ${P4RUNTIME_STD_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${Protobuf_PROTOC_EXECUTABLE}
-I${P4RUNTIME_STD_DIR} -I${CMAKE_CURRENT_SOURCE_DIR} -I${Protobuf_INCLUDE_DIR}
--cpp_out ${CMAKE_CURRENT_BINARY_DIR}
--python_out ${CMAKE_CURRENT_BINARY_DIR}
--experimental_allow_proto3_optional
Expand Down Expand Up @@ -96,7 +96,7 @@ add_library(controlplane-gen OBJECT ${P4RUNTIME_GEN_SRCS})
target_include_directories(controlplane-gen
SYSTEM BEFORE PUBLIC ${Protobuf_INCLUDE_DIR}
)
target_link_libraries (controlplane-gen PUBLIC ${PROTOBUF_LIBRARY})
target_link_libraries (controlplane-gen PUBLIC ${Protobuf_LIBRARY})
# Needed for the correct import of google/status.pb.cc
target_include_directories(
controlplane-gen PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
Expand Down

0 comments on commit 3b2b974

Please sign in to comment.