From dfe58758411ecf6331e494405d50b41e8f0b0d4c Mon Sep 17 00:00:00 2001 From: Pauli Date: Tue, 7 Jul 2020 20:24:27 +0300 Subject: [PATCH 1/7] Set default build type to Release The build type is left empty if CMakeLists.txt doesn't set it before first project call. Signed-off-by: Pauli --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f069f7d..f26e0e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required (VERSION 2.6) +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif () + project (ww-deal-server) add_subdirectory(server) From 3f519201c9eb0ec79548bd807b28eed3ee9f7f7e Mon Sep 17 00:00:00 2001 From: Pauli Date: Tue, 7 Jul 2020 20:27:55 +0300 Subject: [PATCH 2/7] Add install target for api-server Signed-off-by: Pauli --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f26e0e2..f5c6e14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,5 +6,12 @@ endif () project (ww-deal-server) +include(GNUInstallDirs) + add_subdirectory(server) add_subdirectory(ww-deal) + +install(TARGETS api-server + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT Runtime + ) From f58bd8595b5dda78a596cc37e371cbdf8c50719c Mon Sep 17 00:00:00 2001 From: Pauli Date: Tue, 7 Jul 2020 20:30:01 +0300 Subject: [PATCH 3/7] Use standard way to set C++ version and link to threads CMake offers standardized way to select C++ version. This method checks if requested version is supported and sets correct compiler flags. Thread support should use find_package to get system specific compiler and linker flags. Signed-off-by: Pauli --- server/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index bba93bb..e00113b 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -1,8 +1,12 @@ cmake_minimum_required (VERSION 3.2) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + project(api-server) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -pg -g3" ) +find_package(Threads) include(ExternalProject) @@ -34,4 +38,4 @@ file(GLOB SRCS add_executable(${PROJECT_NAME} ${SRCS} ) add_dependencies(${PROJECT_NAME} PISTACHE NLOHMANN) -target_link_libraries(${PROJECT_NAME} pistache pthread wwdeal) +target_link_libraries(${PROJECT_NAME} pistache Threads::Threads wwdeal) From f56284ac963067f88e29695a4d16cf0da1999b3a Mon Sep 17 00:00:00 2001 From: Pauli Date: Tue, 7 Jul 2020 20:34:09 +0300 Subject: [PATCH 4/7] Use target include directories Preferred method to change any compiler settings is to set them for a specific target with visibility flags. PRIVATE means include directories are used only compiling the target. Any depending target won't inherit directories listed for the target. Signed-off-by: Pauli --- server/CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index e00113b..39f8c3a 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -25,10 +25,6 @@ ExternalProject_Add(NLOHMANN include_directories(${EXTERNAL_INSTALL_LOCATION}/include) link_directories(${EXTERNAL_INSTALL_LOCATION}/lib) -include_directories(model) -include_directories(api) -include_directories(impl) - file(GLOB SRCS ${CMAKE_CURRENT_SOURCE_DIR}/api/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/impl/*.cpp @@ -37,5 +33,6 @@ file(GLOB SRCS ) add_executable(${PROJECT_NAME} ${SRCS} ) +target_include_directories(${PROJECT_NAME} PRIVATE model api impl) add_dependencies(${PROJECT_NAME} PISTACHE NLOHMANN) target_link_libraries(${PROJECT_NAME} pistache Threads::Threads wwdeal) From 1709d3ba01f9bc7fc497317c51fb33c2cdd1c089 Mon Sep 17 00:00:00 2001 From: Pauli Date: Tue, 7 Jul 2020 20:37:56 +0300 Subject: [PATCH 5/7] Forward prefix and build type to external projects External projects should be build with same build type and prefix. This allows better control over build process. I also added RPATH configuration to make sure installed binary can find libpistache.so. Signed-off-by: Pauli --- server/CMakeLists.txt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 39f8c3a..ad91256 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -10,20 +10,20 @@ find_package(Threads) include(ExternalProject) -set(EXTERNAL_INSTALL_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/external) - ExternalProject_Add(PISTACHE GIT_REPOSITORY https://github.com/oktal/pistache.git - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) ExternalProject_Add(NLOHMANN GIT_REPOSITORY https://github.com/nlohmann/json.git - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION} -DJSON_BuildTests=Off + BINARY_DIR NLOHMANN-prefix/build + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DJSON_BuildTests=Off + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) -include_directories(${EXTERNAL_INSTALL_LOCATION}/include) -link_directories(${EXTERNAL_INSTALL_LOCATION}/lib) file(GLOB SRCS ${CMAKE_CURRENT_SOURCE_DIR}/api/*.cpp @@ -34,5 +34,11 @@ file(GLOB SRCS add_executable(${PROJECT_NAME} ${SRCS} ) target_include_directories(${PROJECT_NAME} PRIVATE model api impl) + +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_INSTALL_PREFIX}/include) +target_link_directories(${PROJECT_NAME} PRIVATE ${CMAKE_INSTALL_PREFIX}/lib) + +set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) + add_dependencies(${PROJECT_NAME} PISTACHE NLOHMANN) target_link_libraries(${PROJECT_NAME} pistache Threads::Threads wwdeal) From 52647f6f20ed00f930befaeb741ed29d0e1f02a4 Mon Sep 17 00:00:00 2001 From: Pauli Date: Tue, 7 Jul 2020 20:47:14 +0300 Subject: [PATCH 6/7] Use submodules for external projects and optimize image build My target was to reduce build times for local testing and images. There is many interlinked changes to image building which should make caching better. The biggest changes is external projects using submodules for sources. This allows build process to reduce numbers of times sources are downloaded. Image building still uses remote source. Changes allow better caching for sources. Submodules use relative paths to make sure submodule update uses same protocol as clone. Image build is split two variants. The developer build uses local/* tag to allow quick testing using sources from the working tree. On other hand release builds use git repository with a tag. This makes sure release build will use correct sources without any local changes. Base image and build dependencies install was changed. Base image was upgraded to the latest Debian stable release. Package install command specifies all build dependencies explicitly and avoids install recommendations. The last bit of changes makes sure deployed image includes only runtime dependencies. It adds an empty image where binaries are copied from the build image. Signed-off-by: Pauli --- .gitignore | 7 ++++- .gitmodules | 11 ++++++- CMakeLists.txt | 12 ++++++++ Dockerfile | 71 +++++++++++++++++++++++++++++++++++-------- Makefile | 15 +++++++-- README.md | 1 + json | 1 + pistache | 1 + server/.gitignore | 1 - server/CMakeLists.txt | 27 +--------------- 10 files changed, 102 insertions(+), 45 deletions(-) create mode 160000 json create mode 160000 pistache delete mode 100644 server/.gitignore diff --git a/.gitignore b/.gitignore index 84c048a..fe2e96b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ -/build/ +.git/ +*build*/ +/tags +/.dockerignore +*~ +*.swp diff --git a/.gitmodules b/.gitmodules index 88f087f..47818de 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,12 @@ [submodule "ww-deal"] path = ww-deal - url = git@github.com:woefulwabbit/ww-deal.git + url = ../../woefulwabbit/ww-deal.git + branch = master +[submodule "pistache"] + path = pistache + url = ../../oktal/pistache.git + branch = master +[submodule "json"] + path = json + url = ../../nlohmann/json.git + branch = master diff --git a/CMakeLists.txt b/CMakeLists.txt index f5c6e14..38ca6dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,18 @@ endif () project (ww-deal-server) +find_package(Pistache 0.0.2) +find_package(nlohmann_json) +if (NOT Pistache_FOUND) + add_subdirectory(${CMAKE_SOURCE_DIR}/pistache) +endif () +if (NOT nlohmann_json_FOUND) + if (NOT DEFINED JSON_BuildTests) + set(JSON_BuildTests OFF) + endif () + add_subdirectory(json) +endif () + include(GNUInstallDirs) add_subdirectory(server) diff --git a/Dockerfile b/Dockerfile index ad85820..bdfa73f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,66 @@ -FROM debian:stretch as deal-builder +FROM debian:buster as deal-builder +# Install build dependecies RUN apt-get update -RUN apt-get install -y \ - git \ - build-essential \ - cmake +RUN apt-get install -y --no-install-recommends \ + g++ \ + cmake \ + ninja-build -RUN git clone https://github.com/online-bridge-hackathon/Deal.git && \ - cd /Deal - -WORKDIR /Deal +ARG PREFIX=/usr/local +ARG BUILD_TYPE=RelWithDepInfo -RUN git clone https://github.com/woefulwabbit/ww-deal.git +RUN mkdir -p /build/pistache && mkdir -p /build/json -RUN cmake . && \ - make +# Fetch source from the build context +ADD pistache /sources/pistache +# Build the pistache library +RUN cmake -DCMAKE_INSTALL_PREFIX=$PREFIX \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ + -G Ninja \ + -S /sources/pistache \ + -B /build/pistache && \ + ninja install -C /build/pistache -WORKDIR /Deal/server +ADD json /sources/json +# Build the json library +RUN cmake -DCMAKE_INSTALL_PREFIX=$PREFIX \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ + -DJSON_BuildTests=Off \ + -G Ninja \ + -S /sources/json \ + -B /build/json && \ + ninja install -C /build/json +ADD ww-deal /sources/ww-deal +ADD server /sources/server +ADD CMakeLists.txt /sources/ + +# Build sources +RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -G Ninja \ + -S /sources \ + -B /build && \ + ninja install -C /build + +# Create a clean server image +FROM debian:buster as deal-image + +# Install runtime dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + libatomic1 + +# Copy required runtime files +COPY --from=deal-builder /usr/local/lib/libpistache.so.0.* /usr/local/lib/ +COPY --from=deal-builder /usr/local/bin/api-server /usr/local/bin/api-server + +# Add the library to the lookup cache +RUN ln -s /usr/local/lib/libpistache.so.0.* /usr/local/lib/libpistache.so.0 && \ + ldconfig + +# Setup runtime options for the server +WORKDIR /usr/local/bin +EXPOSE 8080/tcp CMD ./api-server diff --git a/Makefile b/Makefile index 4c1c212..a5ea7f3 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ DOCKER_REPO ?= gcr.io/online-bridge-hackathon-2020 VERSION ?= $(shell cat VERSION) DOCKER_TAG=${DOCKER_REPO}/deal-api:${VERSION} +DEV_DOCKER_TAG=local/deal-api:${VERSION} +GIT_REPO ?= https://github.com/online-bridge-hackathon/Deal.git EXTERNAL_ADDRES ?= deal.hackathon.globalbridge.app @@ -9,12 +11,19 @@ GCP_PROJECT ?= online-bridge-hackathon-2020 GKE_CLUSTER_NAME ?= hackathon-cluster GKE_ZONE ?= europe-west3-b -release: build push +all: build + @echo + @echo "Run local test server using: docker run -t ${DEV_DOCKER_TAG}" + +release: push build: - docker build -t ${DOCKER_TAG} . + docker build -t ${DEV_DOCKER_TAG} . + +build-release: + docker build -t ${DOCKER_TAG} "${GIT_REPO}#${VERSION}" -push: +push: build-release docker push ${DOCKER_TAG} deploy: set_gcp_context ensure_ns diff --git a/README.md b/README.md index 9ae149f..c97fcf2 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ A web service that accepts request by APIs and returns 1+ bridge deals # Build ``` +git submodule update --init mkdir build cd build cmake .. diff --git a/json b/json new file mode 160000 index 0000000..efcc826 --- /dev/null +++ b/json @@ -0,0 +1 @@ +Subproject commit efcc826ecb9b55893397f749e5514316ba8629bb diff --git a/pistache b/pistache new file mode 160000 index 0000000..bcad665 --- /dev/null +++ b/pistache @@ -0,0 +1 @@ +Subproject commit bcad665e721959ecd92217204d5f7cd6270d6229 diff --git a/server/.gitignore b/server/.gitignore deleted file mode 100644 index f6359aa..0000000 --- a/server/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/external/ diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index ad91256..67ef67b 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -6,25 +6,6 @@ set(CMAKE_CXX_EXTENSIONS OFF) project(api-server) -find_package(Threads) - -include(ExternalProject) - -ExternalProject_Add(PISTACHE - GIT_REPOSITORY https://github.com/oktal/pistache.git - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -) - -ExternalProject_Add(NLOHMANN - GIT_REPOSITORY https://github.com/nlohmann/json.git - BINARY_DIR NLOHMANN-prefix/build - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} - -DJSON_BuildTests=Off - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -) - file(GLOB SRCS ${CMAKE_CURRENT_SOURCE_DIR}/api/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/impl/*.cpp @@ -34,11 +15,5 @@ file(GLOB SRCS add_executable(${PROJECT_NAME} ${SRCS} ) target_include_directories(${PROJECT_NAME} PRIVATE model api impl) +target_link_libraries(${PROJECT_NAME} pistache_shared wwdeal nlohmann_json) -target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_INSTALL_PREFIX}/include) -target_link_directories(${PROJECT_NAME} PRIVATE ${CMAKE_INSTALL_PREFIX}/lib) - -set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) - -add_dependencies(${PROJECT_NAME} PISTACHE NLOHMANN) -target_link_libraries(${PROJECT_NAME} pistache Threads::Threads wwdeal) From 37aeebbe6877a1cf71675b9704be2b7f2859bc7d Mon Sep 17 00:00:00 2001 From: Pauli Date: Wed, 8 Jul 2020 14:26:33 +0300 Subject: [PATCH 7/7] Add .dockerignore which is generated from .gitignore It appears that .dockerignore use different syntax compared to .gitignore. This requires a bit processing to reuse .gitignore for Docker build. --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a5ea7f3..acc0dbf 100644 --- a/Makefile +++ b/Makefile @@ -17,10 +17,13 @@ all: build release: push -build: +.dockerignore: .gitignore + sed 's#^[^/]#**/\0#' < $< > $@ + +build: .dockerignore docker build -t ${DEV_DOCKER_TAG} . -build-release: +build-release: .dockerignore docker build -t ${DOCKER_TAG} "${GIT_REPO}#${VERSION}" push: build-release