# -----------------------------------------------------------------------------------------------------------
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
# CANN Open Software License Agreement Version 2.0 (the "License").
# Please refer to the License for details. You may not use this file except in compliance with the License.
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
# See LICENSE in the root of the software repository for the full text of the License.
# -----------------------------------------------------------------------------------------------------------
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
include(ExternalProject)
include(GNUInstallDirs)
set(PROTOBUF_SRC_DIR ${CMAKE_BINARY_DIR}/protobuf-src)
set(PROTOBUF_DL_DIR ${CMAKE_BINARY_DIR}/downloads)
set(PROTOBUF_STATIC_PKG_DIR ${CMAKE_BINARY_DIR}/protobuf_static)
set(PROTOBUF_SHARED_PKG_DIR ${CMAKE_BINARY_DIR}/protobuf_shared)
set(PROTOBUF_HOST_STATIC_PKG_DIR ${CMAKE_BINARY_DIR}/protobuf_host_static)
set(SECURITY_COMPILE_OPT "-Wl,-z,relro,-z,now,-z,noexecstack -s -Wl,-Bsymbolic")
set(PROTOBUF_CXXFLAGS "${SECURITY_COMPILE_OPT} -Wno-maybe-uninitialized -Wno-unused-parameter -fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2 -D_GLIBCXX_USE_CXX11_ABI=1 ${OPTIMIZE_OPTION} -Dgoogle=ascend_private")
set(HOST_PROTOBUF_CXXFLAGS "${SECURITY_COMPILE_OPT} -Wno-maybe-uninitialized -Wno-unused-parameter -fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2 -D_GLIBCXX_USE_CXX11_ABI=0 ${OPTIMIZE_OPTION} -Dgoogle=ascend_private")
if (PRODUCT_SIDE STREQUAL "device")
message(STATUS "[UDF protobuf] Building for device side")
set(HOST_PROTOBUF_CXXFLAGS ${PROTOBUF_CXXFLAGS})
endif()
set(HOST_PROTOBUF_CXXFLAGS "${HOST_PROTOBUF_CXXFLAGS}")
message(STATUS "[UDF protobuf] HOST_PROTOBUF_CXXFLAGS is ${HOST_PROTOBUF_CXXFLAGS}")
# 使用设备端工具链生成 ascend_protobuf_static
set(CMAKE_CXX_COMPILER_ ${TOOLCHAIN_DIR}/bin/aarch64-target-linux-gnu-g++)
set(CMAKE_C_COMPILER_ ${TOOLCHAIN_DIR}/bin/aarch64-target-linux-gnu-gcc)
set(SOURCE_DIR ${PROTOBUF_SRC_DIR})
set(PROTOBUF_PATH ${CANN_3RD_LIB_PATH}/protobuf)
set(ABSEIL_PATH ${CANN_3RD_LIB_PATH}/abseil-cpp)
set(PATCH_PATH ${CMAKE_CURRENT_SOURCE_DIR})
if ((NOT EXISTS "${PROTOBUF_PATH}/protobuf-all-25.1.tar.gz" AND NOT EXISTS "${PROTOBUF_PATH}/protobuf-25.1.tar.gz") OR
NOT EXISTS "${ABSEIL_PATH}/abseil-cpp-20230802.1.tar.gz")
message(STATUS "[UDF protobuf] protobuf tar.gz not exists or abseil-cpp-20230802.1.tar.gz not exists")
set(REQ_URL "https://gitcode.com/cann-src-third-party/protobuf/releases/download/v25.1/protobuf-25.1.tar.gz")
set(ABS_REQ_URL "https://gitcode.com/cann-src-third-party/abseil-cpp/releases/download/20230802.1/abseil-cpp-20230802.1.tar.gz")
ExternalProject_Add(protobuf_src_dl
URL ${REQ_URL}
TLS_VERIFY OFF
DOWNLOAD_DIR ${PROTOBUF_DL_DIR}/
DOWNLOAD_NO_EXTRACT 1
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
ExternalProject_Add(abseil_src_dl
URL ${ABS_REQ_URL}
TLS_VERIFY OFF
DOWNLOAD_DIR ${PROTOBUF_DL_DIR}/abseil-cpp/
DOWNLOAD_NO_EXTRACT 1
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
# 下载/解压 protobuf 源码
ExternalProject_Add(protobuf_src
DOWNLOAD_COMMAND ""
COMMAND tar -zxf ${PROTOBUF_DL_DIR}/protobuf-25.1.tar.gz --strip-components 1 -C ${SOURCE_DIR}
COMMAND tar -zxf ${PROTOBUF_DL_DIR}/abseil-cpp/abseil-cpp-20230802.1.tar.gz --strip-components 1 -C ${SOURCE_DIR}/third_party/abseil-cpp
PATCH_COMMAND cd ${SOURCE_DIR} && patch -p1 < ${PATCH_PATH}/protobuf_25.1_change_version.patch && cd ${SOURCE_DIR}/third_party/abseil-cpp && patch -p1 < ${PATCH_PATH}/protobuf-hide_absl_symbols.patch
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
add_dependencies(protobuf_src protobuf_src_dl abseil_src_dl)
else()
if(EXISTS "${PROTOBUF_PATH}/protobuf-all-25.1.tar.gz")
set(PROTOBUF_FILE_NAME "protobuf-all-25.1.tar.gz")
else()
set(PROTOBUF_FILE_NAME "protobuf-25.1.tar.gz")
endif()
message(STATUS "[UDF protobuf] protobuf tar.gz exists: ${PROTOBUF_FILE_NAME}")
ExternalProject_Add(protobuf_src
DOWNLOAD_COMMAND ""
COMMAND tar -zxf ${CANN_3RD_LIB_PATH}/protobuf/${PROTOBUF_FILE_NAME} --strip-components 1 -C ${SOURCE_DIR}
COMMAND tar -zxf ${CANN_3RD_LIB_PATH}/abseil-cpp/abseil-cpp-20230802.1.tar.gz --strip-components 1 -C ${SOURCE_DIR}/third_party/abseil-cpp
PATCH_COMMAND cd ${SOURCE_DIR} && patch -p1 < ${PATCH_PATH}/protobuf_25.1_change_version.patch && cd ${SOURCE_DIR}/third_party/abseil-cpp && patch -p1 < ${PATCH_PATH}/protobuf-hide_absl_symbols.patch
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
endif()
ExternalProject_Add(protobuf_static_build
DEPENDS protobuf_src
SOURCE_DIR ${PROTOBUF_SRC_DIR}
DOWNLOAD_COMMAND ""
UPDATE_COMMAND ""
CONFIGURE_COMMAND ${CMAKE_COMMAND}
-G ${CMAKE_GENERATOR}
-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
-DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
-DTOOLCHAIN_DIR=${TOOLCHAIN_DIR}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DCMAKE_INSTALL_LIBDIR=lib
-DBUILD_SHARED_LIBS=OFF
-Dprotobuf_WITH_ZLIB=OFF
-DLIB_PREFIX=ascend_
-DCMAKE_SKIP_RPATH=TRUE
-Dprotobuf_BUILD_TESTS=OFF
-DCMAKE_CXX_STANDARD=14
-DCMAKE_CXX_FLAGS=${HOST_PROTOBUF_CXXFLAGS}
-DCMAKE_INSTALL_PREFIX=${PROTOBUF_STATIC_PKG_DIR}
-Dprotobuf_BUILD_PROTOC_BINARIES=OFF
-DABSL_COMPILE_OBJ=TRUE
<SOURCE_DIR>
BUILD_COMMAND $(MAKE)
INSTALL_COMMAND $(MAKE) install
EXCLUDE_FROM_ALL TRUE
)
ExternalProject_Add(protobuf_shared_build
DEPENDS protobuf_src
SOURCE_DIR ${PROTOBUF_SRC_DIR}
DOWNLOAD_COMMAND ""
UPDATE_COMMAND ""
CONFIGURE_COMMAND ${CMAKE_COMMAND}
-G ${CMAKE_GENERATOR}
-DTOOLCHAIN_DIR=${TOOLCHAIN_DIR}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
-DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
-DCMAKE_INSTALL_LIBDIR=lib
-DBUILD_SHARED_LIBS=ON
-Dprotobuf_WITH_ZLIB=OFF
-DLIB_PREFIX=ascend_
-DCMAKE_SKIP_RPATH=TRUE
-Dprotobuf_BUILD_TESTS=OFF
-DCMAKE_CXX_STANDARD=14
-DCMAKE_CXX_FLAGS=${HOST_PROTOBUF_CXXFLAGS}
-DCMAKE_INSTALL_PREFIX=${PROTOBUF_SHARED_PKG_DIR}
-Dprotobuf_BUILD_PROTOC_BINARIES=OFF
<SOURCE_DIR>
BUILD_COMMAND $(MAKE)
INSTALL_COMMAND $(MAKE) install
EXCLUDE_FROM_ALL TRUE
)
ExternalProject_Add(protobuf_host_static_build
DEPENDS protobuf_src
SOURCE_DIR ${PROTOBUF_SRC_DIR}
DOWNLOAD_COMMAND ""
UPDATE_COMMAND ""
CONFIGURE_COMMAND ${CMAKE_COMMAND}
-G ${CMAKE_GENERATOR}
-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
-DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
-DCMAKE_INSTALL_LIBDIR=lib
-DBUILD_SHARED_LIBS=OFF
-Dprotobuf_WITH_ZLIB=OFF
-DLIB_PREFIX=host_ascend_
-DCMAKE_SKIP_RPATH=TRUE
-Dprotobuf_BUILD_TESTS=OFF
-DCMAKE_CXX_STANDARD=14
-DCMAKE_CXX_FLAGS=${HOST_PROTOBUF_CXXFLAGS}
-DCMAKE_INSTALL_PREFIX=${PROTOBUF_HOST_STATIC_PKG_DIR}
-Dprotobuf_BUILD_PROTOC_BINARIES=OFF
-DABSL_COMPILE_OBJ=TRUE
<SOURCE_DIR>
BUILD_COMMAND $(MAKE)
INSTALL_COMMAND $(MAKE) install
EXCLUDE_FROM_ALL TRUE
)
set(PROTOBUF_HOST_DIR ${CMAKE_BINARY_DIR}/protobuf_host)
ExternalProject_Add(protobuf_host_build
DEPENDS protobuf_src
SOURCE_DIR ${PROTOBUF_SRC_DIR}
DOWNLOAD_COMMAND ""
UPDATE_COMMAND ""
CONFIGURE_COMMAND ${CMAKE_COMMAND}
-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
-DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
-DCMAKE_INSTALL_PREFIX=${PROTOBUF_HOST_DIR}
-Dprotobuf_BUILD_TESTS=OFF
-DCMAKE_CXX_STANDARD=14
-Dprotobuf_WITH_ZLIB=OFF
<SOURCE_DIR>
BUILD_COMMAND $(MAKE)
INSTALL_COMMAND $(MAKE) install
EXCLUDE_FROM_ALL TRUE
)
add_executable(host_protoc IMPORTED)
set_target_properties(host_protoc PROPERTIES
IMPORTED_LOCATION ${PROTOBUF_HOST_DIR}/bin/protoc
)
add_dependencies(host_protoc protobuf_host_build)
add_library(ascend_protobuf_static_lib STATIC IMPORTED)
set_target_properties(ascend_protobuf_static_lib PROPERTIES
IMPORTED_LOCATION ${PROTOBUF_STATIC_PKG_DIR}/lib/libascend_protobuf.a
)
add_library(ascend_protobuf_static INTERFACE)
target_include_directories(ascend_protobuf_static INTERFACE ${PROTOBUF_STATIC_PKG_DIR}/include)
target_link_libraries(ascend_protobuf_static INTERFACE ascend_protobuf_static_lib)
add_dependencies(ascend_protobuf_static protobuf_static_build)