diff --git a/.docker/netremote-dev/Dockerfile b/.docker/netremote-dev/Dockerfile index 41caadac..04f5ceb6 100644 --- a/.docker/netremote-dev/Dockerfile +++ b/.docker/netremote-dev/Dockerfile @@ -1,5 +1,5 @@ -FROM ubuntu:mantic as netremote +FROM ubuntu:mantic as netremote-build # Set arguments used only in this Dockerfile. ARG build_date="2023-11-09T19:51:18Z" @@ -21,8 +21,8 @@ LABEL org.label-schema.schema-version = "1.0" # 1. Update package cache. # sudo apt-get update # -# 2. Install core build tools: -# sudo apt-get install -y --no-install-recommends build-essential ca-certificates cmake curl dotnet7 git gnupg linux-libc-dev ninja-build pkg-config tar unzip zip +# 2. Install core build tools and dependencies: +# sudo apt-get install -y --no-install-recommends build-essential ca-certificates cmake curl dotnet7 git gnupg linux-libc-dev ninja-build pkg-config tar unzip zip libnl-3-dev libssl-dev libnl-genl-3-dev libdbus-c++-dev libnl-route-3-dev # # 3. Remove llvm 16 toolchain packages to avoid conflicts with llvm 17 toolchain. # sudo apt-get remove -y --purge clang-16* lldb-16* llvm-16* @@ -35,13 +35,13 @@ LABEL org.label-schema.schema-version = "1.0" # rm llvm.sh # # 5. Install development dependency packages: -# sudo apt-get install -y --no-install-recommends libnl-3-dev libnl-genl-3-dev libssl-dev libdbus-c++-dev libnl-route-3-dev bc bison dwarves flex libelf-dev dos2unix file gnupg2 iproute2 mtools neofetch rsync ssh sudo emacs gdb kmod nano policycoreutils-python-utils python-is-python3 vim +# sudo apt-get install -y --no-install-recommends bc bison dwarves flex libelf-dev dos2unix file gnupg2 iproute2 mtools neofetch rsync ssh sudo emacs gdb kmod nano policycoreutils-python-utils python-is-python3 vim # # Install packages. RUN apt-get update && \ apt-get install -qq -y --no-install-recommends \ - # Project build dependencies. + # Core project build dependencies. # build-essential ca-certificates cmake curl dotnet7 git gnupg linux-libc-dev ninja-build pkg-config tar unzip zip build-essential \ ca-certificates \ @@ -55,7 +55,16 @@ RUN apt-get update && \ pkg-config \ tar \ unzip \ - zip + zip \ + # hostapd build dependencies. + # libnl-3-dev libssl-dev libnl-genl-3-dev + libnl-3-dev \ + libnl-genl-3-dev \ + libssl-dev \ + # wpa_supplicant build dependencies. + # libnl-3-dev libssl-dev libnl-genl-3-dev libdbus-c++-dev libnl-route-3-dev + libdbus-c++-dev \ + libnl-route-3-dev # Install complete llvm toolchain using automatic installation script. # lsb-release, software-properties-common, and wget are required by the script. @@ -76,20 +85,34 @@ RUN apt-get install -qq -y --no-install-recommends \ RUN apt-get clean && \ rm -rf /var/lib/apt/lists/* -FROM netremote as netremote-dev +# Set environment variables for external vcpkg to support binary caching +ENV VCPKG_ROOT_BASE=/vcpkg +ENV VCPKG_BINARY_CACHE=${VCPKG_ROOT_BASE}/cache +ENV VCPKG_ROOT=${VCPKG_ROOT_BASE}/vcpkg +ENV VCPKG_DEFAULT_BINARY_CACHE=${VCPKG_BINARY_CACHE} + +WORKDIR ${VCPKG_ROOT_BASE} + +RUN mkdir -p ${VCPKG_BINARY_CACHE} + +# Obtain vcpkg, bootstrap it, and install dependencies. +COPY vcpkg.json . + +RUN git clone https://github.com/microsoft/vcpkg.git --depth 1 && \ + ./vcpkg/bootstrap-vcpkg.sh && \ + ./vcpkg/vcpkg install --clean-buildtrees-after-build --clean-downloads-after-build + +# Copy build entrypoint script. +COPY --chmod=0755 entrypoint-build.sh /bin/entrypoint-build.sh + +# Build the repository. +ENTRYPOINT [ "/bin/entrypoint-build.sh" ] + +FROM netremote-build as netremote-dev # Install packages. RUN apt-get update && \ apt-get install -y --no-install-recommends \ - # hostapd build dependencies. - # libnl-3-dev libssl-dev libnl-genl-3-dev - libnl-3-dev \ - libnl-genl-3-dev \ - libssl-dev \ - # wpa_supplicant build dependencies. - # libnl-3-dev libssl-dev libnl-genl-3-dev libdbus-c++-dev libnl-route-3-dev - libdbus-c++-dev \ - libnl-route-3-dev \ # WSL2 kernel development dependencies. # build-essential flex bison dwarves libssl-dev libelf-dev bc bc \ diff --git a/.docker/netremote-dev/entrypoint-build.sh b/.docker/netremote-dev/entrypoint-build.sh new file mode 100644 index 00000000..6dbd6f22 --- /dev/null +++ b/.docker/netremote-dev/entrypoint-build.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -euf -o pipefail + +REPOSITORY_ROOT=${1:-${PWD}} + +# Verify the repository root is a git repository. +if [[ ! -d ${REPOSITORY_ROOT}/.git ]]; then + echo "Repository root is not a git repository: ${REPOSITORY_ROOT}" + exit 1 +fi + +# Verify the vcpkg toolchain file is present. +if [[ ! -f ${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake ]]; then + echo "vcpkg cmake toolchain file not found: ${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + exit 1 +fi + +# Assign cmake presets. +# TODO: these should be passed in as arguments instead. +PRESET_CONFIGURE=release-linux +PRESET_BUILD=release-linux-debug +BUILD_CONFIG=Debug + +# Add the workspace directory to the safe directory list. +git config --global --add safe.directory ${REPOSITORY_ROOT} + +# Change to the root of the repo. +cd ${REPOSITORY_ROOT} +cmake --preset ${PRESET_CONFIGURE} +cmake --build --preset ${PRESET_BUILD} +cmake --install out/build/${PRESET_CONFIGURE} --config ${BUILD_CONFIG} diff --git a/.docker/netremote-dev/vcpkg.json b/.docker/netremote-dev/vcpkg.json new file mode 100644 index 00000000..d85fddb7 --- /dev/null +++ b/.docker/netremote-dev/vcpkg.json @@ -0,0 +1,19 @@ +{ + "name": "netremote", + "version-string": "1", + "dependencies": [ + { + "name": "grpc", + "host": true + }, + "cli11", + "protobuf", + "catch2", + "plog", + "magic-enum", + { + "name": "wil", + "platform": "windows" + } + ] +} \ No newline at end of file diff --git a/.github/actions/build-with-docker/action.yml b/.github/actions/build-with-docker/action.yml new file mode 100644 index 00000000..760f2ae7 --- /dev/null +++ b/.github/actions/build-with-docker/action.yml @@ -0,0 +1,8 @@ + +name: 'Build' +description: 'Build the repository in a Docker container' +runs: + using: 'docker' + image: 'docker://abeltrano/netremote-build:latest' + args: + - '/github/workspace' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..ff3cb007 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,14 @@ + +on: + pull_request: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build in container + uses: ./.github/actions/build-with-docker + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index b1569b5c..c4acbbd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) include(vcpkg) # Tell vcpkg to use the submodule root directory as the vcpkg root, and then configure it. -set(VCPKG_SUBMODULE_ROOT ${CMAKE_CURRENT_LIST_DIR}/vcpkg) +set(VCPKG_SUBMODULE_ROOT ${CMAKE_CURRENT_LIST_DIR}/vcpkg CACHE PATH "Location of vcpkg submodule root") vcpkg_configure(SUBMODULE_ROOT ${VCPKG_SUBMODULE_ROOT}) project(netremote diff --git a/CMakePresets.json b/CMakePresets.json index a2b3cadb..8c0a8b0c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -39,6 +39,22 @@ "binaryDir": "${sourceDir}/out/build/${presetName}", "installDir": "${sourceDir}/out/install/${presetName}" }, + { + "name": "linux-base", + "hidden": true, + "cacheVariables": { + "CMAKE_CXX_COMPILER": "/usr/bin/clang++-17", + "CMAKE_C_COMPILER": "/usr/bin/clang-17", + "CMAKE_GENERATOR": "Ninja" + } + }, + { + "name": "windows-base", + "hidden": true, + "cacheVariables": { + "CMAKE_GENERATOR": "Visual Studio 17 2022" + } + }, { "name": "dev-base", "hidden": true, @@ -63,13 +79,9 @@ "description": "Development build for inner-loop on Linux", "inherits": [ "os-linux", + "linux-base", "dev" - ], - "cacheVariables": { - "CMAKE_CXX_COMPILER": "/usr/bin/clang++-17", - "CMAKE_C_COMPILER": "/usr/bin/clang-17", - "CMAKE_GENERATOR": "Ninja" - } + ] }, { "name": "dev-windows", @@ -77,18 +89,103 @@ "description": "Development build for inner-loop on Windows", "inherits": [ "os-windows", + "windows-base", "dev" + ] + }, + { + "name": "release-base", + "hidden": true, + "inherits": [ + "in-source-build" + ] + }, + { + "name": "release-linux", + "inherits":[ + "os-linux", + "linux-base", + "release-base" ], "cacheVariables": { - "CMAKE_GENERATOR": "Visual Studio 17 2022" + "CMAKE_GENERATOR": "Ninja Multi-Config" } + }, + { + "name": "release-windows", + "inherits":[ + "os-windows", + "windows-base", + "release-base" + ] } ], "buildPresets": [ { - "name": "dev", - "configurePreset": "dev", + "name": "dev-linux", + "configurePreset": "dev-linux" + }, + { + "name": "dev-windows", + "configurePreset": "dev-windows" + }, + { + "name": "cfg-debug", + "hidden": true, "configuration": "Debug" + }, + + { + "name": "cfg-release", + "hidden": true, + "configuration": "Release" + }, + { + "name": "cfg-release-with-debug", + "hidden": true, + "configuration": "RelWithDebInfo" + }, + { + "name": "release-linux-debug", + "configurePreset": "release-linux", + "inherits": [ + "cfg-debug" + ] + }, + { + "name": "release-linux-release", + "configurePreset": "release-linux", + "inherits": [ + "cfg-release" + ] + }, + { + "name": "release-linux-release-with-debug", + "configurePreset": "release-linux", + "inherits": [ + "cfg-release-with-debug" + ] + }, + { + "name": "release-windows-debug", + "configurePreset": "release-windows", + "inherits": [ + "cfg-debug" + ] + }, + { + "name": "release-windows-release", + "configurePreset": "release-windows", + "inherits": [ + "cfg-release" + ] + }, + { + "name": "release-windows-release-with-debug", + "configurePreset": "release-windows", + "inherits": [ + "cfg-release-with-debug" + ] } ], "testPresets": [ @@ -108,6 +205,7 @@ }, { "name": "local-base", + "hidden": true, "description": "Run tests that don't require a remote connection", "inherits": [ "test-common" diff --git a/cmake/vcpkg.cmake b/cmake/vcpkg.cmake index feca13dc..b9917e19 100644 --- a/cmake/vcpkg.cmake +++ b/cmake/vcpkg.cmake @@ -17,30 +17,30 @@ function(vcpkg_configure) ${ARGN} ) -# If the vcpkg root has been specified externally, use it. -if (DEFINED ENV{VCPKG_ROOT}) - set(VCPKG_ROOT "$ENV{VCPKG_ROOT}") -# Otherwise, use the specified submodule root. -else() - set(VCPKG_ROOT ${VCPKG_SUBMODULE_ROOT}) - - find_package(Git REQUIRED) - - # Initialize vcpkg sub-module if not already done. - if (NOT EXISTS ${VCPKG_SUBMODULE_ROOT}/.git) - execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive -- ${VCPKG_SUBMODULE_ROOT} - WORKING_DIRECTORY ${VCPKG_SUBMODULE_ROOT}/../ - COMMAND_ERROR_IS_FATAL ANY) + # If the vcpkg root has been specified externally, use it. + if (DEFINED ENV{VCPKG_ROOT}) + set(VCPKG_ROOT "$ENV{VCPKG_ROOT}") + # Otherwise, use the specified submodule root. + else() + set(VCPKG_ROOT ${VCPKG_SUBMODULE_ROOT}) + + find_package(Git REQUIRED) + + # Initialize vcpkg sub-module if not already done. + if (NOT EXISTS ${VCPKG_SUBMODULE_ROOT}/.git) + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive -- ${VCPKG_SUBMODULE_ROOT} + WORKING_DIRECTORY ${VCPKG_SUBMODULE_ROOT}/../ + COMMAND_ERROR_IS_FATAL ANY) + endif() + + # Ignore all changes to the submodule tree. + get_filename_component(VCPKG_SUBMODULE_NAME ${VCPKG_SUBMODULE_ROOT} NAME) + execute_process(COMMAND ${GIT_EXECUTABLE} "config submodule.${VCPKG_SUBMODULE_NAME}.ignore all" + WORKING_DIRECTORY ${VCPKG_SUBMODULE_ROOT}../ + ) endif() - # Ignore all changes to the submodule tree. - get_filename_component(VCPKG_SUBMODULE_NAME ${VCPKG_SUBMODULE_ROOT} NAME) - execute_process(COMMAND ${GIT_EXECUTABLE} "config submodule.${VCPKG_SUBMODULE_NAME}.ignore all" - WORKING_DIRECTORY ${VCPKG_SUBMODULE_ROOT}../ - ) -endif() - -# Set the CMake toolchain file to use vcpkg. -set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE FILEPATH "CMake toolchain file") + # Set the CMake toolchain file to use vcpkg. + set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE FILEPATH "CMake toolchain file") endfunction()