From 8aa9604d1a0bca838db281735a68689ac64b5242 Mon Sep 17 00:00:00 2001 From: Gabriel Lima Date: Sun, 18 Jan 2026 21:26:29 -0300 Subject: [PATCH] Initial commit (template) --- .env.example | 17 +++++ .gitignore | 14 ++++ .vscode/extensions.json | 6 ++ .vscode/launch.json | 76 ++++++++++++++++++ .vscode/tasks.json | 165 ++++++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 64 ++++++++++++++++ main.cpp | 9 +++ rpi1-toolchain.cmake | 71 +++++++++++++++++ 8 files changed, 422 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 CMakeLists.txt create mode 100644 main.cpp create mode 100644 rpi1-toolchain.cmake diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..566a7a6 --- /dev/null +++ b/.env.example @@ -0,0 +1,17 @@ +# .env.example - Template for environment configuration +# Copy this to .env and update with your values + +# Target device IP address +TARGET_IP=192.168.1.100 + +# Target device username +TARGET_USER=user + +# Directory on target where executable will be stored +TARGET_DIR=/home/user + +# Path to your buildroot directory +BUILDROOT_PATH=/home/user/rpi1/buildroot + +# Name of your project executable +PROJECT_NAME=hello-rpi \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e78c677 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# VS Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets +!*.code-workspace + +# Environment file +.env + +# Generated build path +build/ \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..c48d0ec --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "ms-vscode.cpptools", + "augustocdias.tasks-shell-input" + ], +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5e9eb67 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,76 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug on ARM", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/${input:project_name}", + "preLaunchTask": "Deploy and Start GDB Server", + "cwd": "${workspaceFolder}", + "MIMode": "gdb", + "externalConsole": false, + "logging": { + "engineLogging": false + }, + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "stopAtEntry": true, + "miDebuggerServerAddress": "${input:target_ip}:2345", + "miDebuggerPath": "${input:buildroot_path}/output/host/bin/arm-linux-gdb", + "targetArchitecture": "arm" + } + ], + "inputs": [ + { + "id": "target_ip", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $TARGET_IP", + "useFirstResult": true + } + }, + { + "id": "target_user", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $TARGET_USER", + "useFirstResult": true + } + }, + { + "id": "target_dir", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $TARGET_DIR", + "useFirstResult": true + } + }, + { + "id": "buildroot_path", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $BUILDROOT_PATH", + "useFirstResult": true + } + }, + { + "id": "project_name", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $PROJECT_NAME", + "useFirstResult": true + } + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..c03aa8d --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,165 @@ +{ + "version": "2.0.0", + "inputs": [ + { + "id": "target_ip", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $TARGET_IP", + "useFirstResult": true + } + }, + { + "id": "target_user", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $TARGET_USER", + "useFirstResult": true + } + }, + { + "id": "target_dir", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $TARGET_DIR", + "useFirstResult": true + } + }, + { + "id": "buildroot_path", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $BUILDROOT_PATH", + "useFirstResult": true + } + }, + { + "id": "project_name", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": ". ${workspaceFolder}/.env && echo $PROJECT_NAME", + "useFirstResult": true + } + } + ], + "tasks": [ + { + "label": "CMake: Configure", + "type": "shell", + "command": "cmake", + "args": [ + "-S", "${workspaceFolder}", + "-B", "${workspaceFolder}/build", + "-DCMAKE_TOOLCHAIN_FILE=${workspaceFolder}/rpi1-toolchain.cmake", + "-DCMAKE_BUILD_TYPE=Debug", + "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", + "-DBUILDROOT_PATH=${input:buildroot_path}", + "-DPROJECT_NAME_OVERRIDE=${input:project_name}" + ], + "problemMatcher": [], + "detail": "Configure CMake for cross-compilation" + }, + { + "label": "CMake: Build", + "type": "shell", + "command": "cmake", + "args": [ + "--build", "${workspaceFolder}/build", + "--config", "Debug", + "-j", "4" + ], + "dependsOn": "CMake: Configure", + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Build the project with CMake" + }, + { + "label": "CMake: Clean", + "type": "shell", + "command": "cmake", + "args": [ + "--build", "${workspaceFolder}/build", + "--target", "clean" + ], + "problemMatcher": [], + "detail": "Clean build artifacts" + }, + { + "label": "CMake: Rebuild", + "type": "shell", + "dependsOn": ["CMake: Clean", "CMake: Build"], + "dependsOrder": "sequence", + "problemMatcher": [], + "detail": "Clean and rebuild the project" + }, + { + "label": "Deploy", + "type": "shell", + "dependsOn": "CMake: Build", + "command": "scp", + "args": [ + "-O", + "${workspaceFolder}/build/${input:project_name}", + "${input:target_user}@${input:target_ip}:${input:target_dir}/${input:project_name}" + ], + "problemMatcher": [], + "group": { + "kind": "build" + } + }, + { + "label": "Start GDB Server", + "type": "shell", + "command": "ssh", + "args": [ + "-t", + "${input:target_user}@${input:target_ip}", + "gdbserver :2345 ${input:target_dir}/${input:project_name}" + ], + "isBackground": true, + "presentation": { + "reveal": "always", + "panel": "dedicated", + "focus": false, + "clear": true + }, + "problemMatcher": { + "pattern": { + "regexp": "^Listening on port (\\d+)$", + "line": 1 + }, + "background": { + "activeOnStart": true, + "beginsPattern": ".", + "endsPattern": "^Listening on port \\d+$" + } + } + }, + { + "label": "Deploy and Start GDB Server", + "dependsOn": ["Deploy", "Start GDB Server"], + "dependsOrder": "sequence", + "problemMatcher": [] + }, + { + "label": "Stop GDB Server", + "type": "shell", + "command": "ssh", + "args": [ + "${input:target_user}@${input:target_ip}", + "pkill -9 gdbserver" + ], + "problemMatcher": [] + } + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..31b2238 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,64 @@ +cmake_minimum_required(VERSION 3.16) + +# Require project name to be passed from command line +if(NOT DEFINED PROJECT_NAME) + message(FATAL_ERROR + "PROJECT_NAME is not defined!\n" + "Please pass -DPROJECT_NAME=your_project_name when configuring CMake.\n" + "Example: cmake -DPROJECT_NAME=hello-rpi ..." + ) +endif() + +# Validate project name (no spaces, special characters, etc.) +if(PROJECT_NAME MATCHES "[ /\\]") + message(FATAL_ERROR + "PROJECT_NAME contains invalid characters: ${PROJECT_NAME}\n" + "Project name should not contain spaces or path separators." + ) +endif() + +# Project name and version +project(${PROJECT_NAME} VERSION 1.0 LANGUAGES C CXX) + +# Display configuration info +message(STATUS "Building project: ${PROJECT_NAME}") +message(STATUS "Buildroot path: ${BUILDROOT_PATH}") + +# Generate compile_commands.json for IntelliSense +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Set C standard +set(CMAKE_C_STANDARD 23) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) + +# Set C++ standard +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) # This enables GNU extensions (gnu++23 instead of c++23) + +# Add compile options +add_compile_options(-Wall -Wextra -pedantic) + +# Build with debug symbols by default +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif() + +# Use project name for executable +add_executable(${PROJECT_NAME} + main.cpp +) + +# If you have additional source files, add them here: +# add_executable(${PROJECT_NAME} +# main.cpp +# other_file.cpp +# another_file.cpp +# ) + +# If you need to link libraries (example: pthread) +# target_link_libraries(${PROJECT_NAME} PRIVATE pthread) + +# Install rule (optional) +install(TARGETS ${PROJECT_NAME} DESTINATION bin) \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..03ae8f3 --- /dev/null +++ b/main.cpp @@ -0,0 +1,9 @@ +#include + +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + std::cout << "Hello RPI" << std::endl; + return 0; +} diff --git a/rpi1-toolchain.cmake b/rpi1-toolchain.cmake new file mode 100644 index 0000000..be3d749 --- /dev/null +++ b/rpi1-toolchain.cmake @@ -0,0 +1,71 @@ +# rpi1-toolchain.cmake - Toolchain file for Raspberry Pi 1 (ARMv6) + +# Additional settings for better compatibility +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) + +# Detect if we're in a try_compile invocation +# During try_compile, BUILDROOT_PATH won't be available, but that's OK +# because we set CMAKE_TRY_COMPILE_TARGET_TYPE above +get_property(_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) + +if(NOT _IN_TRY_COMPILE) + # Only validate during main configuration, not during try_compile + if(NOT BUILDROOT_PATH) + message(FATAL_ERROR + "BUILDROOT_PATH is not defined!\n" + "Please pass -DBUILDROOT_PATH=/path/to/buildroot when configuring CMake.\n" + "Example: cmake -DBUILDROOT_PATH=/home/user/rpi1/buildroot ..." + ) + endif() + + # Verify BUILDROOT_PATH exists + if(NOT EXISTS "${BUILDROOT_PATH}") + message(FATAL_ERROR + "BUILDROOT_PATH does not exist: ${BUILDROOT_PATH}\n" + "Please check your .env file or cmake configuration." + ) + endif() + + # Cache it for use in this file during try_compile + set(BUILDROOT_PATH "${BUILDROOT_PATH}" CACHE PATH "Path to buildroot directory" FORCE) +endif() + +# If BUILDROOT_PATH is not set (during try_compile), try to get it from cache +if(NOT BUILDROOT_PATH) + get_property(BUILDROOT_PATH CACHE BUILDROOT_PATH PROPERTY VALUE) +endif() + +# Specify the cross compiler +set(TOOLCHAIN_PREFIX ${BUILDROOT_PATH}/output/host) +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}/bin/arm-linux-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}/bin/arm-linux-g++) + +# Specify the sysroot for finding libraries and headers +set(CMAKE_SYSROOT ${TOOLCHAIN_PREFIX}/arm-buildroot-linux-gnueabihf/sysroot) +set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + +# Only verify paths during main configuration +if(NOT _IN_TRY_COMPILE) + # Verify sysroot exists + if(NOT EXISTS "${CMAKE_SYSROOT}") + message(FATAL_ERROR + "Sysroot not found: ${CMAKE_SYSROOT}\n" + "Please check that buildroot is properly built." + ) + endif() +endif() + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# Search for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# Specify target architecture flags +set(CMAKE_C_FLAGS_INIT "-march=armv6 -mfpu=vfp -mfloat-abi=hard") +set(CMAKE_CXX_FLAGS_INIT "-march=armv6 -mfpu=vfp -mfloat-abi=hard") \ No newline at end of file