Skip to content

Commit

Permalink
Add a way for users to provide local directories for external libraries
Browse files Browse the repository at this point in the history
Allow the users to provide their own directories for all the external libraries that are downloaded as part of the build process, by overriding name_SOURCE_DIR and name_BINARY_DIR.

PiperOrigin-RevId: 246938364
  • Loading branch information
a-maurice committed May 7, 2019
1 parent c3c8f74 commit 5c15a6e
Show file tree
Hide file tree
Showing 15 changed files with 114 additions and 73 deletions.
49 changes: 22 additions & 27 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ set(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "")

# Add flatbuffers as a subdirectory, and set the directory variables for it,
# so that the sub Firebase projects can depend upon it if necessary.
add_external_subdirectory(flatbuffers)
populate_external_source_vars(flatbuffers)
add_external_library(flatbuffers)

# Some of the external libraries are not used for mobile.
if (NOT ANDROID AND NOT IOS)
Expand All @@ -98,18 +97,15 @@ if (NOT ANDROID AND NOT IOS)
if (WIN32)
set(CMAKE_USE_WINSSL ON CACHE BOOL "")
endif()
add_external_subdirectory(curl)
populate_external_source_vars(curl)
add_external_library(curl)

add_external_subdirectory(libuv)
populate_external_source_vars(libuv)
add_external_library(libuv)

find_package(OpenSSL)

add_external_subdirectory(zlib)
populate_external_source_vars(zlib)
add_external_library(zlib)

populate_external_source_vars(uWebSockets)
add_external_library(uWebSockets)
# uWebSockets does not come with a CMakeLists file, so define the target.
# Note that since it depends on OpenSSL, only do so if that was found.
if (OPENSSL_FOUND)
Expand All @@ -118,18 +114,18 @@ if (NOT ANDROID AND NOT IOS)
else()
# Epoll is only used on Linux, otherwise LibUV is used.
set(uWebSockets_extra_src
${uWebSockets_SOURCE_DIR}/src/Epoll.cpp)
${UWEBSOCKETS_SOURCE_DIR}/src/Epoll.cpp)
endif()
add_library(libuWS STATIC
${uWebSockets_extra_src}
${uWebSockets_SOURCE_DIR}/src/Extensions.cpp
${uWebSockets_SOURCE_DIR}/src/Group.cpp
${uWebSockets_SOURCE_DIR}/src/HTTPSocket.cpp
${uWebSockets_SOURCE_DIR}/src/Hub.cpp
${uWebSockets_SOURCE_DIR}/src/Networking.cpp
${uWebSockets_SOURCE_DIR}/src/Node.cpp
${uWebSockets_SOURCE_DIR}/src/Socket.cpp
${uWebSockets_SOURCE_DIR}/src/WebSocket.cpp)
${UWEBSOCKETS_SOURCE_DIR}/src/Extensions.cpp
${UWEBSOCKETS_SOURCE_DIR}/src/Group.cpp
${UWEBSOCKETS_SOURCE_DIR}/src/HTTPSocket.cpp
${UWEBSOCKETS_SOURCE_DIR}/src/Hub.cpp
${UWEBSOCKETS_SOURCE_DIR}/src/Networking.cpp
${UWEBSOCKETS_SOURCE_DIR}/src/Node.cpp
${UWEBSOCKETS_SOURCE_DIR}/src/Socket.cpp
${UWEBSOCKETS_SOURCE_DIR}/src/WebSocket.cpp)
if(MSVC)
set(websockets_additional_defines
-DWIN32_LEAN_AND_MEAN # Ensure that windows doesn't include winsock.h by
Expand All @@ -149,10 +145,10 @@ if (NOT ANDROID AND NOT IOS)
)
target_include_directories(libuWS
PUBLIC
${libuv_SOURCE_DIR}/include
${uWebSockets_SOURCE_DIR}
${zlib_SOURCE_DIR}
${zlib_BINARY_DIR}
${LIBUV_SOURCE_DIR}/include
${UWEBSOCKETS_SOURCE_DIR}
${ZLIB_SOURCE_DIR}
${ZLIB_BINARY_DIR}
PRIVATE
${OPENSSL_INCLUDE_DIR}
)
Expand All @@ -167,19 +163,18 @@ if (NOT ANDROID AND NOT IOS)
find_package(Protobuf)
if (PROTOBUF_FOUND)
# NanoPB requires Protobuf to be present, so only add it if it was found.
add_external_subdirectory(nanopb)
populate_external_source_vars(nanopb)
add_external_library(nanopb)
# NanoPB has a FindNanopb which defines the function to generate files, so
# add it to the module path, and use that.
list(INSERT CMAKE_MODULE_PATH 0 ${nanopb_SOURCE_DIR}/extra)
list(INSERT CMAKE_MODULE_PATH 0 ${NANOPB_SOURCE_DIR}/extra)
find_package(Nanopb)
endif()
endif()

if(ANDROID OR IOS)
# Mobile platforms build flatc externally so that it works on the platform
# performing the build.
set(firebase_external_flatc_build_dir "${flatbuffers_BINARY_DIR}-flatc")
set(firebase_external_flatc_build_dir "${FLATBUFFERS_BINARY_DIR}-flatc")
set(firebase_external_flatc "${firebase_external_flatc_build_dir}/flatc")

if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
Expand Down Expand Up @@ -224,7 +219,7 @@ if(ANDROID OR IOS)
add_custom_command(
OUTPUT ${firebase_external_flatc}
COMMAND cd ${firebase_external_flatc_build_dir} ${COMMAND_CONCAT}
${ENV_COMMAND} cmake ${flatbuffers_SOURCE_DIR} ${COMMAND_CONCAT}
${ENV_COMMAND} cmake ${FLATBUFFERS_SOURCE_DIR} ${COMMAND_CONCAT}
${ENV_COMMAND} cmake --build . --target flatc
COMMENT "Building flatc (the FlatBuffer schema compiler)")

Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,34 @@ cmake -G “Visual Studio 15 2017” ..
More information on generators can be found at
<https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html>.

By default, when building the SDK, the CMake process will download any third
party dependencies that are needed for the build. This logic is in
[cmake/external_rules.cmake](/cmake/external_rules.cmake), and the accompanying
[cmake/external/CMakeLists.txt](/cmake/external/CMakeLists.txt). If you would
like to provide your own directory for these dependencies, you can override
`[[dependency_name]]_SOURCE_DIR` and `[[dependency_name]]_BINARY_DIR`. If the
binary directory is not provided, it defaults to the given source directory,
appended with `-build`.

For example, to provide a custom flatbuffer directory you could run:

``` bash
cmake -DFLATBUFFERS_SOURCE_DIR=/tmp/flatbuffers ..
```

And the binary directory would automatically be set to `/tmp/flatbuffers-build`.

Currently, the third party libraries that can be provided this way are:

| Library |
| ------- |
| CURL |
| FLATBUFFERS |
| LIBUV |
| NANOPB |
| UWEBSOCKETS |
| ZLIB |

#### Building with CMake for iOS
The Firebase C++ SDK comes with a CMake config file to build the library for
iOS platforms, [cmake/ios.cmake](/cmake/ios.cmake). In order to build with it,
Expand Down
2 changes: 1 addition & 1 deletion app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ target_include_directories(firebase_app
${FIREBASE_GEN_FILE_DIR}
PRIVATE
${FIREBASE_CPP_SDK_ROOT_DIR}
${flatbuffers_SOURCE_DIR}/include
${FLATBUFFERS_SOURCE_DIR}/include
)
target_compile_definitions(firebase_app
PRIVATE
Expand Down
8 changes: 4 additions & 4 deletions app/rest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ add_library(firebase_rest_lib STATIC
target_include_directories(firebase_rest_lib
PUBLIC
${FIREBASE_CPP_SDK_ROOT_DIR}
${flatbuffers_SOURCE_DIR}/include
${zlib_SOURCE_DIR}/..
${zlib_BINARY_DIR}
${FLATBUFFERS_SOURCE_DIR}/include
${ZLIB_SOURCE_DIR}/..
${ZLIB_BINARY_DIR}
PRIVATE
${curl_SOURCE_DIR}/include
${CURL_SOURCE_DIR}/include
)

if(MSVC)
Expand Down
2 changes: 1 addition & 1 deletion auth/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ if(ANDROID OR IOS)
set(additional_target_definitions)
else()
set(additional_include_DIR
${flatbuffers_SOURCE_DIR}/include
${FLATBUFFERS_SOURCE_DIR}/include
${LIBSECRET_INCLUDE_DIRS})
set(additional_link_LIB
firebase_rest_lib
Expand Down
6 changes: 2 additions & 4 deletions cmake/external/curl.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@

include(ExternalProject)

if(TARGET curl)
if(TARGET curl OR NOT DOWNLOAD_CURL)
return()
endif()

# TODO(b/117950963): Use a system- or user-supplied curl if available

ExternalProject_Add(
curl

Expand All @@ -32,4 +30,4 @@ ExternalProject_Add(
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
)
2 changes: 1 addition & 1 deletion cmake/external/flatbuffers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

include(ExternalProject)

if(TARGET flatbuffers)
if(TARGET flatbuffers OR NOT DOWNLOAD_FLATBUFFERS)
return()
endif()

Expand Down
6 changes: 2 additions & 4 deletions cmake/external/libuv.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@

include(ExternalProject)

if(TARGET libuv)
if(TARGET libuv OR NOT DOWNLOAD_LIBUV)
return()
endif()

# TODO(b/117950963): Use a system- or user-supplied libuv if available

ExternalProject_Add(
libuv

Expand All @@ -32,4 +30,4 @@ ExternalProject_Add(
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
)
4 changes: 2 additions & 2 deletions cmake/external/nanopb.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

include(ExternalProject)

if(TARGET nanopb)
if(TARGET nanopb OR NOT DOWNLOAD_NANOPB)
return()
endif()

Expand All @@ -31,4 +31,4 @@ ExternalProject_Add(
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
)
6 changes: 2 additions & 4 deletions cmake/external/uWebSockets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@

include(ExternalProject)

if(TARGET uWebSockets)
if(TARGET uWebSockets OR NOT DOWNLOAD_UWEBSOCKETS)
return()
endif()

# TODO(b/117950963): Use a system- or user-supplied openssl if available

ExternalProject_Add(
uWebSockets

Expand All @@ -32,4 +30,4 @@ ExternalProject_Add(
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
)
6 changes: 2 additions & 4 deletions cmake/external/zlib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@

include(ExternalProject)

if(TARGET zlib)
if(TARGET zlib OR NOT DOWNLOAD_ZLIB)
return()
endif()

# TODO(b/117950963): Use a system- or user-supplied zlib if available

ExternalProject_Add(
zlib

Expand All @@ -34,4 +32,4 @@ ExternalProject_Add(
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
)
60 changes: 43 additions & 17 deletions cmake/external_rules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,35 @@ function(download_external_sources)
else()
set(external_platform DESKTOP)
endif()


# Set variables to indicate if local versions of third party libraries should
# be used instead of downloading them.
function(check_use_local_directory NAME)
if (EXISTS ${${NAME}_SOURCE_DIR})
set(DOWNLOAD_${NAME} OFF PARENT_SCOPE)
else()
set(DOWNLOAD_${NAME} ON PARENT_SCOPE)
endif()
endfunction()
check_use_local_directory(CURL)
check_use_local_directory(FLATBUFFERS)
check_use_local_directory(LIBUV)
check_use_local_directory(NANOPB)
check_use_local_directory(UWEBSOCKETS)
check_use_local_directory(ZLIB)

execute_process(
COMMAND
${ENV_COMMAND} cmake
-DCMAKE_INSTALL_PREFIX=${FIREBASE_INSTALL_DIR}
-DFIREBASE_DOWNLOAD_DIR=${FIREBASE_DOWNLOAD_DIR}
-DFIREBASE_EXTERNAL_PLATFORM=${external_platform}
-DDOWNLOAD_CURL=${DOWNLOAD_CURL}
-DDOWNLOAD_FLATBUFFERS=${DOWNLOAD_FLATBUFFERS}
-DDOWNLOAD_LIBUV=${DOWNLOAD_LIBUV}
-DDOWNLOAD_NANOPB=${DOWNLOAD_NANOPB}
-DDOWNLOAD_UWEBSOCKETS=${DOWNLOAD_UWEBSOCKETS}
-DDOWNLOAD_ZLIB=${DOWNLOAD_ZLIB}
${PROJECT_SOURCE_DIR}/cmake/external
OUTPUT_FILE ${PROJECT_BINARY_DIR}/external/output_cmake_config.txt
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/external
Expand All @@ -60,20 +82,24 @@ function(download_external_sources)
)
endfunction()

# Populates directory variables for the given name, to the location that name
# would be in after a call to download_external_sources.
function(populate_external_source_vars NAME)
set(${NAME}_SOURCE_DIR "${FIREBASE_BINARY_DIR}/external/src/${NAME}"
PARENT_SCOPE)
set(${NAME}_BINARY_DIR "${FIREBASE_BINARY_DIR}/external/src/${NAME}-build"
PARENT_SCOPE)
endfunction()
# Populates directory variables for the given name to the location that name
# would be in after a call to download_external_sources, if the variable is
# not already a valid directory.
# Adds the source directory as a subdirectory if a CMakeLists file is found.
function(add_external_library NAME)
string(TOUPPER ${NAME} UPPER_NAME)
if (NOT EXISTS ${${UPPER_NAME}_SOURCE_DIR})
set(${UPPER_NAME}_SOURCE_DIR "${FIREBASE_BINARY_DIR}/external/src/${NAME}")
set(${UPPER_NAME}_SOURCE_DIR "${${UPPER_NAME}_SOURCE_DIR}" PARENT_SCOPE)
endif()

# Adds the given library's location as a subdirectory that the caller uses.
function(add_external_subdirectory NAME)
add_subdirectory(
${FIREBASE_BINARY_DIR}/external/src/${NAME}
${FIREBASE_BINARY_DIR}/external/src/${NAME}-build
EXCLUDE_FROM_ALL
)
endfunction()
if (NOT EXISTS ${${UPPER_NAME}_BINARY_DIR})
set(${UPPER_NAME}_BINARY_DIR "${${UPPER_NAME}_SOURCE_DIR}-build")
set(${UPPER_NAME}_BINARY_DIR "${${UPPER_NAME}_BINARY_DIR}" PARENT_SCOPE)
endif()

if (EXISTS "${${UPPER_NAME}_SOURCE_DIR}/CMakeLists.txt")
add_subdirectory(${${UPPER_NAME}_SOURCE_DIR} ${${UPPER_NAME}_BINARY_DIR}
EXCLUDE_FROM_ALL)
endif()
endfunction()
4 changes: 2 additions & 2 deletions database/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ if(ANDROID OR IOS)
set(additional_DEFINES)
else()
set(additional_include_DIR
${flatbuffers_SOURCE_DIR}/include
${FLATBUFFERS_SOURCE_DIR}/include
${OPENSSL_INCLUDE_DIR}
${uWebSockets_SOURCE_DIR}/..)
${UWEBSOCKETS_SOURCE_DIR}/..)

set(additional_link_LIB
flatbuffers
Expand Down
2 changes: 1 addition & 1 deletion messaging/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ target_include_directories(firebase_messaging
if(ANDROID)
target_include_directories(firebase_messaging
PRIVATE
${flatbuffers_SOURCE_DIR}/include
${FLATBUFFERS_SOURCE_DIR}/include
)
endif()
target_compile_definitions(firebase_messaging
Expand Down
2 changes: 1 addition & 1 deletion remote_config/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ if(ANDROID OR IOS OR use_stub)
set(additional_link_LIB)
else()
set(additional_include_DIR
${flatbuffers_SOURCE_DIR}/include
${FLATBUFFERS_SOURCE_DIR}/include
${NANOPB_INCLUDE_DIRS}
${PROJECT_BINARY_DIR}/..)
set(additional_link_LIB
Expand Down

0 comments on commit 5c15a6e

Please sign in to comment.