From c6090035cee2d38fddc01f08ddf73a788b9c6cff Mon Sep 17 00:00:00 2001 From: Liu Yiqun Date: Fri, 28 Apr 2017 06:36:31 +0000 Subject: [PATCH] Support the auto-compiling for host protoc when cross-compiling. --- cmake/cross_compiling/android.cmake | 19 ++++- cmake/external/protobuf.cmake | 105 ++++++++++++++++++---------- 2 files changed, 83 insertions(+), 41 deletions(-) diff --git a/cmake/cross_compiling/android.cmake b/cmake/cross_compiling/android.cmake index db5a753cd..4dd81bf29 100644 --- a/cmake/cross_compiling/android.cmake +++ b/cmake/cross_compiling/android.cmake @@ -110,9 +110,22 @@ IF(${CMAKE_VERSION} VERSION_LESS "3.7.0") ENDIF() ENDIF() SET(ANDROID_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_NAME}-") - - SET(CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}gcc") - SET(CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}g++") + + IF(EXISTS "${ANDROID_TOOLCHAIN_PREFIX}gcc") + SET(CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}gcc") + ELSE() + MESSAGE(FATAL_ERROR "Cannot find C compiler: ${ANDROID_TOOLCHAIN_PREFIX}gcc") + ENDIF() + + IF(EXISTS "${ANDROID_TOOLCHAIN_PREFIX}g++") + SET(CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}g++") + ELSE() + MESSAGE(FATAL_ERROR "Cannot find CXX compiler: ${ANDROID_TOOLCHAIN_PREFIX}g++") + ENDIF() + + IF(EXISTS "${ANDROID_TOOLCHAIN_PREFIX}gfortran") + SET(CMAKE_Fortran_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}gfortran") + ENDIF() # Toolchain and ABI specific flags. SET(ANDROID_COMPILER_FLAGS "-ffunction-sections -fdata-sections -finline-limit=64") diff --git a/cmake/external/protobuf.cmake b/cmake/external/protobuf.cmake index 2df042d22..2fc142de2 100644 --- a/cmake/external/protobuf.cmake +++ b/cmake/external/protobuf.cmake @@ -14,42 +14,41 @@ INCLUDE(ExternalProject) -set(PROTOBUF_VERSION 3.1) -FIND_PACKAGE(Protobuf ${PROTOBUF_VERSION}) +FUNCTION(build_protobuf TARGET_NAME BUILD_FOR_HOST) + SET(PROTOBUF_SOURCES_DIR ${THIRD_PARTY_PATH}/${TARGET_NAME}) + SET(PROTOBUF_INSTALL_DIR ${THIRD_PARTY_PATH}/install/${TARGET_NAME}) -IF(PROTOBUF_FOUND) - EXEC_PROGRAM(${PROTOBUF_PROTOC_EXECUTABLE} ARGS --version OUTPUT_VARIABLE PROTOBUF_VERSION) - STRING(REGEX MATCH "[0-9]+.[0-9]+" PROTOBUF_VERSION "${PROTOBUF_VERSION}") - IF (${PROTOBUF_VERSION} VERSION_LESS "3.1.0") - SET(PROTOBUF_FOUND OFF) - ENDIF() -ENDIF(PROTOBUF_FOUND) - -IF(NOT PROTOBUF_FOUND) - SET(PROTOBUF_SOURCES_DIR ${THIRD_PARTY_PATH}/protobuf) - SET(PROTOBUF_INSTALL_DIR ${THIRD_PARTY_PATH}/install/protobuf) - SET(PROTOBUF_INCLUDE_DIR "${PROTOBUF_INSTALL_DIR}/include" CACHE PATH "protobuf include directory." FORCE) + SET(${TARGET_NAME}_INCLUDE_DIR "${PROTOBUF_INSTALL_DIR}/include" PARENT_SCOPE) + SET(${TARGET_NAME}_LITE_LIBRARY + "${PROTOBUF_INSTALL_DIR}/lib/libprotobuf-lite${STATIC_LIBRARY_SUFFIX}" + PARENT_SCOPE) + SET(${TARGET_NAME}_LIBRARY + "${PROTOBUF_INSTALL_DIR}/lib/libprotobuf${STATIC_LIBRARY_SUFFIX}" + PARENT_SCOPE) + SET(${TARGET_NAME}_PROTOC_LIBRARY + "${PROTOBUF_INSTALL_DIR}/lib/libprotoc${STATIC_LIBRARY_SUFFIX}" + PARENT_SCOPE) + SET(${TARGET_NAME}_PROTOC_EXECUTABLE + "${PROTOBUF_INSTALL_DIR}/bin/protoc${EXECUTABLE_SUFFIX}" + PARENT_SCOPE) - IF(WIN32) - SET(PROTOBUF_LITE_LIBRARY - "${PROTOBUF_INSTALL_DIR}/lib/libprotobuf-lite.lib" CACHE FILEPATH "protobuf lite library." FORCE) - SET(PROTOBUF_LIBRARY - "${PROTOBUF_INSTALL_DIR}/lib/libprotobuf.lib" CACHE FILEPATH "protobuf library." FORCE) - SET(PROTOBUF_PROTOC_LIBRARY - "${PROTOBUF_INSTALL_DIR}/lib/libprotoc.lib" CACHE FILEPATH "protoc library." FORCE) - SET(PROTOBUF_PROTOC_EXECUTABLE "${PROTOBUF_INSTALL_DIR}/bin/protoc.exe" CACHE FILEPATH "protobuf executable." FORCE) - ELSE(WIN32) - SET(PROTOBUF_LITE_LIBRARY - "${PROTOBUF_INSTALL_DIR}/lib/libprotobuf-lite.a" CACHE FILEPATH "protobuf lite library." FORCE) - SET(PROTOBUF_LIBRARY - "${PROTOBUF_INSTALL_DIR}/lib/libprotobuf.a" CACHE FILEPATH "protobuf library." FORCE) - SET(PROTOBUF_PROTOC_LIBRARY - "${PROTOBUF_INSTALL_DIR}/lib/libprotoc.a" CACHE FILEPATH "protoc library." FORCE) - SET(PROTOBUF_PROTOC_EXECUTABLE "${PROTOBUF_INSTALL_DIR}/bin/protoc" CACHE FILEPATH "protobuf executable." FORCE) - ENDIF(WIN32) + 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() ExternalProject_Add( - protobuf + ${TARGET_NAME} ${EXTERNAL_PROJECT_LOG_ARGS} PREFIX ${PROTOBUF_SOURCES_DIR} UPDATE_COMMAND "" @@ -57,11 +56,9 @@ IF(NOT PROTOBUF_FOUND) GIT_REPOSITORY "https://github.com/google/protobuf.git" GIT_TAG "9f75c5aa851cd877fb0d93ccc31b8567a6706546" CONFIGURE_COMMAND - ${CMAKE_COMMAND} ${PROTOBUF_SOURCES_DIR}/src/protobuf/cmake + ${CMAKE_COMMAND} ${PROTOBUF_SOURCES_DIR}/src/${TARGET_NAME}/cmake + ${OPTIONAL_ARGS} -Dprotobuf_BUILD_TESTS=OFF - -DZLIB_ROOT:FILEPATH=${ZLIB_ROOT} - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PROTOBUF_INSTALL_DIR} @@ -71,10 +68,42 @@ IF(NOT PROTOBUF_FOUND) -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_VERBOSE_MAKEFILE:BOOL=OFF -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON - -DZLIB_ROOT:STRING=${ZLIB_ROOT} + ${OPTIONAL_CACHE_ARGS} ) - LIST(APPEND external_project_dependencies protobuf) + LIST(APPEND external_project_dependencies ${TARGET_NAME} PARENT_SCOPE) +ENDFUNCTION() + +IF(NOT CMAKE_CROSSCOMPILING) + SET(PROTOBUF_VERSION 3.1) + FIND_PACKAGE(Protobuf ${PROTOBUF_VERSION}) + + IF(PROTOBUF_FOUND) + EXEC_PROGRAM(${PROTOBUF_PROTOC_EXECUTABLE} ARGS --version OUTPUT_VARIABLE PROTOBUF_VERSION) + STRING(REGEX MATCH "[0-9]+.[0-9]+" PROTOBUF_VERSION "${PROTOBUF_VERSION}") + IF (${PROTOBUF_VERSION} VERSION_LESS "3.1.0") + SET(PROTOBUF_FOUND OFF) + ENDIF() + ENDIF(PROTOBUF_FOUND) +ELSE() + build_protobuf(protobuf_host TRUE) + SET(PROTOBUF_PROTOC_EXECUTABLE ${protobuf_host_PROTOC_EXECUTABLE} + CACHE FILEPATH "protobuf executable." FORCE) +ENDIF() + +IF(NOT PROTOBUF_FOUND) + build_protobuf(protobuf FALSE) + SET(PROTOBUF_INCLUDE_DIR ${protobuf_INCLUDE_DIR} + CACHE PATH "protobuf include directory." FORCE) + IF(NOT CMAKE_CROSSCOMPILING) + SET(PROTOBUF_PROTOC_EXECUTABLE ${protobuf_PROTOC_EXECUTABLE} + CACHE FILEPATH "protobuf executable." FORCE) + ENDIF() + SET(PROTOBUF_LITE_LIBRARY ${protobuf_LITE_LIBRARY} CACHE FILEPATH "protobuf lite library." FORCE) + SET(PROTOBUF_LIBRARY ${protobuf_LIBRARY} CACHE FILEPATH "protobuf library." FORCE) + SET(PROTOBUF_PROTOC_LIBRARY ${protobuf_PROTOC_LIBRARY} CACHE FILEPATH "protoc library." FORCE) ENDIF(NOT PROTOBUF_FOUND) +MESSAGE(STATUS "Protobuf protoc executable: ${PROTOBUF_PROTOC_EXECUTABLE}") +MESSAGE(STATUS "Protobuf library: ${PROTOBUF_LIBRARY}") INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) -- GitLab