diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72abac85..4b279228 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -134,15 +134,15 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Set up QEMU for cross-platform builds - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 with: platforms: all @@ -243,14 +243,14 @@ jobs: echo "Wrote $out" - name: Upload version report - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: "aasdk-deb-versions-${{ matrix.distro }}-${{ matrix.arch }}" path: "deb-versions-${{ matrix.distro }}-${{ matrix.arch }}.md" retention-days: 60 - name: Upload build artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: "aasdk-packages-${{ matrix.distro }}-${{ matrix.arch }}" path: | @@ -265,10 +265,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download build artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v6 with: pattern: aasdk-packages-* merge-multiple: true @@ -307,7 +307,7 @@ jobs: done - name: Upload test report - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: aasdk-test-report-${{ github.run_number }} path: test-report.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index af66e339..05783dcf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 @@ -229,13 +229,13 @@ jobs: cat ../RELEASE_NOTES.md - name: Ensure git metadata - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Create GitHub Release id: create_release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: tag_name: ${{ steps.release_info.outputs.version || github.run_number }} name: "AASDK Release ${{ steps.release_info.outputs.version || github.run_number }}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 04f27000..d2a2ef28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,19 +1,44 @@ -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(aasdk) message(STATUS "AASDK Library") message(STATUS "Cross Compiling?") -# Cross Compiling Architecture +# Options to skip building dependencies +option(SKIP_BUILD_PROTOBUF "Skip building protobuf, use system-installed version" OFF) +option(SKIP_BUILD_ABSL "Skip building Abseil, use system-installed version" OFF) + +# Cross Compiling Architecture and Package Architecture Detection if( TARGET_ARCH STREQUAL "amd64" ) message(STATUS "...amd64") set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") elseif( TARGET_ARCH STREQUAL "armhf" ) message(STATUS "...armhf") set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "armhf") + # Only set cross-compilation compilers if explicitly using cross-compilation + # For native builds (e.g., Docker with QEMU), let CMake use default compilers + if(DEFINED ENV{CMAKE_C_COMPILER} AND DEFINED ENV{CMAKE_CXX_COMPILER}) + # Environment variables are set (from build.sh), use them + set(CMAKE_C_COMPILER $ENV{CMAKE_C_COMPILER}) + set(CMAKE_CXX_COMPILER $ENV{CMAKE_CXX_COMPILER}) + elseif(CMAKE_CROSSCOMPILING OR DEFINED CMAKE_TOOLCHAIN_FILE) + # Only set cross-compilation when actually cross-compiling + set(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc) + set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++) + endif() elseif( TARGET_ARCH STREQUAL "arm64" ) message(STATUS "...arm64") set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64") + # Only set cross-compilation compilers if explicitly using cross-compilation + if(DEFINED ENV{CMAKE_C_COMPILER} AND DEFINED ENV{CMAKE_CXX_COMPILER}) + # Environment variables are set (from build.sh), use them + set(CMAKE_C_COMPILER $ENV{CMAKE_C_COMPILER}) + set(CMAKE_CXX_COMPILER $ENV{CMAKE_CXX_COMPILER}) + elseif(CMAKE_CROSSCOMPILING OR DEFINED CMAKE_TOOLCHAIN_FILE) + # Only set cross-compilation when actually cross-compiling + set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc) + set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++) + endif() elseif( TARGET_ARCH STREQUAL "i386" ) message(STATUS "...i386") set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "i386") @@ -51,48 +76,26 @@ string(TIMESTAMP LIBRARY_BUILD_YEAR "%Y" UTC) # Major version = Year (e.g., string(TIMESTAMP LIBRARY_BUILD_MONTH "%m" UTC) # Minor version = Month (01-12) string(TIMESTAMP LIBRARY_BUILD_DAY "%d" UTC) # Patch version = Day (01-31) -# Get git commit information -find_package(Git QUIET) -if(GIT_FOUND) - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE GIT_COMMIT_ID - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE GIT_BRANCH - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - execute_process( - COMMAND ${GIT_EXECUTABLE} describe --tags --dirty --always - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE GIT_DESCRIBE - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - # Check if repository is dirty (has uncommitted changes) - execute_process( - COMMAND ${GIT_EXECUTABLE} diff --quiet - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - RESULT_VARIABLE GIT_DIRTY - ERROR_QUIET - ) -else() - set(GIT_COMMIT_ID "unknown") - set(GIT_BRANCH "unknown") - set(GIT_DESCRIBE "unknown") - set(GIT_DIRTY 0) -endif() +# Set CMAKE_MODULE_PATH early so we can include gitversion.cmake +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake_modules/") + +# Get git commit information using gitversion.cmake module +set(local_dir ${CMAKE_CURRENT_SOURCE_DIR}) +include(gitversion) + +# Include DEB package filename generation module +include(DebPackageFilename) # Clean up git commit ID (remove any unwanted characters) -if(NOT GIT_COMMIT_ID) +if(NOT GIT_COMMIT_ID OR GIT_COMMIT_ID STREQUAL "") set(GIT_COMMIT_ID "unknown") endif() +if(NOT GIT_BRANCH OR GIT_BRANCH STREQUAL "") + set(GIT_BRANCH "unknown") +endif() +if(NOT GIT_DESCRIBE OR GIT_DESCRIBE STREQUAL "") + set(GIT_DESCRIBE "unknown") +endif() # Set version components set(LIBRARY_BUILD_MAJOR_RELEASE ${LIBRARY_BUILD_YEAR}) @@ -113,10 +116,9 @@ set(include_ut_directory ${base_directory}/unit_test) # Configure CMAKE message(STATUS "Configuring CMAKE") -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake_modules/") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT} -fPIC -Wall -pedantic") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -DNDEBUG") @@ -151,7 +153,7 @@ endif() # Paths set(sources_directory ${CMAKE_CURRENT_SOURCE_DIR}/src) set(include_directory ${CMAKE_CURRENT_SOURCE_DIR}/include) -set(include_ut_directory ${CMAKE_CURRENT_SOURCE_DIR}/include_ut) +set(include_ut_directory ${CMAKE_CURRENT_SOURCE_DIR}/unit_test) # Set output directories to build directory for proper packaging set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) @@ -189,55 +191,46 @@ if(AASDK_TEST) FetchContent_MakeAvailable(googletest) endif(AASDK_TEST) -# Detect cross-compilation -string(FIND "${CMAKE_C_COMPILER}" "aarch64-linux-gnu" IS_ARM64_CROSS) -string(FIND "${CMAKE_C_COMPILER}" "arm-linux-gnueabihf" IS_ARMHF_CROSS) -string(FIND "${CMAKE_CXX_COMPILER}" "aarch64-linux-gnu" IS_ARM64_CXX_CROSS) -string(FIND "${CMAKE_CXX_COMPILER}" "arm-linux-gnueabihf" IS_ARMHF_CXX_CROSS) +# Always build aap_protobuf for header generation +add_subdirectory(protobuf) -if(IS_ARM64_CROSS GREATER -1 OR IS_ARMHF_CROSS GREATER -1 OR IS_ARM64_CXX_CROSS GREATER -1 OR IS_ARMHF_CXX_CROSS GREATER -1) - set(CROSS_COMPILING TRUE) - message(STATUS "Cross-compilation detected, using system protobuf packages") +# Handle protobuf library linking based on skip option +if(NOT SKIP_BUILD_PROTOBUF) + message(STATUS "Using built protobuf v30.0") else() - set(CROSS_COMPILING FALSE) + message(STATUS "Skipping protobuf build, using system-installed version") + find_package(Protobuf REQUIRED) endif() -# Build aap_protobuf as part of this project (unless cross-compiling) -if(NOT CROSS_COMPILING) - message(STATUS "Building aap_protobuf as subdirectory") - add_subdirectory(protobuf) -endif() - -# Building on a Mac requires Abseil -if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") # macOS - message(STATUS "MacOS System Detected") - find_package(protobuf REQUIRED CONFIG) - find_package(absl REQUIRED) -else () - # Linux specific command - if(CROSS_COMPILING) - # For cross-compilation, use pkg-config to find cross-compiled protobuf - find_package(PkgConfig REQUIRED) - pkg_check_modules(Protobuf REQUIRED protobuf) - set(Protobuf_FOUND TRUE) - message(STATUS "Using cross-compiled protobuf: ${Protobuf_VERSION}") +# Require Abseil when building protobuf ourselves (which we always do for aap_protobuf), or on macOS +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR NOT SKIP_BUILD_ABSL) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + message(STATUS "MacOS System Detected - Abseil required") + elseif(SKIP_BUILD_ABSL) + message(STATUS "Building protobuf with system-installed Abseil") else() - find_path(Protobuf_INCLUDE_DIR google/protobuf/message.h PATHS /usr/include /usr/local/include) - find_library(Protobuf_LIBRARY protobuf PATHS /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/aarch64-linux-gnu /usr/lib/arm-linux-gnueabihf /usr/local/lib) - find_program(PROTOBUF_PROTOC_EXECUTABLE protoc) - message(STATUS "Found Protobuf include: ${Protobuf_INCLUDE_DIR}") - message(STATUS "Found Protobuf library: ${Protobuf_LIBRARY}") - message(STATUS "Found protoc: ${PROTOBUF_PROTOC_EXECUTABLE}") - if(NOT Protobuf_INCLUDE_DIR OR NOT Protobuf_LIBRARY OR NOT PROTOBUF_PROTOC_EXECUTABLE) - message(FATAL_ERROR "Protobuf not found. Please install libprotobuf-dev and protobuf-compiler") - endif() - set(Protobuf_FOUND TRUE) + message(STATUS "Building protobuf with bundled Abseil") endif() -endif () - -include(FindProtobuf) + find_package(absl REQUIRED) +else() + message(STATUS "Skipping Abseil requirement - using system protobuf") +endif() find_package(Boost REQUIRED COMPONENTS system log_setup log OPTIONAL_COMPONENTS unit_test_framework) + +# Capture Boost version for packaging +if(Boost_VERSION) + string(REPLACE "." ";" VERSION_LIST ${Boost_VERSION}) + list(GET VERSION_LIST 0 Boost_VERSION_MAJOR) + list(GET VERSION_LIST 1 Boost_VERSION_MINOR) + set(BOOST_PACKAGE_VERSION "${Boost_VERSION_MAJOR}.${Boost_VERSION_MINOR}.0") + message(STATUS "Detected Boost version: ${BOOST_PACKAGE_VERSION}") +else() + # Fallback to common versions if detection fails + set(BOOST_PACKAGE_VERSION "1.83.0") + message(WARNING "Could not detect Boost version, using fallback: ${BOOST_PACKAGE_VERSION}") +endif() + find_package(libusb-1.0 REQUIRED) find_package(OpenSSL REQUIRED) @@ -269,18 +262,28 @@ else() ${source_files} ${include_files}) endif() -target_include_directories(aasdk PUBLIC +if(SKIP_BUILD_PROTOBUF) + target_include_directories(aasdk PUBLIC $ + $ $ -) + ) +else() + target_include_directories(aasdk PUBLIC + $ + $ + $ + ) +endif() +# Link libraries - aap_protobuf is always built as subdirectory target_link_libraries(aasdk PUBLIC - ${LIBUSB_1_LIBRARIES} - ${Boost_LIBRARIES} - ${PROTOBUF_LIBRARIES} - aap_protobuf - ${OPENSSL_LIBRARIES} - ${WINSOCK2_LIBRARIES}) + ${LIBUSB_1_LIBRARIES} + ${Boost_LIBRARIES} + aap_protobuf + ${OPENSSL_LIBRARIES} + ${WINSOCK2_LIBRARIES} + $,protobuf::libprotobuf,${PROTOBUF_LIBRARIES}>) # Link nlohmann/json if available and JSON logging is enabled if(ENABLE_JSON_LOGGING AND nlohmann_json_FOUND) @@ -307,6 +310,7 @@ message(STATUS "Project Version: ${LIBRARY_VERSION_STRING}") message(STATUS "Git Branch: ${GIT_BRANCH}") message(STATUS "Git Commit: ${GIT_COMMIT_ID}") message(STATUS "Git Describe: ${GIT_DESCRIBE}") +message(STATUS "Git Timestamp: ${GIT_COMMIT_TIMESTAMP}") if(GIT_DIRTY GREATER 0) message(STATUS "Repository Status: DIRTY (has uncommitted changes)") else() @@ -347,6 +351,37 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/aasdk/Version.hpp" COMPONENT development ) +# Install SSL certificate and key files +install(FILES + "${CMAKE_CURRENT_SOURCE_DIR}/cert/headunit.crt" + DESTINATION /etc/aasdk + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + COMPONENT runtime +) + +install(FILES + "${CMAKE_CURRENT_SOURCE_DIR}/cert/headunit.key" + DESTINATION /etc/aasdk + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ + COMPONENT runtime +) + +# Align direct "make install" behavior with package postinst: +# create/use aasdk group and assign cert/key group ownership + key group-read. +install(CODE [[ + set(_cert_dir "$ENV{DESTDIR}/etc/aasdk") + set(_cert_file "${_cert_dir}/headunit.crt") + set(_key_file "${_cert_dir}/headunit.key") + + execute_process( + COMMAND /bin/sh -c "if ! getent group aasdk >/dev/null 2>&1; then if command -v addgroup >/dev/null 2>&1; then addgroup --system aasdk || true; elif command -v groupadd >/dev/null 2>&1; then groupadd --system aasdk || true; fi; fi" + ) + + execute_process( + COMMAND /bin/sh -c "if getent group aasdk >/dev/null 2>&1; then if [ -f '${_cert_file}' ]; then chown root:aasdk '${_cert_file}' || true; chmod 644 '${_cert_file}' || true; fi; if [ -f '${_key_file}' ]; then chown root:aasdk '${_key_file}' || true; chmod 640 '${_key_file}' || true; fi; fi" + ) +]] COMPONENT runtime) + # Export the targets to a script install(EXPORT aasdkTargets FILE aasdkTargets.cmake @@ -374,7 +409,19 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/aasdkConfigVersion.cmake" DESTINATION lib/cmake/aasdk COMPONENT development) +# Configure and install pkg-config file +include(GNUInstallDirs) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/aasdk.pc.in + "${CMAKE_CURRENT_BINARY_DIR}/aasdk.pc" + @ONLY) + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/aasdk.pc" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + COMPONENT development) + if(AASDK_TEST) + enable_testing() + add_executable(aasdk_ut ${tests_source_files} ${tests_include_files}) @@ -385,6 +432,8 @@ if(AASDK_TEST) gtest_main gmock_main) + add_test(NAME aasdk_ut COMMAND aasdk_ut) + if(AASDK_CODE_COVERAGE) include(CodeCoverage) append_coverage_compiler_flags() @@ -395,12 +444,19 @@ endif(AASDK_TEST) # CPack Configuration for DEB packages set(CPACK_GENERATOR "DEB") -set(CPACK_PACKAGE_NAME "libaasdk") + +# Add debug suffix to package name for debug builds +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CPACK_PACKAGE_NAME "libaasdk-dbg") +else() + set(CPACK_PACKAGE_NAME "libaasdk") +endif() + set(CPACK_PACKAGE_VENDOR "AASDK") -set(CPACK_PACKAGE_VERSION ${LIBRARY_VERSION_STRING}) +set(CPACK_PACKAGE_CONTACT "OpenCarDev Team ") +set(CPACK_PACKAGE_VERSION ${LIBRARY_BUILD_MAJOR_RELEASE}.${LIBRARY_BUILD_MINOR_RELEASE}.${LIBRARY_BUILD_PATCH_RELEASE}) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Android Auto SDK Library") set(CPACK_PACKAGE_DESCRIPTION "Android Auto SDK (AASDK) is a library for implementing Android Auto functionality in C++ applications.") -set(CPACK_PACKAGE_CONTACT "AASDK ") set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/opencardev/aasdk") # Set the correct install prefix for packaging @@ -409,37 +465,28 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) endif() # Debian package configuration -set(CPACK_DEBIAN_PACKAGE_MAINTAINER "AASDK ") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "AASDK ") set(CPACK_DEBIAN_PACKAGE_SECTION "libs") set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/opencardev/aasdk") -set(CPACK_DEBIAN_PACKAGE_DEPENDS "libusb-1.0-0 (>= 1.0.0), libboost-system1.81.0 | libboost-system1.74.0, libboost-log1.81.0 | libboost-log1.74.0, libssl3 (>= 3.0.0), libprotobuf32 (>= 3.21.0)") + +# Compute runtime Depends automatically per distro/arch using dpkg-shlibdeps +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) +# Ensure component runtime also gets shlibdeps +set(CPACK_DEBIAN_RUNTIME_PACKAGE_SHLIBDEPS ON) +# Help dpkg-shlibdeps find private libs in the build tree (if any) +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS "${CMAKE_CURRENT_BINARY_DIR}/lib;${CMAKE_CURRENT_BINARY_DIR}") set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "") set(CPACK_DEBIAN_PACKAGE_SUGGESTS "") -# Configure different packages based on build type and architecture -set(ARCH_SUFFIX "-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CPACK_PACKAGE_NAME "libaasdk${ARCH_SUFFIX}-dbg") - set(CPACK_DEBIAN_PACKAGE_NAME "libaasdk${ARCH_SUFFIX}-dbg") - set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Android Auto SDK Library (Debug) for ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") - set(CPACK_PACKAGE_DESCRIPTION "Android Auto SDK (AASDK) debug library with debugging symbols and information for ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE} architecture.") - set(CPACK_DEBIAN_PACKAGE_SECTION "debug") - set(CPACK_DEBIAN_PACKAGE_PRIORITY "extra") -else() - set(CPACK_PACKAGE_NAME "libaasdk${ARCH_SUFFIX}") - set(CPACK_DEBIAN_PACKAGE_NAME "libaasdk${ARCH_SUFFIX}") - set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Android Auto SDK Library for ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") - set(CPACK_PACKAGE_DESCRIPTION "Android Auto SDK (AASDK) is a library for implementing Android Auto functionality in C++ applications for ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE} architecture.") -endif() - -# File naming based on build type and architecture -if(DEFINED CPACK_DEBIAN_PACKAGE_ARCHITECTURE) - set(CPACK_DEBIAN_FILE_NAME "${CPACK_DEBIAN_PACKAGE_NAME}_${LIBRARY_VERSION_STRING}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb") -else() - set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") -endif() +# Configure DEB package filename using the DebPackageFilename module +configure_deb_filename( + PACKAGE_NAME "${CPACK_PACKAGE_NAME}" + VERSION "${LIBRARY_VERSION_STRING}" + ARCHITECTURE "${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}" + RUNTIME_PACKAGE_NAME "${CPACK_PACKAGE_NAME}" + DEVELOPMENT_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-dev" +) # Component configuration for multi-package builds set(CPACK_DEB_COMPONENT_INSTALL ON) @@ -448,20 +495,27 @@ set(CPACK_COMPONENTS_ALL runtime development) # Runtime package (libraries only) set(CPACK_COMPONENT_RUNTIME_DISPLAY_NAME "AASDK Runtime Libraries for ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") set(CPACK_COMPONENT_RUNTIME_DESCRIPTION "Runtime libraries for Android Auto SDK on ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE} architecture") -set(CPACK_DEBIAN_RUNTIME_PACKAGE_NAME "${CPACK_DEBIAN_PACKAGE_NAME}") -set(CPACK_DEBIAN_RUNTIME_FILE_NAME "${CPACK_DEBIAN_PACKAGE_NAME}_${LIBRARY_VERSION_STRING}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb") +set(CPACK_DEBIAN_RUNTIME_PACKAGE_NAME "${CPACK_PACKAGE_NAME}") set(CPACK_DEBIAN_RUNTIME_PACKAGE_SECTION "libs") set(CPACK_DEBIAN_RUNTIME_PACKAGE_PRIORITY "optional") -set(CPACK_DEBIAN_RUNTIME_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}") +# Do not hardcode Depends here; let dpkg-shlibdeps compute per-distro/arch # Development package (headers and cmake files) set(CPACK_COMPONENT_DEVELOPMENT_DISPLAY_NAME "AASDK Development Files for ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") set(CPACK_COMPONENT_DEVELOPMENT_DESCRIPTION "Development headers and CMake files for Android Auto SDK on ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE} architecture") -set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_NAME "${CPACK_DEBIAN_PACKAGE_NAME}-dev") -set(CPACK_DEBIAN_DEVELOPMENT_FILE_NAME "${CPACK_DEBIAN_PACKAGE_NAME}-dev_${LIBRARY_VERSION_STRING}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb") +set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-dev") set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_SECTION "libdevel") set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_PRIORITY "optional") -set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_NAME} (= ${LIBRARY_VERSION_STRING})") +# Construct the full Debian package version including any CPACK release suffix +if(DEFINED CPACK_DEBIAN_PACKAGE_RELEASE AND NOT "${CPACK_DEBIAN_PACKAGE_RELEASE}" STREQUAL "") + # Full version: - + set(_full_package_version "${LIBRARY_BUILD_MAJOR_RELEASE}.${LIBRARY_BUILD_MINOR_RELEASE}.${LIBRARY_BUILD_PATCH_RELEASE}-${CPACK_DEBIAN_PACKAGE_RELEASE}") +else() + # Fallback to the simple date based version + set(_full_package_version "${LIBRARY_BUILD_MAJOR_RELEASE}.${LIBRARY_BUILD_MINOR_RELEASE}.${LIBRARY_BUILD_PATCH_RELEASE}") +endif() + +set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_DEPENDS "${CPACK_PACKAGE_NAME} (= ${_full_package_version})") # Package relationships set(CPACK_COMPONENT_DEVELOPMENT_DEPENDS runtime) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..583cc136 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,129 @@ +# * Project: OpenAuto +# * This file is part of openauto project. +# * Copyright (C) 2025 OpenCarDev Team +# * +# * openauto is free software: you can redistribute it and/or modify +# * it under the terms of the GNU General Public License as published by +# * the Free Software Foundation; either version 3 of the License, or +# * (at your option) any later version. +# * +# * openauto is distributed in the hope that it will be useful, +# * but WITHOUT ANY WARRANTY; without even the implied warranty of +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# * GNU General Public License for more details. +# * +# * You should have received a copy of the GNU General Public License +# * along with openauto. If not, see . + +# Multi-stage build for AASDK with native compilation for each architecture +# This Dockerfile builds AASDK natively on each target platform using QEMU emulation + +# Allow selecting Debian base (bookworm or trixie). Default to trixie. +ARG DEBIAN_VERSION=trixie +FROM debian:${DEBIAN_VERSION}-slim + +# Build arguments +ARG TARGET_ARCH=amd64 +ARG BUILD_TYPE=release +ARG RUN_TESTS=false +ARG DEBIAN_FRONTEND=noninteractive +ARG GIT_COMMIT_ID=unknown +ARG GIT_BRANCH=unknown +ARG GIT_DESCRIBE=unknown +ARG GIT_COMMIT_TIMESTAMP=unknown +ARG GIT_DIRTY=unknown + +# Export git info as environment variables +ENV GIT_COMMIT_ID=${GIT_COMMIT_ID} +ENV GIT_BRANCH=${GIT_BRANCH} +ENV GIT_DESCRIBE=${GIT_DESCRIBE} +ENV GIT_COMMIT_TIMESTAMP=${GIT_COMMIT_TIMESTAMP} +ENV GIT_DIRTY=${GIT_DIRTY} + +# Debug: Print git variables +RUN echo "Docker build args received:" && \ + echo " GIT_COMMIT_ID=${GIT_COMMIT_ID}" && \ + echo " GIT_BRANCH=${GIT_BRANCH}" && \ + echo " GIT_DESCRIBE=${GIT_DESCRIBE}" && \ + echo " GIT_COMMIT_TIMESTAMP=${GIT_COMMIT_TIMESTAMP}" && \ + echo " GIT_DIRTY=${GIT_DIRTY}" + +# Set locale to avoid encoding issues +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 + +# Install build dependencies and tools +RUN apt-get update && apt-get install -y \ + # Core build tools + build-essential \ + cmake \ + ninja-build \ + pkg-config \ + git \ + lsb-release \ + # Development libraries (native for this platform) + libboost-all-dev \ + libprotobuf-dev \ + protobuf-compiler \ + libusb-1.0-0-dev \ + libssl-dev \ + # Packaging tools + file \ + dpkg-dev \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /src + +# Copy source code. +COPY . . + +# Debug: List what was copied +RUN echo "Contents of /src:" && ls -la + +# Create output directory for packages +RUN mkdir -p /output + +# Make build script executable and verify it exists +RUN if [ -f "build.sh" ]; then \ + echo "Found build.sh, making executable"; \ + chmod +x build.sh; \ + else \ + echo "ERROR: build.sh not found!"; \ + echo "Current directory contents:"; \ + ls -la; \ + exit 1; \ + fi + +# Build and package AASDK using the simplified build.sh approach +ARG CROSS_COMPILE=false +RUN echo "=== Git environment variables before build ===" && \ + echo " GIT_COMMIT_ID=$GIT_COMMIT_ID" && \ + echo " GIT_BRANCH=$GIT_BRANCH" && \ + echo " GIT_DESCRIBE=$GIT_DESCRIBE" && \ + echo " GIT_COMMIT_TIMESTAMP=$GIT_COMMIT_TIMESTAMP" && \ + echo " GIT_DIRTY=$GIT_DIRTY" && \ + echo " RUN_TESTS=$RUN_TESTS" && \ + echo "=============================================" && \ + export TARGET_ARCH=$(dpkg-architecture -qDEB_HOST_ARCH) && \ + TEST_ARG="" && \ + if [ "$RUN_TESTS" = "true" ]; then TEST_ARG="test"; fi && \ + echo "Building AASDK for architecture: $TARGET_ARCH (native compilation)" && \ + # Compute distro-specific release suffix for DEB packages + DISTRO_DEB_RELEASE=$(bash /src/scripts/distro_release.sh) && \ + CPACK_DEB_RELEASE="$DISTRO_DEB_RELEASE" && \ + echo "Using CPACK_DEBIAN_PACKAGE_RELEASE: $CPACK_DEB_RELEASE" && \ + # Pass through to CMake via build.sh using CMAKE_ARGS + env DISTRO_DEB_RELEASE="$CPACK_DEB_RELEASE" CMAKE_ARGS="$CMAKE_ARGS -DCPACK_DEBIAN_PACKAGE_RELEASE=$CPACK_DEB_RELEASE -DCPACK_PROJECT_CONFIG_FILE=/src/cmake_modules/CPackProjectConfig.cmake" \ + CROSS_COMPILE=${CROSS_COMPILE} \ + ./build.sh ${BUILD_TYPE} clean ${TEST_ARG} package --skip-protobuf --skip-absl && \ + if [ -d "packages" ]; then \ + cp packages/*.deb /output/ 2>/dev/null || true && \ + echo "Packages built:" && \ + ls -la /output/; \ + else \ + echo "No packages directory found" && \ + find . -name "*.deb" -exec cp {} /output/ \; 2>/dev/null || true; \ + fi && \ + echo "Build completed"# Default command +CMD ["bash", "-c", "echo 'AASDK build container ready. Use docker run with volume mounts to build packages.'"] \ No newline at end of file diff --git a/aasdk.pc.in b/aasdk.pc.in new file mode 100644 index 00000000..786f6529 --- /dev/null +++ b/aasdk.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ + +Name: aasdk +Description: Android Auto SDK Library +Version: @LIBRARY_VERSION_STRING@ +Requires: libusb-1.0 protobuf openssl +Libs: -L${libdir} -laasdk +Cflags: -I${includedir} diff --git a/build.sh b/build.sh index 87994de1..2462a463 100755 --- a/build.sh +++ b/build.sh @@ -17,9 +17,11 @@ # package - Create packages after building # # Environment Variables: -# TARGET_ARCH - Target architecture (amd64, arm64, armhf, i386) -# JOBS - Number of parallel build jobs (default: nproc) -# CMAKE_ARGS - Additional CMake arguments +# TARGET_ARCH - Target architecture (amd64, arm64, armhf, i386) +# JOBS - Number of parallel build jobs (default: nproc-1) +# CMAKE_ARGS - Additional CMake arguments +# CROSS_COMPILE - Enable cross-compilation (true/false, default: true) +# DRY_RUN - If set to true/1, skip any system installation steps set -e # Exit on any error @@ -31,16 +33,38 @@ BLUE='\033[0;34m' NC='\033[0m' # No Color # Default values -BUILD_TYPE=${1:-debug} +# Auto-detect build type based on git branch if not specified +if [ -z "$1" ]; then + CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown") + if [ "$CURRENT_BRANCH" = "main" ] || [ "$CURRENT_BRANCH" = "master" ]; then + BUILD_TYPE="release" + else + BUILD_TYPE="debug" + fi +else + BUILD_TYPE="$1" +fi TARGET_ARCH=${TARGET_ARCH:-amd64} -JOBS=${JOBS:-$(nproc)} +# Use one fewer core by default to reduce memory pressure on small devices +NPROC=$(nproc 2>/dev/null || echo 1) +if [ "$NPROC" -gt 1 ]; then + JOBS_DEFAULT=$((NPROC-1)) +else + JOBS_DEFAULT=1 +fi +JOBS=${JOBS:-$JOBS_DEFAULT} CMAKE_ARGS=${CMAKE_ARGS:-} +CROSS_COMPILE=${CROSS_COMPILE:-true} +# Dry run mode (skip system install) +DRY_RUN=${DRY_RUN:-false} # Parse command line arguments CLEAN=false RUN_TESTS=false INSTALL=false CREATE_PACKAGES=false +SKIP_PROTOBUF=false +SKIP_ABSL=false for arg in "$@"; do case $arg in @@ -59,12 +83,29 @@ for arg in "$@"; do package) CREATE_PACKAGES=true ;; + dryrun) + DRY_RUN=true + ;; + --skip-protobuf) + SKIP_PROTOBUF=true + ;; + --skip-absl) + SKIP_ABSL=true + ;; *) # Unknown option ;; esac done +# Add skip options to CMake args after parsing arguments +if [ "$SKIP_PROTOBUF" = true ]; then + CMAKE_ARGS="$CMAKE_ARGS -DSKIP_BUILD_PROTOBUF=ON" +fi +if [ "$SKIP_ABSL" = true ]; then + CMAKE_ARGS="$CMAKE_ARGS -DSKIP_BUILD_ABSL=ON" +fi + # Functions print_header() { echo -e "${BLUE}================================================${NC}" @@ -77,6 +118,15 @@ print_header() { echo -e "Run Tests: ${GREEN}${RUN_TESTS}${NC}" echo -e "Install: ${GREEN}${INSTALL}${NC}" echo -e "Create Packages: ${GREEN}${CREATE_PACKAGES}${NC}" + echo -e "Dry Run: ${GREEN}${DRY_RUN}${NC}" + echo -e "Skip Protobuf: ${GREEN}${SKIP_PROTOBUF}${NC}" + echo -e "Skip Abseil: ${GREEN}${SKIP_ABSL}${NC}" + echo -e "${YELLOW}Git details:${NC}" + echo " GIT_COMMIT_ID: $GIT_COMMIT_ID" + echo " GIT_BRANCH: $GIT_BRANCH" + echo " GIT_DESCRIBE: $GIT_DESCRIBE" + echo " GIT_TIMESTAMP: $GIT_COMMIT_TIMESTAMP" + echo " GIT_DIRTY: $GIT_DIRTY" echo -e "${BLUE}================================================${NC}" echo } @@ -128,91 +178,107 @@ check_dependencies() { missing_deps+=("libssl-dev") fi + # Check for absl only if not skipping protobuf (system protobuf v3.21.12 doesn't require absl) + if [ "$SKIP_PROTOBUF" != true ] && ! pkg-config --exists absl_base; then + missing_deps+=("libabsl-dev") + fi + if [ ${#missing_deps[@]} -ne 0 ]; then print_error "Missing dependencies detected:" printf '%s\n' "${missing_deps[@]}" echo - echo -e "${YELLOW}Installing missing dependencies...${NC}" - apt update && apt install -y ${missing_deps[*]} - print_success "Dependencies installed" + echo -e "${YELLOW}To install missing dependencies on Ubuntu/Debian:${NC}" + echo "sudo apt update && sudo apt install -y ${missing_deps[*]}" + echo + echo -e "${YELLOW}Or use the DevContainer for automatic dependency management.${NC}" + exit 1 fi print_success "All dependencies found" } -find_cross_compiler() { - local prefix="$1" - local compiler="" - - # First try the base name (might be a symlink to latest) - if command -v "${prefix}gcc" &> /dev/null && [ -x "$(command -v "${prefix}gcc")" ]; then - compiler="$(command -v "${prefix}gcc")" - else - # Find all versioned compilers and pick the latest that actually exists and is executable - local candidates=() - for candidate in $(ls /usr/bin/${prefix}gcc-* 2>/dev/null | sort -V); do - if [ -x "$candidate" ]; then - candidates+=("$candidate") - fi - done - if [ ${#candidates[@]} -gt 0 ]; then - compiler="${candidates[-1]}" - fi - fi +setup_native_compilation() { + print_step "Setting up native compilation for ${TARGET_ARCH}..." + + # Force native compilers + export CC=/usr/bin/cc + export CXX=/usr/bin/c++ + export CMAKE_C_COMPILER=/usr/bin/cc + export CMAKE_CXX_COMPILER=/usr/bin/c++ + + # Add compiler settings to CMAKE_ARGS + CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_C_COMPILER=/usr/bin/cc" + CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_CXX_COMPILER=/usr/bin/c++" + + # Architecture-specific library paths for dependency detection + local multiarch_path + case $TARGET_ARCH in + amd64) + multiarch_path="x86_64-linux-gnu" + ;; + arm64) + multiarch_path="aarch64-linux-gnu" + ;; + armhf) + multiarch_path="arm-linux-gnueabihf" + ;; + i386) + multiarch_path="i386-linux-gnu" + ;; + *) + print_error "Unsupported architecture: $TARGET_ARCH" + echo "Supported architectures: amd64, arm64, armhf, i386" + exit 1 + ;; + esac - if [ -n "$compiler" ] && [ -x "$compiler" ]; then - echo "$compiler" - return 0 - else - return 1 - fi + # Add dependency paths to CMAKE_ARGS for common libraries + CMAKE_ARGS="$CMAKE_ARGS -DProtobuf_INCLUDE_DIR=/usr/include" + CMAKE_ARGS="$CMAKE_ARGS -DProtobuf_LIBRARIES=/usr/lib/${multiarch_path}/libprotobuf.so" + CMAKE_ARGS="$CMAKE_ARGS -DProtobuf_LIBRARY=/usr/lib/${multiarch_path}/libprotobuf.so" + CMAKE_ARGS="$CMAKE_ARGS -DProtobuf_LITE_LIBRARY=/usr/lib/${multiarch_path}/libprotobuf-lite.so" + CMAKE_ARGS="$CMAKE_ARGS -DProtobuf_PROTOC_EXECUTABLE=/usr/bin/protoc" + CMAKE_ARGS="$CMAKE_ARGS -DLIBUSB_1_INCLUDE_DIRS=/usr/include/libusb-1.0" + CMAKE_ARGS="$CMAKE_ARGS -DLIBUSB_1_LIBRARIES=/usr/lib/${multiarch_path}/libusb-1.0.so" + CMAKE_ARGS="$CMAKE_ARGS -DOPENSSL_INCLUDE_DIR=/usr/include/openssl" + CMAKE_ARGS="$CMAKE_ARGS -DOPENSSL_CRYPTO_LIBRARY=/usr/lib/${multiarch_path}/libcrypto.so" + CMAKE_ARGS="$CMAKE_ARGS -DOPENSSL_SSL_LIBRARY=/usr/lib/${multiarch_path}/libssl.so" + + print_success "Native compilation configured for ${TARGET_ARCH}" } setup_cross_compilation() { - # if target arch equal actual arch, skip cross-compilation setup -# if [ "$TARGET_ARCH" = "$(dpkg --print-architecture)" ]; then -# print_step "Target architecture is native, skipping cross-compilation setup" -# return -# fi -# -# if [ -f /.dockerenv ] || [ -f /proc/sys/fs/binfmt_misc/qemu-aarch64 ] || [ -f /proc/sys/fs/binfmt_misc/qemu-arm ]; then -# print_step "Running in Docker container for native build - skipping cross-compilation setup" -# return -# fi - - if [ "$TARGET_ARCH" != "amd64" ]; then + if [ "$TARGET_ARCH" != "amd64" ] && [ "$CROSS_COMPILE" = "true" ]; then print_step "Setting up cross-compilation for ${TARGET_ARCH}..." case $TARGET_ARCH in arm64) - local c_compiler=$(find_cross_compiler "aarch64-linux-gnu-") - if [ $? -eq 0 ]; then - export CMAKE_C_COMPILER="$c_compiler" - export CMAKE_CXX_COMPILER="${c_compiler/gcc/g++}" - else + export CMAKE_C_COMPILER=aarch64-linux-gnu-gcc + export CMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ + CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH=/usr/aarch64-linux-gnu" + CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER" + CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY" + CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY" + + if ! command -v aarch64-linux-gnu-gcc &> /dev/null; then print_error "ARM64 cross-compiler not found" echo "Install with: sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu" exit 1 fi - CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH=/usr/aarch64-linux-gnu;/usr" + ;; + armhf) + export CMAKE_C_COMPILER=arm-linux-gnueabihf-gcc + export CMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ + CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH=/usr/arm-linux-gnueabihf" CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER" CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY" CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY" - ;; - armhf) - local c_compiler=$(find_cross_compiler "arm-linux-gnueabihf-") - if [ $? -eq 0 ]; then - export CMAKE_C_COMPILER="$c_compiler" - export CMAKE_CXX_COMPILER="${c_compiler/gcc/g++}" - else + + if ! command -v arm-linux-gnueabihf-gcc &> /dev/null; then print_error "ARMHF cross-compiler not found" echo "Install with: sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf" exit 1 fi - CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH=/usr/arm-linux-gnueabihf;/usr" - CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER" - CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY" - CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY" ;; i386) CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32" @@ -225,12 +291,14 @@ setup_cross_compilation() { esac print_success "Cross-compilation configured for ${TARGET_ARCH}" + elif [ "$CROSS_COMPILE" = "false" ]; then + setup_native_compilation fi } build_protobuf() { if [ ! -d "protobuf/build" ] || [ "$CLEAN" = true ]; then - print_step "Building protobuf dependency..." + print_step "Building AAP Protobuf dependency..." if [ "$CLEAN" = true ] && [ -d "protobuf/build" ]; then rm -rf protobuf/build @@ -238,36 +306,27 @@ build_protobuf() { mkdir -p protobuf/build cd protobuf/build + # Stage installs under the project to avoid requiring root + STAGING_DIR="$(pwd)/_staging" + mkdir -p "$STAGING_DIR" - local protobuf_cmake_args="$CMAKE_ARGS" - if [ "$TARGET_ARCH" != "amd64" ]; then - case $TARGET_ARCH in - arm64) - protobuf_cmake_args="$protobuf_cmake_args -DCMAKE_INSTALL_PREFIX=/usr/aarch64-linux-gnu" - ;; - armhf) - protobuf_cmake_args="$protobuf_cmake_args -DCMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf" - ;; - i386) - # For i386, install to default location since it's not true cross-compilation - ;; - esac - fi + cmake -DCMAKE_BUILD_TYPE=Release \ + -DTARGET_ARCH=$TARGET_ARCH \ + -DCMAKE_INSTALL_PREFIX="/usr/local" \ + $CMAKE_ARGS \ + .. - export CC="$CMAKE_C_COMPILER" - export CXX="$CMAKE_CXX_COMPILER" - cmake -DCMAKE_BUILD_TYPE=Release \ - -DTARGET_ARCH=$TARGET_ARCH \ - $protobuf_cmake_args \ - .. + make -j$JOBS + # Install to a local staging dir so no sudo is required + make install DESTDIR="$STAGING_DIR" - make -j$JOBS - make install + # Ensure main build can discover the staged install if it uses find_package + export CMAKE_PREFIX_PATH="$STAGING_DIR/usr/local:${CMAKE_PREFIX_PATH}" cd ../.. - print_success "Protobuf built successfully" + print_success "AAP Protobuf built successfully" else - print_step "Protobuf already built, skipping..." + print_step "AAP Protobuf already built, skipping..." fi } @@ -353,6 +412,10 @@ run_tests() { install_project() { if [ "$INSTALL" = true ]; then + if [ "$DRY_RUN" = true ] || [ "$DRY_RUN" = 1 ]; then + print_step "Dry run enabled: skipping system installation" + return 0 + fi print_step "Installing AASDK..." cd "$BUILD_DIR" @@ -465,23 +528,32 @@ show_usage() { echo " release Release build with optimizations enabled" echo echo "OPTIONS:" - echo " clean Clean build directory before building" - echo " test Run tests after building" - echo " install Install after building" - echo " package Create packages after building" + echo " clean Clean build directory before building" + echo " test Run tests after building" + echo " install Install after building" + echo " package Create packages after building" + echo " --skip-protobuf Skip building protobuf, use system-installed version" + echo " --skip-absl Skip building Abseil, use system-installed version" echo echo "Environment Variables:" echo " TARGET_ARCH Target architecture (amd64, arm64, armhf, i386)" - echo " JOBS Number of parallel build jobs (default: nproc)" + echo " JOBS Number of parallel build jobs (default: nproc-1)" echo " CMAKE_ARGS Additional CMake arguments" + echo " CROSS_COMPILE Enable cross-compilation (true/false, default: true)" echo echo "Examples:" echo " $0 debug # Debug build" echo " $0 release clean # Clean release build" echo " $0 debug test # Debug build with tests" + echo " $0 debug --skip-protobuf # Debug build using system protobuf" + echo " $0 release --skip-absl # Release build using system Abseil" echo " TARGET_ARCH=arm64 $0 release # Cross-compile for ARM64" echo " JOBS=4 $0 debug clean # Build with 4 parallel jobs" echo + echo "Backward Compatibility:" + echo " This version includes API changes from AASDK v4.x. For migration help," + echo " see include/aasdk/BackwardCompatibility.hpp and the migration guide." + echo echo "For complete documentation, see BUILD.md" } @@ -505,7 +577,9 @@ main() { # Build process check_dependencies setup_cross_compilation - # build_protobuf # Skipped since protobuf packages are installed + # NOTE: aap_protobuf is built via add_subdirectory(protobuf) inside the main CMake build. + # Prebuilding and installing it separately is unnecessary and can require elevated privileges. + # The previous step has been disabled to keep dry runs Pi-safe and rootless. configure_cmake build_project validate_build diff --git a/cert/.gitignore b/cert/.gitignore new file mode 100644 index 00000000..ea2ee661 --- /dev/null +++ b/cert/.gitignore @@ -0,0 +1,8 @@ +# Allow the default certificates +!headunit.crt +!headunit.key + +# But ignore any custom/user certificates +*.pem +custom_*.crt +custom_*.key diff --git a/cert/README.md b/cert/README.md new file mode 100644 index 00000000..429467a2 --- /dev/null +++ b/cert/README.md @@ -0,0 +1,109 @@ +# SSL/TLS Certificate Configuration + +## Overview + +This directory contains the SSL/TLS certificate and private key used by AASDK for Android Auto communication. These files are used during the SSL handshake between the head unit and the Android device. + +## Files + +- **headunit.crt**: X.509 certificate (Google Automotive Link issued to JVC Kenwood) +- **headunit.key**: RSA private key (2048-bit) +- **.gitignore**: Protects custom certificates from being committed + +## Default Certificate + +The default certificate included (`headunit.crt`) is a publicly available certificate used in Android Auto head units. It is **not a secret** and is suitable for standard Android Auto functionality. + +## Custom Certificates + +You can replace the default certificate with your own: + +1. Create custom certificate files: + - `custom_headunit.crt` + - `custom_headunit.key` + +2. These will be automatically ignored by git (see `.gitignore`) + +3. The application will try loading certificates from these paths in order: + - `/etc/openauto/headunit.crt` (installed location) + - `/usr/share/aasdk/cert/headunit.crt` (alternative system location) + - `./cert/headunit.crt` (development directory) + - `../cert/headunit.crt` (alternative development directory) + +4. If no certificate file is found, the application falls back to the embedded certificate in the code + +## Installation + +When building the aasdk package, the certificate files are automatically installed to `/etc/openauto/` with read-only permissions: + +```bash +# Installed by debian package: +/etc/openauto/headunit.crt (owner: root, permissions: 0644) +/etc/openauto/headunit.key (owner: root, permissions: 0644) +``` + +## Security Notes + +- The default certificate is public and **not confidential** +- Custom certificates can be used for specific vendor requirements +- The private key should be protected if using a custom certificate +- Certificate files are loaded at runtime, allowing updates without recompilation + +## Usage + +The `Cryptor` class in AASDK automatically loads these certificates during initialization: + +```cpp +// Certificate loading happens in Cryptor::init() +std::string certContent = loadCertificate(); // Tries file paths, falls back to embedded +std::string keyContent = loadPrivateKey(); // Tries file paths, falls back to embedded +``` + +Logging is enabled to show which certificate path was successfully loaded: +``` +[INFO] [Cryptor] Loaded certificate from: /etc/openauto/headunit.crt +``` + +## Development + +During development, place your certificate files in the `cert/` directory: +- `cert/headunit.crt` +- `cert/headunit.key` + +The application will automatically find them using the relative path fallback mechanism. + +## Updating Certificates + +To update the certificate on an installed system: + +1. Copy new certificate files to `/etc/openauto/`: + ```bash + sudo cp new_headunit.crt /etc/openauto/headunit.crt + sudo cp new_headunit.key /etc/openauto/headunit.key + sudo chmod 644 /etc/openauto/headunit.* + ``` + +2. Restart the service: + ```bash + sudo systemctl restart openauto + ``` + +No recompilation required! + +## Troubleshooting + +If the certificate fails to load: + +1. Check file permissions: + ```bash + ls -l /etc/openauto/headunit.* + ``` + +2. Verify certificate format (should be PEM): + ```bash + openssl x509 -in /etc/openauto/headunit.crt -text -noout + ``` + +3. Check application logs for certificate loading messages + +4. The application will fall back to the embedded certificate if files cannot be read diff --git a/cert/headunit.crt b/cert/headunit.crt new file mode 100644 index 00000000..45ad6cc4 --- /dev/null +++ b/cert/headunit.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDKjCCAhICARswDQYJKoZIhvcNAQELBQAwWzELMAkGA1UEBhMCVVMxEzARBgNV +BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM +Fkdvb2dsZSBBdXRvbW90aXZlIExpbmswJhcRMTQwNzA0MDAwMDAwLTA3MDAXETQ1 +MDQyOTE0MjgzOC0wNzAwMFMxCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzER +MA8GA1UEBwwISGFjaGlvamkxFDASBgNVBAoMC0pWQyBLZW53b29kMQswCQYDVQQL +DAIwMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM911mNnUfx+WJtx +uk06GO7kXRW/gXUVNQBkbAFZmVdVNvLoEQNthi2X8WCOwX6n6oMPxU2MGJnvicP3 +6kBqfHhfQ2Fvqlf7YjjhgBHh0lqKShVPxIvdatBjVQ76aym5H3GpkigLGkmeyiVo +VO8oc3cJ1bO96wFRmk7kJbYcEjQyakODPDu4QgWUTwp1Z8Dn41ARMG5OFh6otITL +XBzj9REkUPkxfS03dBXGr5/LIqvSsnxib1hJ47xnYJXROUsBy3e6T+fYZEEzZa7y +7tFioHIQ8G/TziPmvFzmQpaWMGiYfoIgX8WoR3GD1diYW+wBaZTW+4SFUZJmRKgq +TbMNFkMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsGdH5VFn78WsBElMXaMziqFC +zmilkvr85/QpGCIztI0FdF6xyMBJk/gYs2thwvF+tCCpXoO8mjgJuvJZlwr6fHzK +Ox5hNUb06AeMtsUzUfFjSZXKrSR+XmclVd+Z6/ie33VhGePOPTKYmJ/PPfTT9wvT +93qswcxhA+oX5yqLbU3uDPF1ZnJaEeD/YN45K/4eEA4/0SDXaWW14OScdS2LV0Bc +YmsbkPVNYZn37FlY7e2Z4FUphh0A7yME2Eh/e57QxWrJ1wubdzGnX8mrABc67ADU +U5r9tlTRqMs7FGOk6QS2Cxp4pqeVQsrPts4OEwyPUyb3LfFNo3+sP111D9zEow== +-----END CERTIFICATE----- diff --git a/cert/headunit.key b/cert/headunit.key new file mode 100644 index 00000000..c2b2666a --- /dev/null +++ b/cert/headunit.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAz3XWY2dR/H5Ym3G6TToY7uRdFb+BdRU1AGRsAVmZV1U28ugR +A22GLZfxYI7Bfqfqgw/FTYwYme+Jw/fqQGp8eF9DYW+qV/tiOOGAEeHSWopKFU/E +i91q0GNVDvprKbkfcamSKAsaSZ7KJWhU7yhzdwnVs73rAVGaTuQlthwSNDJqQ4M8 +O7hCBZRPCnVnwOfjUBEwbk4WHqi0hMtcHOP1ESRQ+TF9LTd0Fcavn8siq9KyfGJv +WEnjvGdgldE5SwHLd7pP59hkQTNlrvLu0WKgchDwb9POI+a8XOZClpYwaJh+giBf +xahHcYPV2Jhb7AFplNb7hIVRkmZEqCpNsw0WQwIDAQABAoIBAB2u7ZLheKCY71Km +bhKYqnKb6BmxgfNfqmq4858p07/kKG2O+Mg1xooFgHrhUhwuKGbCPee/kNGNrXeF +pFW9JrwOXVS2pnfaNw6ObUWhuvhLaxgrhqLAdoUEgWoYOHcKzs3zhj8Gf6di+edq +SyTA8+xnUtVZ6iMRKvP4vtCUqaIgBnXdmQbGINP+/4Qhb5R7XzMt/xPe6uMyAIyC +y5Fm9HnvekaepaeFEf3bh4NV1iN/R8px6cFc6ELYxIZc/4Xbm91WGqSdB0iSriaZ +TjgrmaFjSO40tkCaxI9N6DGzJpmpnMn07ifhl2VjnGOYwtyuh6MKEnyLqTrTg9x0 +i3mMwskCgYEA9IyljPRerXxHUAJt+cKOayuXyNt80q9PIcGbyRNvn7qIY6tr5ut+ +ZbaFgfgHdSJ/4nICRq02HpeDJ8oj9BmhTAhcX6c1irH5ICjRlt40qbPwemIcpybt +mb+DoNYbI8O4dUNGH9IPfGK8dRpOok2m+ftfk94GmykWbZF5CnOKIp8CgYEA2Syc +5xlKB5Qk2ZkwXIzxbzozSfunHhWWdg4lAbyInwa6Y5GB35UNdNWI8TAKZsN2fKvX +RFgCjbPreUbREJaM3oZ92o5X4nFxgjvAE1tyRqcPVbdKbYZgtcqqJX06sW/g3r/3 +RH0XPj2SgJIHew9sMzjGWDViMHXLmntI8rVA7d0CgYBOr36JFwvrqERN0ypNpbMr +epBRGYZVSAEfLGuSzEUrUNqXr019tKIr2gmlIwhLQTmCxApFcXArcbbKs7jTzvde +PoZyZJvOr6soFNozP/YT8Ijc5/quMdFbmgqhUqLS5CPS3z2N+YnwDNj0mO1aPcAP +STmcm2DmxdaolJksqrZ0owKBgQCD0KJDWoQmaXKcaHCEHEAGhMrQot/iULQMX7Vy +gl5iN5E2EgFEFZIfUeRWkBQgH49xSFPWdZzHKWdJKwSGDvrdrcABwdfx520/4MhK +d3y7CXczTZbtN1zHuoTfUE0pmYBhcx7AATT0YCblxrynosrHpDQvIefBBh5YW3AB +cKZCOQKBgEM/ixzI/OVSZ0Py2g+XV8+uGQyC5XjQ6cxkVTX3Gs0ZXbemgUOnX8co +eCXS4VrhEf4/HYMWP7GB5MFUOEVtlLiLM05ruUL7CrphdfgayDXVcTPfk75lLhmu +KAwp3tIHPoJOQiKNQ3/qks5km/9dujUGU2ARiU3qmxLMdgegFz8e +-----END RSA PRIVATE KEY----- diff --git a/cmake_modules/CPackProjectConfig.cmake b/cmake_modules/CPackProjectConfig.cmake new file mode 100644 index 00000000..dcf82120 --- /dev/null +++ b/cmake_modules/CPackProjectConfig.cmake @@ -0,0 +1,8 @@ +# CPack project configuration to harmonize packaging for AASDK +# If CPACK_DEBIAN_PACKAGE_RELEASE was not explicitly set, pick it up from environment + +if(NOT DEFINED CPACK_DEBIAN_PACKAGE_RELEASE) + if(DEFINED ENV{DISTRO_DEB_RELEASE} AND NOT "$ENV{DISTRO_DEB_RELEASE}" STREQUAL "") + set(CPACK_DEBIAN_PACKAGE_RELEASE "$ENV{DISTRO_DEB_RELEASE}") + endif() +endif() diff --git a/cmake_modules/DebPackageFilename.cmake b/cmake_modules/DebPackageFilename.cmake new file mode 100644 index 00000000..5325c5e2 --- /dev/null +++ b/cmake_modules/DebPackageFilename.cmake @@ -0,0 +1,167 @@ +# * Project: OpenAuto +# * This file is part of openauto project. +# * Copyright (C) 2025 OpenCarDev Team +# * +# * openauto is free software: you can redistribute it and/or modify +# * it under the terms of the GNU General Public License as published by +# * the Free Software Foundation; either version 3 of the License, or +# * (at your option) any later version. +# * +# * openauto is distributed in the hope that it will be useful, +# * but WITHOUT ANY WARRANTY; without even the implied warranty of +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# * GNU General Public License for more details. +# * +# * You should have received a copy of the GNU General Public License +# * along with openauto. If not, see . + +# DebPackageFilename.cmake +# Generates Debian package filename based on distribution and architecture +# +# This module sets the following variables: +# DEB_SUITE - Distribution codename (e.g., bookworm, trixie, jammy) +# DEB_VERSION - Distribution version (e.g., deb12, deb13, ubuntu22.04) +# DEB_RELEASE - Release string for filename (e.g., deb13u1, 0ubuntu1~22.04) +# +# Usage: +# include(DebPackageFilename) +# configure_deb_filename(PACKAGE_NAME VERSION ARCHITECTURE ) +message(STATUS "------- Start DebPackageFilename------") +message(STATUS "PACKAGE_NAME: ${DEB_CONFIG_PACKAGE_NAME}") +message(STATUS "VERSION: ${DEB_CONFIG_VERSION}") +message(STATUS "ARCHITECTURE: ${DEB_CONFIG_ARCHITECTURE}") +message(STATUS "-------End DebPackageFilename------") + +function(get_linux_lsb_release_information) + find_program(LSB_RELEASE_EXEC lsb_release) + if(NOT LSB_RELEASE_EXEC) + message(FATAL_ERROR "Could not detect lsb_release executable, can not gather required information") + endif() + + execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --id OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --codename OUTPUT_VARIABLE LSB_RELEASE_CODENAME_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) + + set(LSB_RELEASE_ID_SHORT "${LSB_RELEASE_ID_SHORT}" PARENT_SCOPE) + set(LSB_RELEASE_VERSION_SHORT "${LSB_RELEASE_VERSION_SHORT}" PARENT_SCOPE) + set(LSB_RELEASE_CODENAME_SHORT "${LSB_RELEASE_CODENAME_SHORT}" PARENT_SCOPE) +endfunction() + +# Detect suite/codename for filename +function(detect_deb_suite OUT_SUITE) + message(STATUS "detect_deb_suite") + set(DETECTED_SUITE "unknown") + + if(DEFINED ENV{DISTRO_DEB_SUITE} AND NOT "$ENV{DISTRO_DEB_SUITE}" STREQUAL "") + message(STATUS "DISTRO_DEB_SUITE: ${DISTRO_DEB_SUITE}") + set(DETECTED_SUITE "$ENV{DISTRO_DEB_SUITE}") + elseif(DEFINED CPACK_DEBIAN_PACKAGE_RELEASE AND NOT "${CPACK_DEBIAN_PACKAGE_RELEASE}" STREQUAL "") + if(CMAKE_SYSTEM_NAME MATCHES "Linux") + get_linux_lsb_release_information() + message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}") + set(DETECTED_SUITE "${LSB_RELEASE_CODENAME_SHORT}") + endif() + endif() + message(STATUS "Detected Suite: ${DETECTED_SUITE}") + set(${OUT_SUITE} "${DETECTED_SUITE}" PARENT_SCOPE) +endfunction() + +# Detect debian version for filename (e.g. deb13, deb12) +function(detect_deb_version OUT_VERSION) + message(STATUS "detect_deb_version") + set(DETECTED_VERSION "unknown") + + if(DEFINED CPACK_DEBIAN_PACKAGE_RELEASE AND NOT "${CPACK_DEBIAN_PACKAGE_RELEASE}" STREQUAL "") + message(STATUS "CPACK_DEBIAN_PACKAGE_RELEASE: ${CPACK_DEBIAN_PACKAGE_RELEASE}") + if(CPACK_DEBIAN_PACKAGE_RELEASE MATCHES "deb([0-9]+)") + set(DETECTED_VERSION "deb${CMAKE_MATCH_1}") + elseif(CPACK_DEBIAN_PACKAGE_RELEASE MATCHES "0ubuntu1~([0-9]+\.[0-9]+)") + set(DETECTED_VERSION "ubuntu${CMAKE_MATCH_1}") + elseif(CPACK_DEBIAN_PACKAGE_RELEASE MATCHES "rpi([0-9]+)") + set(DETECTED_VERSION "rpi${CMAKE_MATCH_1}") + else() + set(DETECTED_VERSION "unknown") + endif() + endif() + message(STATUS "DETECTED_VERSION: ${DETECTED_VERSION}") + set(${OUT_VERSION} "${DETECTED_VERSION}" PARENT_SCOPE) +endfunction() + +# Extract release string for filename +function(detect_deb_release OUT_RELEASE) + message(STATUS "detect_deb_release") + set(DETECTED_RELEASE "unknown") + + if(DEFINED CPACK_DEBIAN_PACKAGE_RELEASE AND NOT "${CPACK_DEBIAN_PACKAGE_RELEASE}" STREQUAL "") + message(STATUS "CPACK_DEBIAN_PACKAGE_RELEASE: ${CPACK_DEBIAN_PACKAGE_RELEASE}") + # Remove any leading version numbers (e.g. 1+deb13u1 -> deb13u1) + string(REGEX REPLACE "^[0-9]+[\+~]?" "" DETECTED_RELEASE "${CPACK_DEBIAN_PACKAGE_RELEASE}") + else() + set(DETECTED_RELEASE "unknown") + endif() + + message(STATUS "DETECTED_RELEASE: ${DETECTED_RELEASE}") + set(${OUT_RELEASE} "${DETECTED_RELEASE}" PARENT_SCOPE) +endfunction() + +# Configure the DEB package filename +function(configure_deb_filename) + cmake_parse_arguments( + DEB_CONFIG + "" + "PACKAGE_NAME;VERSION;ARCHITECTURE;RUNTIME_PACKAGE_NAME;DEVELOPMENT_PACKAGE_NAME" + "" + ${ARGN} + ) + + if(NOT DEFINED DEB_CONFIG_PACKAGE_NAME) + message(FATAL_ERROR "PACKAGE_NAME is required for configure_deb_filename") + endif() + + if(NOT DEFINED DEB_CONFIG_VERSION) + message(FATAL_ERROR "VERSION is required for configure_deb_filename") + endif() + + if(NOT DEFINED DEB_CONFIG_ARCHITECTURE) + message(FATAL_ERROR "ARCHITECTURE is required for configure_deb_filename") + endif() + + # Detect all components + detect_deb_suite(DEB_SUITE_VAL) + detect_deb_version(DEB_VERSION_VAL) + detect_deb_release(DEB_RELEASE_VAL) + + # Set parent scope variables + set(DEB_SUITE "${DEB_SUITE_VAL}" PARENT_SCOPE) + set(DEB_VERSION "${DEB_VERSION_VAL}" PARENT_SCOPE) + set(DEB_RELEASE "${DEB_RELEASE_VAL}" PARENT_SCOPE) + + # Generate filename + set(FILENAME "${DEB_CONFIG_PACKAGE_NAME}_${DEB_CONFIG_VERSION}_${DEB_RELEASE_VAL}_${DEB_CONFIG_ARCHITECTURE}.deb") + set(CPACK_DEBIAN_FILE_NAME "${FILENAME}" PARENT_SCOPE) + + # Generate runtime and development package filenames if specified + if(DEFINED DEB_CONFIG_RUNTIME_PACKAGE_NAME) + set(RUNTIME_FILENAME "${DEB_CONFIG_RUNTIME_PACKAGE_NAME}_${DEB_CONFIG_VERSION}_${DEB_RELEASE_VAL}_${DEB_CONFIG_ARCHITECTURE}.deb") + set(CPACK_DEBIAN_RUNTIME_FILE_NAME "${RUNTIME_FILENAME}" PARENT_SCOPE) + endif() + + if(DEFINED DEB_CONFIG_DEVELOPMENT_PACKAGE_NAME) + set(DEVELOPMENT_FILENAME "${DEB_CONFIG_DEVELOPMENT_PACKAGE_NAME}_${DEB_CONFIG_VERSION}_${DEB_RELEASE_VAL}_${DEB_CONFIG_ARCHITECTURE}.deb") + set(CPACK_DEBIAN_DEVELOPMENT_FILE_NAME "${DEVELOPMENT_FILENAME}" PARENT_SCOPE) + endif() + + # Debug output + message(STATUS "DEB Package Filename Configuration:") + message(STATUS " Suite: ${DEB_SUITE_VAL}") + message(STATUS " Version: ${DEB_VERSION_VAL}") + message(STATUS " Release: ${DEB_RELEASE_VAL}") + message(STATUS " Architecture: ${DEB_CONFIG_ARCHITECTURE}") + message(STATUS " Filename: ${FILENAME}") + if(DEFINED DEB_CONFIG_RUNTIME_PACKAGE_NAME) + message(STATUS " Runtime Filename: ${RUNTIME_FILENAME}") + endif() + if(DEFINED DEB_CONFIG_DEVELOPMENT_PACKAGE_NAME) + message(STATUS " Development Filename: ${DEVELOPMENT_FILENAME}") + endif() +endfunction() diff --git a/cmake_modules/gitversion.cmake b/cmake_modules/gitversion.cmake index b3267b5d..2b4182fa 100644 --- a/cmake_modules/gitversion.cmake +++ b/cmake_modules/gitversion.cmake @@ -4,48 +4,127 @@ cmake_minimum_required(VERSION 3.0.0) message(STATUS "Resolving GIT Version") set(_build_version "unknown") +set(_build_branch "unknown") +set(_build_describe "unknown") set(_commit_timestamp "unknown") +set(_build_changes "") -find_package(Git) -if(GIT_FOUND) - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD - WORKING_DIRECTORY "${local_dir}" - OUTPUT_VARIABLE _build_version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY "${local_dir}" - OUTPUT_VARIABLE _build_branch - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - execute_process( - COMMAND ${GIT_EXECUTABLE} log -1 --format=%at - WORKING_DIRECTORY "${local_dir}" - OUTPUT_VARIABLE _commit_timestamp - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - message( STATUS "GIT hash: ${_build_version}; branch: ${_build_branch}; Commit epoch: ${_commit_timestamp};") - execute_process( - COMMAND ${GIT_EXECUTABLE} diff --no-ext-diff --quiet - WORKING_DIRECTORY "${local_dir}" - RESULT_VARIABLE ret - ) - if(ret EQUAL "1") + +# Prefer environment variables if set (for Docker/Podman builds) +if(DEFINED ENV{GIT_COMMIT_ID} AND NOT "$ENV{GIT_COMMIT_ID}" STREQUAL "unknown") + set(_build_version "$ENV{GIT_COMMIT_ID}") + message(STATUS "GIT_COMMIT_ID from ENV: $ENV{GIT_COMMIT_ID}") +else() + message(STATUS "GIT_COMMIT_ID not set in ENV, will use git command if possible.") +endif() +if(DEFINED ENV{GIT_BRANCH} AND NOT "$ENV{GIT_BRANCH}" STREQUAL "unknown") + set(_build_branch "$ENV{GIT_BRANCH}") + message(STATUS "GIT_BRANCH from ENV: $ENV{GIT_BRANCH}") +else() + message(STATUS "GIT_BRANCH not set in ENV, will use git command if possible.") +endif() +if(DEFINED ENV{GIT_DESCRIBE} AND NOT "$ENV{GIT_DESCRIBE}" STREQUAL "unknown") + set(_build_describe "$ENV{GIT_DESCRIBE}") + message(STATUS "GIT_DESCRIBE from ENV: $ENV{GIT_DESCRIBE}") +else() + message(STATUS "GIT_DESCRIBE not set in ENV, will use git command if possible.") +endif() +if(DEFINED ENV{GIT_DIRTY} AND NOT "$ENV{GIT_DIRTY}" STREQUAL "unknown") + if($ENV{GIT_DIRTY} GREATER 0) set(_build_changes "*") else() set(_build_changes "") endif() + message(STATUS "GIT_DIRTY from ENV: $ENV{GIT_DIRTY}") +else() + message(STATUS "GIT_DIRTY not set in ENV, will use git command if possible.") +endif() +if(DEFINED ENV{GIT_COMMIT_TIMESTAMP} AND NOT "$ENV{GIT_COMMIT_TIMESTAMP}" STREQUAL "unknown") + set(_commit_timestamp "$ENV{GIT_COMMIT_TIMESTAMP}") + message(STATUS "GIT_COMMIT_TIMESTAMP from ENV: $ENV{GIT_COMMIT_TIMESTAMP}") +else() + message(STATUS "GIT_COMMIT_TIMESTAMP not set in ENV, will use git command if possible.") +endif() + +# Fallback to git commands if env vars not set +if(_build_branch STREQUAL "unknown") + find_package(Git) + if(GIT_FOUND) + if(_build_version STREQUAL "unknown") + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD + WORKING_DIRECTORY "${local_dir}" + OUTPUT_VARIABLE _build_version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + message(STATUS "GIT_COMMIT_ID from git command: ${_build_version}") + endif() + if(_build_branch STREQUAL "unknown") + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY "${local_dir}" + OUTPUT_VARIABLE _build_branch + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + message(STATUS "GIT_BRANCH from git command: ${_build_branch}") + endif() + if(_build_describe STREQUAL "unknown") + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --tags --dirty --always + WORKING_DIRECTORY "${local_dir}" + OUTPUT_VARIABLE _build_describe + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + message(STATUS "GIT_DESCRIBE from git command: ${_build_describe}") + endif() + if(_commit_timestamp STREQUAL "unknown") + execute_process( + COMMAND ${GIT_EXECUTABLE} log -1 --format=%at + WORKING_DIRECTORY "${local_dir}" + OUTPUT_VARIABLE _commit_timestamp + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + message(STATUS "GIT_COMMIT_TIMESTAMP from git command: ${_commit_timestamp}") + endif() + message(STATUS "Final GIT values: hash: ${_build_version}; branch: ${_build_branch}; describe: ${_build_describe}; changes: ${_build_changes}; Commit epoch: ${_commit_timestamp};") + if(_build_changes STREQUAL "") + execute_process( + COMMAND ${GIT_EXECUTABLE} diff --no-ext-diff --quiet + WORKING_DIRECTORY "${local_dir}" + RESULT_VARIABLE ret + ) + if(ret EQUAL "1") + set(_build_changes "*") + else() + set(_build_changes "") + endif() + endif() + else() + message(STATUS "GIT not found") + endif() +endif() +# Export variables with standard names for CMakeLists.txt +# Note: Using regular set() without PARENT_SCOPE because this is included, not called as a function +set(GIT_COMMIT_ID "${_build_version}") +set(GIT_BRANCH "${_build_branch}") +set(GIT_DESCRIBE "${_build_describe}") +set(GIT_COMMIT_TIMESTAMP "${_commit_timestamp}") + +# Convert _build_changes to GIT_DIRTY (0 for clean, 1 for dirty) +if(_build_changes STREQUAL "*") + set(GIT_DIRTY 1) else() - message(STATUS "GIT not found") + set(GIT_DIRTY 0) endif() -# branch name -# git rev-parse --abbrev-ref HEAD -# changed -# git diff --no-ext-diff --quiet +message(STATUS "Exported GIT_COMMIT_ID: ${_build_version}") +message(STATUS "Exported GIT_BRANCH: ${_build_branch}") +message(STATUS "Exported GIT_DESCRIBE: ${_build_describe}") +message(STATUS "Exported GIT_COMMIT_TIMESTAMP: ${_commit_timestamp}") +message(STATUS "Exported GIT_DIRTY: ${GIT_DIRTY}") + diff --git a/cmake_modules_old/CodeCoverage.cmake b/cmake_modules_old/CodeCoverage.cmake new file mode 100644 index 00000000..2527b3c2 --- /dev/null +++ b/cmake_modules_old/CodeCoverage.cmake @@ -0,0 +1,238 @@ +# Copyright (c) 2012 - 2017, Lars Bilke +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# CHANGES: +# +# 2012-01-31, Lars Bilke +# - Enable Code Coverage +# +# 2013-09-17, Joakim Söderberg +# - Added support for Clang. +# - Some additional usage instructions. +# +# 2016-02-03, Lars Bilke +# - Refactored functions to use named parameters +# +# 2017-06-02, Lars Bilke +# - Merged with modified version from github.com/ufz/ogs +# +# +# USAGE: +# +# 1. Copy this file into your cmake modules path. +# +# 2. Add the following line to your CMakeLists.txt: +# include(CodeCoverage) +# +# 3. Append necessary compiler flags: +# APPEND_COVERAGE_COMPILER_FLAGS() +# +# 4. If you need to exclude additional directories from the report, specify them +# using the COVERAGE_EXCLUDES variable before calling SETUP_TARGET_FOR_COVERAGE. +# Example: +# set(COVERAGE_EXCLUDES 'dir1/*' 'dir2/*') +# +# 5. Use the functions described below to create a custom make target which +# runs your test executable and produces a code coverage report. +# +# 6. Build a Debug build: +# cmake -DCMAKE_BUILD_TYPE=Debug .. +# make +# make my_coverage_target +# + +include(CMakeParseArguments) + +# Check prereqs +find_program( GCOV_PATH gcov ) +find_program( LCOV_PATH lcov ) +find_program( GENHTML_PATH genhtml ) +find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test) +find_program( SIMPLE_PYTHON_EXECUTABLE python ) + +if(NOT GCOV_PATH) + message(FATAL_ERROR "gcov not found! Aborting...") +endif() # NOT GCOV_PATH + +if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") + if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3) + message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") + endif() +elseif(NOT CMAKE_COMPILER_IS_GNUCXX) + message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...") +endif() + +set(COVERAGE_COMPILER_FLAGS "-g -O0 --coverage -fprofile-arcs -ftest-coverage" + CACHE INTERNAL "") + +set(CMAKE_CXX_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the C++ compiler during coverage builds." + FORCE ) +set(CMAKE_C_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the C compiler during coverage builds." + FORCE ) +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "" + CACHE STRING "Flags used for linking binaries during coverage builds." + FORCE ) +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE + "" + CACHE STRING "Flags used by the shared libraries linker during coverage builds." + FORCE ) +mark_as_advanced( + CMAKE_CXX_FLAGS_COVERAGE + CMAKE_C_FLAGS_COVERAGE + CMAKE_EXE_LINKER_FLAGS_COVERAGE + CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) + +if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading") +endif() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug" + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + link_libraries(gcov) +else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") +endif() + +# Defines a target for running and collection code coverage information +# Builds dependencies, runs the given executable and outputs reports. +# NOTE! The executable should always have a ZERO as exit code otherwise +# the coverage generation will not complete. +# +# SETUP_TARGET_FOR_COVERAGE( +# NAME testrunner_coverage # New target name +# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR +# DEPENDENCIES testrunner # Dependencies to build first +# ) +function(SETUP_TARGET_FOR_COVERAGE) + + set(options NONE) + set(oneValueArgs NAME) + set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) + cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT LCOV_PATH) + message(FATAL_ERROR "lcov not found! Aborting...") + endif() # NOT LCOV_PATH + + if(NOT GENHTML_PATH) + message(FATAL_ERROR "genhtml not found! Aborting...") + endif() # NOT GENHTML_PATH + + # Setup target + add_custom_target(${Coverage_NAME} + + # Cleanup lcov + COMMAND ${LCOV_PATH} --directory . --zerocounters + # Create baseline to make sure untouched files show up in the report + COMMAND ${LCOV_PATH} -c -i -d . -o ${Coverage_NAME}.base + + # Run tests + COMMAND ${Coverage_EXECUTABLE} + + # Capturing lcov counters and generating report + COMMAND ${LCOV_PATH} --directory . --capture --output-file ${Coverage_NAME}.info + # add baseline counters + COMMAND ${LCOV_PATH} -a ${Coverage_NAME}.base -a ${Coverage_NAME}.info --output-file ${Coverage_NAME}.total + COMMAND ${LCOV_PATH} --remove ${Coverage_NAME}.total ${COVERAGE_EXCLUDES} --output-file ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned + COMMAND ${GENHTML_PATH} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned + COMMAND ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.info ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned + + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${Coverage_DEPENDENCIES} + COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." + ) + + # Show info where to find the report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." + ) + +endfunction() # SETUP_TARGET_FOR_COVERAGE + +# Defines a target for running and collection code coverage information +# Builds dependencies, runs the given executable and outputs reports. +# NOTE! The executable should always have a ZERO as exit code otherwise +# the coverage generation will not complete. +# +# SETUP_TARGET_FOR_COVERAGE_COBERTURA( +# NAME ctest_coverage # New target name +# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR +# DEPENDENCIES executable_target # Dependencies to build first +# ) +function(SETUP_TARGET_FOR_COVERAGE_COBERTURA) + + set(options NONE) + set(oneValueArgs NAME) + set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) + cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT SIMPLE_PYTHON_EXECUTABLE) + message(FATAL_ERROR "python not found! Aborting...") + endif() # NOT SIMPLE_PYTHON_EXECUTABLE + + if(NOT GCOVR_PATH) + message(FATAL_ERROR "gcovr not found! Aborting...") + endif() # NOT GCOVR_PATH + + # Combine excludes to several -e arguments + set(COBERTURA_EXCLUDES "") + foreach(EXCLUDE ${COVERAGE_EXCLUDES}) + set(COBERTURA_EXCLUDES "-e ${EXCLUDE} ${COBERTURA_EXCLUDES}") + endforeach() + + add_custom_target(${Coverage_NAME} + + # Run tests + ${Coverage_EXECUTABLE} + + # Running gcovr + COMMAND ${GCOVR_PATH} -x -r ${CMAKE_SOURCE_DIR} ${COBERTURA_EXCLUDES} + -o ${Coverage_NAME}.xml + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${Coverage_DEPENDENCIES} + COMMENT "Running gcovr to produce Cobertura code coverage report." + ) + + # Show info where to find the report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml." + ) + +endfunction() # SETUP_TARGET_FOR_COVERAGE_COBERTURA + +function(APPEND_COVERAGE_COMPILER_FLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}") +endfunction() # APPEND_COVERAGE_COMPILER_FLAGS diff --git a/cmake_modules_old/Findaap_protobuf.cmake b/cmake_modules_old/Findaap_protobuf.cmake new file mode 100644 index 00000000..7e2eda82 --- /dev/null +++ b/cmake_modules_old/Findaap_protobuf.cmake @@ -0,0 +1,55 @@ +if (AAP_PROTOBUF_LIB_DIRS AND AAP_PROTOBUF_INCLUDE_DIRS) + # in cache already + message(STATUS "aap_protobuf is cached") + set(AAP_PROTOBUF_FOUND TRUE) +else (AAP_PROTOBUF_LIB_DIRS AND AAP_PROTOBUF_INCLUDE_DIRS) + find_path(AAP_PROTOBUF_INCLUDE_DIR + NAMES + channel/control/GalConstants.pb.h + PATHS + /usr/include + /usr/local/include + /opt/local/include + /sw/include + PATH_SUFFIXES + aap_protobuf + ) + + find_library(AAP_PROTOBUF_LIB_DIR + NAMES + aap_protobuf libaap_protobuf + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /sw/lib + ) + + set(AAP_PROTOBUF_INCLUDE_DIRS + ${AAP_PROTOBUF_INCLUDE_DIR} + ) + set(AAP_PROTOBUF_LIB_DIRS + ${AAP_PROTOBUF_LIB_DIR} + ) + + if (AAP_PROTOBUF_INCLUDE_DIRS AND AAP_PROTOBUF_LIB_DIRS) + set(AAP_PROTOBUF_FOUND TRUE) + endif (AAP_PROTOBUF_INCLUDE_DIRS AND AAP_PROTOBUF_LIB_DIRS) + + if (AAP_PROTOBUF_FOUND) + message(STATUS "SUCCESS. Found: aap_protobuf:") + message(STATUS " - Includes: ${AAP_PROTOBUF_INCLUDE_DIRS}") + message(STATUS " - Libraries: ${AAP_PROTOBUF_LIB_DIRS}") + add_library(aap_protobuf INTERFACE) + target_include_directories(aap_protobuf SYSTEM INTERFACE ${AAP_PROTOBUF_INCLUDE_DIR}) + target_link_libraries(aap_protobuf INTERFACE ${AAP_PROTOBUF_LIB_DIR}) + else (AAP_PROTOBUF_FOUND) + message(STATUS " - Includes: ${AAP_PROTOBUF_INCLUDE_DIRS}") + message(STATUS " - Libraries: ${AAP_PROTOBUF_LIB_DIRS}") + message(FATAL_ERROR "Could not locate aap_protobuf") + endif (AAP_PROTOBUF_FOUND) + + # show the AAP_PROTOBUF_INCLUDE_DIRS and AAP_PROTOBUF_LIB_DIRS variables only in the advanced view + mark_as_advanced(AAP_PROTOBUF_INCLUDE_DIRS AAP_PROTOBUF_LIB_DIRS) + +endif (AAP_PROTOBUF_LIB_DIRS AND AAP_PROTOBUF_INCLUDE_DIRS) diff --git a/cmake_modules_old/Findlibusb-1.0.cmake b/cmake_modules_old/Findlibusb-1.0.cmake new file mode 100644 index 00000000..311cbc14 --- /dev/null +++ b/cmake_modules_old/Findlibusb-1.0.cmake @@ -0,0 +1,101 @@ +# - Try to find libusb-1.0 +# Once done this will define +# +# LIBUSB_1_FOUND - system has libusb +# LIBUSB_1_INCLUDE_DIRS - the libusb include directory +# LIBUSB_1_LIBRARIES - Link these to use libusb +# LIBUSB_1_DEFINITIONS - Compiler switches required for using libusb +# +# Adapted from cmake-modules Google Code project +# +# Copyright (c) 2006 Andreas Schneider +# +# (Changes for libusb) Copyright (c) 2008 Kyle Machulis +# +# Redistribution and use is allowed according to the terms of the New BSD license. +# +# CMake-Modules Project New BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of the CMake-Modules Project nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) + # in cache already + set(LIBUSB_FOUND TRUE) +else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) + find_path(LIBUSB_1_INCLUDE_DIR + NAMES + libusb.h + PATHS + /usr/include + /usr/local/include + /opt/local/include + /sw/include + PATH_SUFFIXES + libusb-1.0 + ) + + find_library(LIBUSB_1_LIBRARY + NAMES + usb-1.0 usb + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /sw/lib + ) + + set(LIBUSB_1_INCLUDE_DIRS + ${LIBUSB_1_INCLUDE_DIR} + ) + set(LIBUSB_1_LIBRARIES + ${LIBUSB_1_LIBRARY} +) + + if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES) + set(LIBUSB_1_FOUND TRUE) + endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES) + + if (LIBUSB_1_FOUND) + if (NOT libusb_1_FIND_QUIETLY) + message(STATUS "Found libusb-1.0:") + message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}") + message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}") + add_library(libusb INTERFACE) + target_include_directories(libusb SYSTEM INTERFACE ${LIBUSB_1_INCLUDE_DIR}) + target_link_libraries(libusb INTERFACE ${LIBUSB_1_LIBRARY}) + endif (NOT libusb_1_FIND_QUIETLY) + else (LIBUSB_1_FOUND) + if (libusb-1.0_FIND_REQUIRED) + message(FATAL_ERROR "Could not find libusb") + endif (libusb-1.0_FIND_REQUIRED) + endif (LIBUSB_1_FOUND) + + # show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view + mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES) + +endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) diff --git a/cmake_modules_old/gitversion.cmake b/cmake_modules_old/gitversion.cmake new file mode 100644 index 00000000..b3267b5d --- /dev/null +++ b/cmake_modules_old/gitversion.cmake @@ -0,0 +1,51 @@ +# cmake/gitversion.cmake +cmake_minimum_required(VERSION 3.0.0) + +message(STATUS "Resolving GIT Version") + +set(_build_version "unknown") +set(_commit_timestamp "unknown") + +find_package(Git) +if(GIT_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD + WORKING_DIRECTORY "${local_dir}" + OUTPUT_VARIABLE _build_version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY "${local_dir}" + OUTPUT_VARIABLE _build_branch + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + execute_process( + COMMAND ${GIT_EXECUTABLE} log -1 --format=%at + WORKING_DIRECTORY "${local_dir}" + OUTPUT_VARIABLE _commit_timestamp + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + message( STATUS "GIT hash: ${_build_version}; branch: ${_build_branch}; Commit epoch: ${_commit_timestamp};") + execute_process( + COMMAND ${GIT_EXECUTABLE} diff --no-ext-diff --quiet + WORKING_DIRECTORY "${local_dir}" + RESULT_VARIABLE ret + ) + if(ret EQUAL "1") + set(_build_changes "*") + else() + set(_build_changes "") + endif() + +else() + message(STATUS "GIT not found") +endif() + +# branch name +# git rev-parse --abbrev-ref HEAD +# changed +# git diff --no-ext-diff --quiet diff --git a/debian/postinst b/debian/postinst index 05493966..726fe0a1 100755 --- a/debian/postinst +++ b/debian/postinst @@ -2,12 +2,56 @@ # postinst script for libaasdk set -e +export DEBIAN_FRONTEND=noninteractive case "$1" in configure) + cert_dir="/etc/aasdk" + legacy_dir="/etc/openauto" + cert_file="$cert_dir/headunit.crt" + key_file="$cert_dir/headunit.key" + + # Ensure dedicated runtime group exists. + if ! getent group aasdk >/dev/null 2>&1; then + if command -v addgroup >/dev/null 2>&1; then + addgroup --system aasdk || true + elif command -v groupadd >/dev/null 2>&1; then + groupadd --system aasdk || true + fi + fi + + # Ensure target cert directory exists. + mkdir -p "$cert_dir" + chmod 755 "$cert_dir" || true + + # Migrate from the old location if needed. + if [ ! -f "$cert_file" ] && [ -f "$legacy_dir/headunit.crt" ]; then + cp -f "$legacy_dir/headunit.crt" "$cert_file" + fi + + if [ ! -f "$key_file" ] && [ -f "$legacy_dir/headunit.key" ]; then + cp -f "$legacy_dir/headunit.key" "$key_file" + fi + + # Prefer a dedicated service group when present. + cert_group="root" + if getent group aasdk >/dev/null 2>&1; then + cert_group="aasdk" + fi + + if [ -f "$cert_file" ]; then + chown root:"$cert_group" "$cert_file" || true + chmod 644 "$cert_file" || true + fi + + if [ -f "$key_file" ]; then + chown root:"$cert_group" "$key_file" || true + chmod 640 "$key_file" || true + fi + # Update the dynamic linker cache if [ -x /sbin/ldconfig ]; then - /sbin/ldconfig + /sbin/ldconfig || true fi ;; diff --git a/debian/prerm b/debian/prerm index f9239778..41374376 100755 --- a/debian/prerm +++ b/debian/prerm @@ -2,10 +2,15 @@ # prerm script for libaasdk set -e +export DEBIAN_FRONTEND=noninteractive case "$1" in - remove|upgrade|deconfigure) - # Nothing specific to do + remove|deconfigure) + # Library removal - nothing specific to do + ;; + + upgrade) + # During upgrade, nothing to do for a library package ;; failed-upgrade) diff --git a/scripts/distro_release.sh b/scripts/distro_release.sh new file mode 100755 index 00000000..f5964d7a --- /dev/null +++ b/scripts/distro_release.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Compute distro-specific Debian revision suffix for CPack DEB packages. +# See openauto/scripts/distro_release.sh for details. + +if [[ -r /etc/os-release ]]; then + # shellcheck disable=SC1091 + . /etc/os-release +else + echo "1~unknown" && exit 0 +fi + +id_lc=$(echo "${ID:-unknown}" | tr '[:upper:]' '[:lower:]') +suite=${VERSION_CODENAME:-unknown} +verid=${VERSION_ID:-0} + +case "$id_lc" in + debian) + case "$suite" in + bookworm) deb_num=12 ;; + trixie) deb_num=13 ;; + *) deb_num="${verid%%.*}" ;; + esac + if [[ -n "${deb_num}" ]]; then + echo "1+deb${deb_num}u1" + else + echo "1~debian${suite}1" + fi + ;; + ubuntu) + series="${verid}" + echo "0ubuntu1~${series}" + ;; + raspbian|raspios) + series="${verid%%.*}" + echo "1+rpi${series}u1" + ;; + *) + echo "1~${id_lc}${verid}-${suite}" + ;; +esac