diff --git a/.github/workflows/install.yaml b/.github/workflows/install.yaml index 8c852ecb..70b9557b 100644 --- a/.github/workflows/install.yaml +++ b/.github/workflows/install.yaml @@ -29,23 +29,32 @@ jobs: vcpkg-${{ runner.os }}- - name: configure run: > - cmake -S . -B ${{runner.workspace}}/build -GNinja -DBUILD_TESTING=OFF + cmake -S . -B ${{runner.temp}}/build -GNinja -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=${{runner.temp}}/staging -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake - name: build - run: cmake --build ${{runner.workspace}}/build + run: cmake --build ${{runner.temp}}/build - name: install - working-directory: ${{runner.workspace}}/build - run: cmake --build ${{runner.workspace}}/build --target install + run: cmake --build ${{runner.temp}}/build --target install + - name: create-overlay + # We want to test with the *current* version of + # `functions-framework-cpp`, not with the version published by vcpkg. + # One can do that by creating an vcpkg overlay. + run: > + mkdir -p "${{runner.temp}}/quickstart/vcpkg-overlays" && + cp build_scripts/vcpkg-overlays/* "${{runner.temp}}/quickstart/vcpkg-overlays" && + sed -i -e "s;/usr/local/share/gcf;${{github.workspace}};" \ + ${{runner.temp}}/quickstart/vcpkg-overlays/portfile.cmake - name: test-configure + env: + VCPKG_OVERLAY_PORTS: "${{runner.temp}}/quickstart/vcpkg-overlays" run: > - cmake -S google/cloud/functions/quickstart -B ${{runner.workspace}}/build-quickstart -GNinja - -DCMAKE_PREFIX_PATH=${{runner.temp}}/staging + cmake -S google/cloud/functions/quickstart -B "${{runner.temp}}/quickstart/build" -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake - name: test-build - run: cmake --build ${{runner.workspace}}/build-quickstart + run: cmake --build ${{runner.temp}}/quickstart/build build-ubuntu-focal-shared: name: ubuntu-20.04-shared @@ -65,19 +74,29 @@ jobs: - uses: actions/checkout@v2 - name: configure run: > - cmake -S . -B ${{runner.workspace}}/build -GNinja + cmake -S . -B ${{runner.temp}}/build -GNinja -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=${{runner.temp}}/staging -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - name: build - run: cmake --build ${{runner.workspace}}/build + run: cmake --build ${{runner.temp}}/build - name: install - working-directory: ${{runner.workspace}}/build - run: cmake --build ${{runner.workspace}}/build --target install + run: cmake --build ${{runner.temp}}/build --target install + - name: create-overlay + # We want to test with the *current* version of + # `functions-framework-cpp`, not with the version published by vcpkg. + # One can do that by creating an vcpkg overlay. + run: > + mkdir -p "${{runner.temp}}/quickstart/vcpkg-overlays" && + cp build_scripts/vcpkg-overlays/* "${{runner.temp}}/quickstart/vcpkg-overlays" && + sed -i -e "s;/usr/local/share/gcf;${{github.workspace}};" \ + ${{runner.temp}}/quickstart/vcpkg-overlays/portfile.cmake - name: test-configure + env: + VCPKG_OVERLAY_PORTS: "${{runner.temp}}/quickstart/vcpkg-overlays" run: > - cmake -S google/cloud/functions/quickstart -B ${{runner.workspace}}/build-quickstart -GNinja - -DCMAKE_PREFIX_PATH=${{runner.temp}}/staging + cmake -S google/cloud/functions/quickstart -B "${{runner.temp}}/quickstart/build" -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake - name: test-build - run: cmake --build ${{runner.workspace}}/build-quickstart + run: cmake --build ${{runner.temp}}/quickstart/build diff --git a/google/cloud/functions/quickstart/CMakeLists.txt b/google/cloud/functions/quickstart/CMakeLists.txt index b6a2b6f4..8740d2e9 100644 --- a/google/cloud/functions/quickstart/CMakeLists.txt +++ b/google/cloud/functions/quickstart/CMakeLists.txt @@ -26,5 +26,5 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Threads REQUIRED) find_package(functions_framework_cpp REQUIRED) -add_executable(quickstart quickstart.cc) +add_executable(quickstart hello_function/hello_function.cc quickstart.cc) target_link_libraries(quickstart functions-framework-cpp::framework) diff --git a/google/cloud/functions/quickstart/README.md b/google/cloud/functions/quickstart/README.md new file mode 100644 index 00000000..f2d0c063 --- /dev/null +++ b/google/cloud/functions/quickstart/README.md @@ -0,0 +1,60 @@ +# Quickstart with Functions Framework for C++ + +[vcpkg-gh]: https://github.com/microsoft/vcpkg +[vcpkg-install]: https://github.com/microsoft/vcpkg#getting-started + +This directory contains a small example showing how to start using the +Functions Framework for C++. The example can be compiled as a standalone local +server, or as a container to be deployed in Cloud Run or a similar environment. + +## How-to Guide: Local Development + +### Installing Dependencies + +> :warning: `functions-framework-cpp` is not published in the main branch +> for vcpkg yet. Use this branch: +> +> https://github.com/coryan/vcpkg/tree/new-port-functions-framework-cpp + +The Functions Framework for C++ recommends using [vcpkg][vcpkg-gh] to manage +dependencies. This is how dependencies will be installed and compiled in the +production environment, so you probably want to use the same approach in +development. Follow the [vcpkg install instructions][vcpkg-install] to get +vcpkg installed on your development environment. For example, on Linux you +would use: + +```shell +cd $HOME +git clone https://github.com/microsoft/vcpkg +(cd vcpkg && ./bootstrap.sh) +``` + +Once vcpkg is compiled you can build the quickstart example using: + +> :warning: the first time you build the framework it might take several +> minutes, maybe as much as 1/2 hour, depending on your workstation +> performance. Future builds, even in different directories, should be +> faster as `vcpkg` caches binary artifacts in `$HOME/.cache/vcpkg`. + +```shell +cd $HOME/functions-framework-cpp/google/cloud/functions/quickstart +cmake -H. -B.build -DCMAKE_TOOLCHAIN_FILE=$HOME/vcpkg/scripts/buildsystems/vcpkg.cmake +``` + +This will produce a standalone HTTP server, which you can run locally using: + +```shell +.build/quickstart --port 8080 +``` + +Test this program using `curl`. In a separate shell run: + +```shell +curl http://localhost:8080 +``` + +And terminate the program gracefully using: + +```shell +curl http://localhost:8080/quit/program/0 +``` diff --git a/google/cloud/functions/quickstart/hello_function/hello_function.cc b/google/cloud/functions/quickstart/hello_function/hello_function.cc new file mode 100644 index 00000000..b5f9aa1c --- /dev/null +++ b/google/cloud/functions/quickstart/hello_function/hello_function.cc @@ -0,0 +1,24 @@ +// Copyright 2021 Google LLC +// +// 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 + +namespace gcf = ::google::cloud::functions; + +gcf::HttpResponse HelloWorld(gcf::HttpRequest request) { // NOLINT + gcf::HttpResponse response; + response.set_header("Content-Type", "text/plain"); + response.set_payload("Hello World\n"); + return response; +} diff --git a/google/cloud/functions/quickstart/quickstart.cc b/google/cloud/functions/quickstart/quickstart.cc index 0784da78..3c37a588 100644 --- a/google/cloud/functions/quickstart/quickstart.cc +++ b/google/cloud/functions/quickstart/quickstart.cc @@ -15,21 +15,19 @@ #include #include -namespace { -using ::google::cloud::functions::HttpRequest; -using ::google::cloud::functions::HttpResponse; +namespace gcf = ::google::cloud::functions; +extern gcf::HttpResponse HelloWorld(gcf::HttpRequest); -HttpResponse HelloWorld(HttpRequest const& request) { - if (request.target() == "/quit/program/0") std::exit(0); +namespace { - HttpResponse response; - response.set_header("Content-Type", "text/plain"); - response.set_payload("Hello World\n"); - return response; +gcf::HttpResponse HelloWithShutdown(gcf::HttpRequest request) { // NOLINT + // Add a way to gracefully shutdown this service, mostly for testing. + if (request.target() == "/quit/program") std::exit(0); + return HelloWorld(std::move(request)); } } // namespace int main(int argc, char* argv[]) { - return ::google::cloud::functions::Run(argc, argv, HelloWorld); + return ::google::cloud::functions::Run(argc, argv, HelloWithShutdown); } diff --git a/google/cloud/functions/quickstart/vcpkg.json b/google/cloud/functions/quickstart/vcpkg.json index 4756b2fc..4fa498e4 100644 --- a/google/cloud/functions/quickstart/vcpkg.json +++ b/google/cloud/functions/quickstart/vcpkg.json @@ -1,14 +1,10 @@ { - "name": "google-functions-framework-cpp-quickstart", - "version-string": "0.0.1-dev", + "name": "functions-framework-cpp-quickstart", + "version-string": "0.4.0-dev", "port-version": 1, "homepage": "https://github.com/GoogleCloudPlatform/functions-framework-cpp/", - "description": "Functions Framework for C++.", + "description": "Quickstart with Functions Framework for C++.", "dependencies": [ - "abseil", - "boost-beast", - "boost-program-options", - "boost-serialization", - "nlohmann-json" + "functions-framework-cpp" ] }