From 6d602292cf42efa0f488ce4ddfedee261b7b6fda Mon Sep 17 00:00:00 2001 From: Mark Horvath Date: Mon, 8 Apr 2024 15:45:19 +0200 Subject: [PATCH] vscode dev container * Dev container added to build and debug the project * Docker image used for CI is updated to can be used as a base for the dev container. * CI script updated minimally to can be run without root privileges. --- .devcontainer/devcontainer.json | 35 +++++ .devcontainer/devcontainer.json.license | 3 + .devcontainer/install_deps.sh | 17 +++ .devcontainer/setup_ccache.sh | 13 ++ .devcontainer/start_qemu.sh | 12 ++ .gitignore | 1 + .gitlab-ci.yml | 2 +- .vscode/launch.json | 75 +++++++++++ .vscode/launch.json.license | 3 + .vscode/settings.json | 7 + .vscode/settings.json.license | 3 + .vscode/tasks.json | 169 ++++++++++++++++++++++++ .vscode/tasks.json.license | 3 + docker/Dockerfile | 22 +-- scripts/ci.sh | 4 +- 15 files changed, 356 insertions(+), 13 deletions(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/devcontainer.json.license create mode 100755 .devcontainer/install_deps.sh create mode 100755 .devcontainer/setup_ccache.sh create mode 100755 .devcontainer/start_qemu.sh create mode 100644 .vscode/launch.json create mode 100644 .vscode/launch.json.license create mode 100644 .vscode/settings.json create mode 100644 .vscode/settings.json.license create mode 100644 .vscode/tasks.json create mode 100644 .vscode/tasks.json.license diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..59f97f429 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,35 @@ +{ + "build" : { + "dockerfile": "../docker/Dockerfile", + "args": { + "USER": "vscode-user" + }, + "options" : [ + "--network=host" + ] + }, + "onCreateCommand" : ".devcontainer/install_deps.sh", + "postStartCommand" : ".devcontainer/setup_ccache.sh ${containerWorkspaceFolder}/.devcontainer/ccache_storage", + "containerEnv": { + "CMAKE_CXX_COMPILER_LAUNCHER": "ccache" + }, + "portsAttributes": { + "2345": { + "label": "Qemu GDB port", + "onAutoForward": "ignore" + } + }, + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "ms-vscode.cpptools", + "ms-vscode.cmake-tools" + ] + } + }, + "runArgs" : [ + "--network=host" + ], + "remoteUser": "vscode-user" +} diff --git a/.devcontainer/devcontainer.json.license b/.devcontainer/devcontainer.json.license new file mode 100644 index 000000000..468a89751 --- /dev/null +++ b/.devcontainer/devcontainer.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates + +SPDX-License-Identifier: Apache-2.0 diff --git a/.devcontainer/install_deps.sh b/.devcontainer/install_deps.sh new file mode 100755 index 000000000..6460abfc1 --- /dev/null +++ b/.devcontainer/install_deps.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 + +set -exu + +sudo apt-get update +DEBIAN_FRONTEND=noninteractive sudo apt-get install --no-install-recommends -y \ + qemu-user \ + clangd-${LLVM_VERSION} \ + ccache \ + gdb-multiarch + +# Needed to run pipx packages originally installed for the root user +sudo chmod +x /root diff --git a/.devcontainer/setup_ccache.sh b/.devcontainer/setup_ccache.sh new file mode 100755 index 000000000..f5f5b3faa --- /dev/null +++ b/.devcontainer/setup_ccache.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 + +set -exu + +CCACHE_CACHE_DIR=$1 + +mkdir -p "${CCACHE_CACHE_DIR}" +mkdir -p "${HOME}/.ccache" +echo "cache_dir = ${CCACHE_CACHE_DIR}" > "${HOME}/.ccache/ccache.conf" diff --git a/.devcontainer/start_qemu.sh b/.devcontainer/start_qemu.sh new file mode 100755 index 000000000..e2a65e39b --- /dev/null +++ b/.devcontainer/start_qemu.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 + +set -eu + +# Needed for vscode, otherwise the debugger is not started +echo "Listening on port" + +qemu-aarch64 "$@" diff --git a/.gitignore b/.gitignore index d87d84493..5c6996fbc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ build/ public/ +.devcontainer/ccache_storage diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0bfc66d87..1bb61930e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -image: registry.gitlab.arm.com/intrinsiccv/intrinsiccv:9 +image: registry.gitlab.arm.com/intrinsiccv/intrinsiccv:10 # Only run CI for main branch & merge requests workflow: diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..6375be780 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,75 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Framework tests", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/intrinsiccv/test/framework/intrinsiccv-framework-test", + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb-multiarch", + "miDebuggerServerAddress": "localhost:2345", + "targetArchitecture": "arm64", + "debugServerPath" : "${workspaceFolder}/.devcontainer/start_qemu.sh", + "debugServerArgs": "-g 2345 ${workspaceFolder}/build/intrinsiccv/test/framework/intrinsiccv-framework-test --gtest_filter=*", + "cwd": "${workspaceFolder}", + "preLaunchTask": "Build IntrinsicCV for debug", + }, + { + "name": "NEON API tests", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/intrinsiccv-debug/test/api/intrinsiccv-api-test", + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb-multiarch", + "miDebuggerServerAddress": "localhost:2345", + "targetArchitecture": "arm64", + "debugServerPath" : "${workspaceFolder}/.devcontainer/start_qemu.sh", + "debugServerArgs": "-g 2345 -cpu cortex-a53 ${workspaceFolder}/build/intrinsiccv-debug/test/api/intrinsiccv-api-test --vector-length=16 --gtest_filter=*", + "cwd": "${workspaceFolder}", + "preLaunchTask": "Build IntrinsicCV for debug", + }, + { + "name": "SVE2 API tests, 128 bits", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/intrinsiccv-debug/test/api/intrinsiccv-api-test", + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb-multiarch", + "miDebuggerServerAddress": "localhost:2345", + "targetArchitecture": "arm64", + "debugServerPath" : "${workspaceFolder}/.devcontainer/start_qemu.sh", + "debugServerArgs": "-g 2345 -cpu max,sve128=on,sme=off ${workspaceFolder}/build/intrinsiccv-debug/test/api/intrinsiccv-api-test --vector-length=16 --gtest_filter=*", + "cwd": "${workspaceFolder}", + "preLaunchTask": "Build IntrinsicCV for debug", + }, + { + "name": "SVE2 API tests, 2048 bits", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/intrinsiccv-debug/test/api/intrinsiccv-api-test", + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb-multiarch", + "miDebuggerServerAddress": "localhost:2345", + "targetArchitecture": "arm64", + "debugServerPath" : "${workspaceFolder}/.devcontainer/start_qemu.sh", + "debugServerArgs": "-g 2345 -cpu max,sve2048=on,sve-default-vector-length=256,sme=off ${workspaceFolder}/build/intrinsiccv-debug/test/api/intrinsiccv-api-test --vector-length=256 --gtest_filter=*", + "cwd": "${workspaceFolder}", + "preLaunchTask": "Build IntrinsicCV for debug", + }, + { + "name": "SME2 API tests", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/intrinsiccv-debug/test/api/intrinsiccv-api-test", + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb-multiarch", + "miDebuggerServerAddress": "localhost:2345", + "targetArchitecture": "arm64", + "debugServerPath" : "${workspaceFolder}/.devcontainer/start_qemu.sh", + "debugServerArgs": "-g 2345 -cpu max,sve128=on,sme512=on ${workspaceFolder}/build/intrinsiccv-debug/test/api/intrinsiccv-api-test --vector-length=64 --gtest_filter=*", + "cwd": "${workspaceFolder}", + "preLaunchTask": "Build IntrinsicCV for debug", + }, + ] +} diff --git a/.vscode/launch.json.license b/.vscode/launch.json.license new file mode 100644 index 000000000..468a89751 --- /dev/null +++ b/.vscode/launch.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates + +SPDX-License-Identifier: Apache-2.0 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..49aaecc4f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "C_Cpp.intelliSenseEngine": "disabled", + "clangd.path": "clangd", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}/build/intrinsiccv" + ] +} diff --git a/.vscode/settings.json.license b/.vscode/settings.json.license new file mode 100644 index 000000000..468a89751 --- /dev/null +++ b/.vscode/settings.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates + +SPDX-License-Identifier: Apache-2.0 diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..b905aebe3 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,169 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build IntrinsicCV", + "type": "shell", + "command": "${workspaceFolder}/scripts/build.sh", + "problemMatcher" :"$gcc", + "args": [ + "intrinsiccv-test" + ], + "options": { + "env": { + "CMAKE_CXX_FLAGS": "--target=aarch64-linux-gnu", + "CMAKE_EXE_LINKER_FLAGS": "--rtlib=compiler-rt -static -fuse-ld=lld", + "EXTRA_CMAKE_ARGS": "-DINTRINSICCV_ENABLE_SVE2=ON -DINTRINSICCV_ENABLE_SVE2_SELECTIVELY=OFF -DCMAKE_EXPORT_COMPILE_COMMANDS=1" + } + }, + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Build IntrinsicCV for debug", + "type": "shell", + "command": "${workspaceFolder}/scripts/build.sh", + "problemMatcher" :"$gcc", + "args": [ + "intrinsiccv-test" + ], + "options": { + "env": { + "BUILD_ID" : "intrinsiccv-debug", + "CMAKE_BUILD_TYPE" : "Debug", + "CMAKE_CXX_FLAGS": "--target=aarch64-linux-gnu", + "CMAKE_EXE_LINKER_FLAGS": "--rtlib=compiler-rt -static -fuse-ld=lld", + "EXTRA_CMAKE_ARGS": "-DINTRINSICCV_ENABLE_SVE2=ON -DINTRINSICCV_ENABLE_SVE2_SELECTIVELY=OFF" + } + }, + "group": { + "kind": "build" + } + }, + { + "label": "Clean build directory", + "type": "shell", + "command": "rm -rf ${workspaceFolder}/build", + "problemMatcher": [] + }, + { + "label": "Clean ccache cache", + "type": "shell", + "command": "rm -rf ${workspaceFolder}/.devcontainer/ccache_storage/*", + "problemMatcher": [] + }, + { + "label": "Framework tests", + "type": "process", + "command": "qemu-aarch64", + "args": [ + "${workspaceFolder}/build/intrinsiccv/test/framework/intrinsiccv-framework-test" + ], + "dependsOn": [ + "Build IntrinsicCV" + ], + "group": { + "kind": "test" + } + }, + { + "label": "NEON API tests", + "type": "process", + "command": "qemu-aarch64", + "args": [ + "-cpu", + "cortex-a35", + "${workspaceFolder}/build/intrinsiccv/test/api/intrinsiccv-api-test", + "--vector-length=16" + ], + "dependsOn": [ + "Build IntrinsicCV" + ], + "group": { + "kind": "test" + } + }, + { + "label": "SVE2 API tests, 128 bits", + "type": "process", + "command": "qemu-aarch64", + "args": [ + "-cpu", + "max,sve128=on,sme=off", + "${workspaceFolder}/build/intrinsiccv/test/api/intrinsiccv-api-test", + "--vector-length=16" + ], + "dependsOn": [ + "Build IntrinsicCV" + ], + "group": { + "kind": "test" + } + }, + { + "label": "SVE2 API tests, 2048 bits", + "type": "process", + "command": "qemu-aarch64", + "args": [ + "-cpu", + "max,sve2048=on,sve-default-vector-length=256,sme=off", + "${workspaceFolder}/build/intrinsiccv/test/api/intrinsiccv-api-test", + "--vector-length=256" + ], + "dependsOn": [ + "Build IntrinsicCV" + ], + "group": { + "kind": "test" + } + }, + { + "label": "SME2 API tests", + "type": "process", + "command": "qemu-aarch64", + "args": [ + "-cpu", + "max,sve128=on,sme512=on", + "${workspaceFolder}/build/intrinsiccv/test/api/intrinsiccv-api-test", + "--vector-length=64" + ], + "dependsOn": [ + "Build IntrinsicCV" + ], + "group": { + "kind": "test" + } + }, + { + "label": "All API tests", + "dependsOn": [ + "NEON API tests", + "SVE2 API tests, 128 bits", + "SVE2 API tests, 2048 bits", + "SME2 API tests" + ], + "group": { + "kind": "test" + } + }, + { + "label": "Format source", + "type": "shell", + "command": "${workspaceFolder}/scripts/format.sh", + "problemMatcher": [] + }, + { + "label": "Run CI script", + "type": "shell", + "command": "${workspaceFolder}/scripts/ci.sh", + "problemMatcher": [] + } + ], + "options": { + "env": { + "GTEST_FILTER" : "*" + } + } +} diff --git a/.vscode/tasks.json.license b/.vscode/tasks.json.license new file mode 100644 index 000000000..468a89751 --- /dev/null +++ b/.vscode/tasks.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates + +SPDX-License-Identifier: Apache-2.0 diff --git a/docker/Dockerfile b/docker/Dockerfile index e3dfabced..080b3436c 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -43,23 +43,16 @@ RUN wget -q https://apt.llvm.org/llvm-snapshot.gpg.key -O /etc/apt/trusted.gpg.d lld-${LLVM_VERSION} \ llvm-${LLVM_VERSION} -# Install libclang-rt-dev on an x86 host. -# Hacks are needed to make this work: -# 1. Once we add the arm64 architecture then apt update will fail so -# ignore the error. -# 2. libclang-rt-dev declares a dependency on libc & libc++ which isn't -# needed to build, so edit the package to remove all dependencies. +# Populate the contents of libclang-rt-dev:arm64 on an x86 host. +# Package installation fails, so instead the package is downloaded and extracted into the root filesystem. RUN if [ $(dpkg --print-architecture) = amd64 ]; then \ dpkg --add-architecture arm64 \ && (apt-get -y update || true) \ && cd /tmp \ && apt-get -y download libclang-rt-${LLVM_VERSION}-dev:arm64 \ - && dpkg-deb -x libclang-rt*.deb libclang-rt \ - && dpkg-deb --control libclang-rt*.deb libclang-rt/DEBIAN \ - && sed -i '/Depends:/d' libclang-rt/DEBIAN/control \ - && dpkg -b libclang-rt libclang-rt.deb \ - && apt-get -y install ./libclang-rt.deb \ + && dpkg-deb -x libclang-rt*.deb / \ && rm -rf libclang-rt* \ + && dpkg --remove-architecture arm64 \ ; fi RUN pipx install cpplint==1.6.1 @@ -77,3 +70,10 @@ RUN wget \ RUN wget \ https://github.com/opencv/opencv_extra/archive/refs/tags/${OPENCV_VERSION}.tar.gz \ -O /opt/opencv-extra-${OPENCV_VERSION}.tar.gz + +# Add a normal user with sudo rights, can be useful for developement purposes +ARG USER=user +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get -y --no-install-recommends install sudo +RUN useradd -s /usr/bin/bash -m ${USER} \ + && echo "${USER} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USER} diff --git a/scripts/ci.sh b/scripts/ci.sh index 3eda8c4f9..0b9560157 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -12,7 +12,9 @@ cd "$(dirname "${BASH_SOURCE[0]}")/.." # Ensure we're doing a clean build rm -rf build -apt-get -y --no-install-recommends install qemu-user +if ! command -v qemu-aarch64; then + apt-get -y --no-install-recommends install qemu-user +fi # Check format of C++ files CHECK_ONLY=ON VERBOSE=ON scripts/format.sh -- GitLab