protobuf.cmake 7.4 KB
Newer Older
L
liaogang 已提交
1
# Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
2
#
L
liaogang 已提交
3 4 5
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
6
#
L
liaogang 已提交
7
# http://www.apache.org/licenses/LICENSE-2.0
8
#
L
liaogang 已提交
9 10 11 12 13 14 15
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

INCLUDE(ExternalProject)
Y
Yu Yang 已提交
16 17 18 19
# Always invoke `FIND_PACKAGE(Protobuf)` for importing function protobuf_generate_cpp
FIND_PACKAGE(Protobuf QUIET)
SET(PROTOBUF_FOUND "OFF")

L
liaogang 已提交
20

21 22
# Print and set the protobuf library information,
# finish this cmake process and exit from this file.
Y
Yu Yang 已提交
23
macro(PROMPT_PROTOBUF_LIB)
24 25
    SET(protobuf_DEPS ${ARGN})

Y
Yu Yang 已提交
26 27
    MESSAGE(STATUS "Protobuf protoc executable: ${PROTOBUF_PROTOC_EXECUTABLE}")
    MESSAGE(STATUS "Protobuf library: ${PROTOBUF_LIBRARY}")
28
    MESSAGE(STATUS "Protobuf version: ${PROTOBUF_VERSION}")
Y
Yu Yang 已提交
29
    INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR})
30 31

    # Assuming that all the protobuf libraries are of the same type.
32
    IF(${PROTOBUF_LIBRARY} MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$")
33
        SET(protobuf_LIBTYPE STATIC)
34
    ELSEIF(${PROTOBUF_LIBRARY} MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
35 36 37 38 39 40 41 42 43 44 45
        SET(protobuf_LIBTYPE SHARED)
    ELSE()
        MESSAGE(FATAL_ERROR "Unknown library type: ${PROTOBUF_LIBRARY}")
    ENDIF()

    ADD_LIBRARY(protobuf ${protobuf_LIBTYPE} IMPORTED GLOBAL)
    SET_PROPERTY(TARGET protobuf PROPERTY IMPORTED_LOCATION ${PROTOBUF_LIBRARY})

    ADD_LIBRARY(protobuf_lite ${protobuf_LIBTYPE} IMPORTED GLOBAL)
    SET_PROPERTY(TARGET protobuf_lite PROPERTY IMPORTED_LOCATION ${PROTOBUF_LITE_LIBRARY})

Y
Yu Yang 已提交
46 47 48 49 50
    ADD_LIBRARY(libprotoc ${protobuf_LIBTYPE} IMPORTED GLOBAL)
    SET_PROPERTY(TARGET libprotoc PROPERTY IMPORTED_LOCATION ${PROTOC_LIBRARY})

    ADD_EXECUTABLE(protoc IMPORTED GLOBAL)
    SET_PROPERTY(TARGET protoc PROPERTY IMPORTED_LOCATION ${PROTOBUF_PROTOC_EXECUTABLE})
Y
Yu Yang 已提交
51 52 53
    # FIND_Protobuf.cmake uses `Protobuf_PROTOC_EXECUTABLE`.
    # make `protobuf_generate_cpp` happy.
    SET(Protobuf_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE})
54 55 56 57

    FOREACH(dep ${protobuf_DEPS})
        ADD_DEPENDENCIES(protobuf ${dep})
        ADD_DEPENDENCIES(protobuf_lite ${dep})
Y
Yu Yang 已提交
58
        ADD_DEPENDENCIES(libprotoc ${dep})
59 60 61 62
        ADD_DEPENDENCIES(protoc ${dep})
    ENDFOREACH()

    LIST(APPEND external_project_dependencies protobuf)
Y
Yu Yang 已提交
63 64
    RETURN()
endmacro()
65 66 67 68
macro(SET_PROTOBUF_VERSION)
    EXEC_PROGRAM(${PROTOBUF_PROTOC_EXECUTABLE} ARGS --version OUTPUT_VARIABLE PROTOBUF_VERSION)
    STRING(REGEX MATCH "[0-9]+.[0-9]+" PROTOBUF_VERSION "${PROTOBUF_VERSION}")
endmacro()
Y
Yu Yang 已提交
69 70 71 72 73 74 75 76

set(PROTOBUF_ROOT "" CACHE PATH "Folder contains protobuf")
if (NOT "${PROTOBUF_ROOT}" STREQUAL "")
    find_path(PROTOBUF_INCLUDE_DIR google/protobuf/message.h PATHS ${PROTOBUF_ROOT}/include)
    find_library(PROTOBUF_LIBRARY protobuf PATHS ${PROTOBUF_ROOT}/lib)
    find_library(PROTOBUF_LITE_LIBRARY protobuf-lite PATHS ${PROTOBUF_ROOT}/lib)
    find_library(PROTOBUF_PROTOC_LIBRARY protoc PATHS ${PROTOBUF_ROOT}/lib)
    find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS ${PROTOBUF_ROOT}/bin)
Y
Yu Yang 已提交
77
    if (PROTOBUF_INCLUDE_DIR AND PROTOBUF_LIBRARY AND PROTOBUF_LITE_LIBRARY AND PROTOBUF_PROTOC_LIBRARY AND PROTOBUF_PROTOC_EXECUTABLE)
Y
Yu Yang 已提交
78
        message(STATUS "Using custom protobuf library in ${PROTOBUF_ROOT}.")
79
        SET_PROTOBUF_VERSION()
Y
Yu Yang 已提交
80 81 82 83 84 85
        PROMPT_PROTOBUF_LIB()
    else()
        message(WARNING "Cannot find protobuf library in ${PROTOBUF_ROOT}.")
    endif()
endif()

86
FUNCTION(build_protobuf TARGET_NAME BUILD_FOR_HOST)
87 88 89
    STRING(REPLACE "extern_" "" TARGET_DIR_NAME "${TARGET_NAME}")
    SET(PROTOBUF_SOURCES_DIR ${THIRD_PARTY_PATH}/${TARGET_DIR_NAME})
    SET(PROTOBUF_INSTALL_DIR ${THIRD_PARTY_PATH}/install/${TARGET_DIR_NAME})
L
liaogang 已提交
90

91
    SET(${TARGET_NAME}_INCLUDE_DIR "${PROTOBUF_INSTALL_DIR}/include" PARENT_SCOPE)
92
    SET(PROTOBUF_INCLUDE_DIR "${PROTOBUF_INSTALL_DIR}/include" PARENT_SCOPE)
93
    SET(${TARGET_NAME}_LITE_LIBRARY
94
        "${PROTOBUF_INSTALL_DIR}/lib/libprotobuf-lite${CMAKE_STATIC_LIBRARY_SUFFIX}"
95 96
         PARENT_SCOPE)
    SET(${TARGET_NAME}_LIBRARY
97
        "${PROTOBUF_INSTALL_DIR}/lib/libprotobuf${CMAKE_STATIC_LIBRARY_SUFFIX}"
98 99
         PARENT_SCOPE)
    SET(${TARGET_NAME}_PROTOC_LIBRARY
100
        "${PROTOBUF_INSTALL_DIR}/lib/libprotoc${CMAKE_STATIC_LIBRARY_SUFFIX}"
101 102
         PARENT_SCOPE)
    SET(${TARGET_NAME}_PROTOC_EXECUTABLE
103
        "${PROTOBUF_INSTALL_DIR}/bin/protoc${CMAKE_EXECUTABLE_SUFFIX}"
104
         PARENT_SCOPE)
105

106 107 108 109 110 111 112 113 114 115 116 117 118 119
    SET(OPTIONAL_CACHE_ARGS "")
    SET(OPTIONAL_ARGS "")
    IF(BUILD_FOR_HOST)
        SET(OPTIONAL_ARGS "-Dprotobuf_WITH_ZLIB=OFF")
    ELSE()
        SET(OPTIONAL_ARGS
            "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
            "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
            "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
            "-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}"
            "-Dprotobuf_WITH_ZLIB=ON"
            "-DZLIB_ROOT:FILEPATH=${ZLIB_ROOT}")
        SET(OPTIONAL_CACHE_ARGS "-DZLIB_ROOT:STRING=${ZLIB_ROOT}")
    ENDIF()
L
liaogang 已提交
120

121
    ExternalProject_Add(
122
        ${TARGET_NAME}
123 124 125 126 127 128 129
        ${EXTERNAL_PROJECT_LOG_ARGS}
        PREFIX          ${PROTOBUF_SOURCES_DIR}
        UPDATE_COMMAND  ""
        DEPENDS         zlib
        GIT_REPOSITORY  "https://github.com/google/protobuf.git"
        GIT_TAG         "9f75c5aa851cd877fb0d93ccc31b8567a6706546"
        CONFIGURE_COMMAND
130 131
        ${CMAKE_COMMAND} ${PROTOBUF_SOURCES_DIR}/src/${TARGET_NAME}/cmake
            ${OPTIONAL_ARGS}
L
liaogang 已提交
132 133 134 135 136 137
            -Dprotobuf_BUILD_TESTS=OFF
            -DCMAKE_POSITION_INDEPENDENT_CODE=ON
            -DCMAKE_BUILD_TYPE=Release
            -DCMAKE_INSTALL_PREFIX=${PROTOBUF_INSTALL_DIR}
            -DCMAKE_INSTALL_LIBDIR=lib
        CMAKE_CACHE_ARGS
L
liaogang 已提交
138
            -DCMAKE_INSTALL_PREFIX:PATH=${PROTOBUF_INSTALL_DIR}
L
liaogang 已提交
139 140 141
            -DCMAKE_BUILD_TYPE:STRING=Release
            -DCMAKE_VERBOSE_MAKEFILE:BOOL=OFF
            -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
142
            ${OPTIONAL_CACHE_ARGS}
143
    )
144 145
ENDFUNCTION()

146
SET(PROTOBUF_VERSION 3.1)
147 148 149 150
IF(NOT CMAKE_CROSSCOMPILING)
    FIND_PACKAGE(Protobuf ${PROTOBUF_VERSION})

    IF(PROTOBUF_FOUND)
151
        SET_PROTOBUF_VERSION()
152
        IF("${PROTOBUF_VERSION}" VERSION_LESS "3.1.0")
153
            SET(PROTOBUF_FOUND OFF)
154 155
        ELSE()
            PROMPT_PROTOBUF_LIB()
156 157 158 159
        ENDIF()
    ENDIF(PROTOBUF_FOUND)
ELSE()
    build_protobuf(protobuf_host TRUE)
160 161
    LIST(APPEND external_project_dependencies protobuf_host)

162 163 164 165 166
    SET(PROTOBUF_PROTOC_EXECUTABLE ${protobuf_host_PROTOC_EXECUTABLE}
        CACHE FILEPATH "protobuf executable." FORCE)
ENDIF()

IF(NOT PROTOBUF_FOUND)
167
    build_protobuf(extern_protobuf FALSE)
168

169
    SET(PROTOBUF_INCLUDE_DIR ${extern_protobuf_INCLUDE_DIR}
170
        CACHE PATH "protobuf include directory." FORCE)
171 172 173 174 175 176 177 178 179 180 181
    SET(PROTOBUF_LITE_LIBRARY ${extern_protobuf_LITE_LIBRARY}
        CACHE FILEPATH "protobuf lite library." FORCE)
    SET(PROTOBUF_LIBRARY ${extern_protobuf_LIBRARY}
        CACHE FILEPATH "protobuf library." FORCE)
    SET(PROTOBUF_PROTOC_LIBRARY ${extern_protobuf_PROTOC_LIBRARY}
        CACHE FILEPATH "protoc library." FORCE)

    IF(CMAKE_CROSSCOMPILING)
        PROMPT_PROTOBUF_LIB(protobuf_host extern_protobuf)
    ELSE()
        SET(PROTOBUF_PROTOC_EXECUTABLE ${extern_protobuf_PROTOC_EXECUTABLE}
182
            CACHE FILEPATH "protobuf executable." FORCE)
183
        PROMPT_PROTOBUF_LIB(extern_protobuf)
184
    ENDIF()
185
ENDIF(NOT PROTOBUF_FOUND)