diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e9d9c9..11de71c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.16) project(salmanoff VERSION 0.00.004 LANGUAGES CXX) include(CMakeDependentOption) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DAPSS.cmake) # Set C++ standard set(CMAKE_CXX_STANDARD 20) @@ -60,6 +61,7 @@ add_subdirectory(smocore) add_subdirectory(commonLibs) add_subdirectory(senseApis) add_subdirectory(wilzorApis) +add_subdirectory(devices) # Main executable add_executable(salmanoff main.cpp) @@ -69,4 +71,7 @@ target_link_libraries(salmanoff ${DL_LIBRARY} ) +# Add all registered DAPSS targets as dependencies +add_all_daps_dependencies() + install(TARGETS salmanoff DESTINATION bin) diff --git a/cmake/DAPSS.cmake b/cmake/DAPSS.cmake new file mode 100644 index 0000000..29ab7ad --- /dev/null +++ b/cmake/DAPSS.cmake @@ -0,0 +1,153 @@ +# DAPSS (Device Attachment Pipe Specification Source) preprocessing module +# This module provides functionality to preprocess .dapss files to .daps files +# using the C preprocessor, respecting include directories and target dependencies. +# +# Usage: +# add_daps_target(target_name SOURCES file1.dapss file2.dapss ...) +# register_daps_target(target_name) # In subdirectories +# add_all_daps_dependencies() # In main CMakeLists.txt +# +# Examples: +# add_daps_target(device_specs SOURCES devices/avia0.dapss devices/win0.dapss) +# register_daps_target(device_specs) +# add_all_daps_dependencies() +# +# The preprocessed .daps files will be placed in ${CMAKE_CURRENT_BINARY_DIR}/ + +# Function to add a DAPSS preprocessing target +# Usage: add_daps_target(target_name SOURCES file1.dapss file2.dapss ...) +function(add_daps_target target_name) + set(options) + set(oneValueArgs) + set(multiValueArgs SOURCES) + cmake_parse_arguments(DAPS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT DAPS_SOURCES) + message(FATAL_ERROR "add_daps_target: No SOURCES specified for target ${target_name}") + endif() + + # Use binary directory directly for processed files + # This ensures files are created in the same directory as the target + set(output_dir "${CMAKE_CURRENT_BINARY_DIR}") + + # List to store all output files + set(output_files) + + # Process each source file + foreach(source_file ${DAPS_SOURCES}) + # Get the base name without extension + get_filename_component(base_name ${source_file} NAME_WE) + get_filename_component(source_dir ${source_file} DIRECTORY) + + # Create output file path + set(output_file "${output_dir}/${base_name}.daps") + list(APPEND output_files ${output_file}) + + # Get include directories from current directory and target + get_directory_property(include_dirs INCLUDE_DIRECTORIES) + + # Build include flags + set(include_flags) + foreach(include_dir ${include_dirs}) + list(APPEND include_flags "-I${include_dir}") + endforeach() + + # Add current source directory to includes if it's not already there + if(source_dir) + list(APPEND include_flags "-I${source_dir}") + endif() + + # Convert list to space-separated string + string(REPLACE ";" " " include_flags_str "${include_flags}") + + # Find C compiler if not already set + if(NOT CMAKE_C_COMPILER) + find_program(CMAKE_C_COMPILER gcc cc clang) + if(NOT CMAKE_C_COMPILER) + message(FATAL_ERROR "No C compiler found for DAPSS preprocessing") + endif() + endif() + + # Create custom command to preprocess the file + add_custom_command( + OUTPUT ${output_file} + COMMAND sh -c "\"${CMAKE_C_COMPILER}\" -E -P -x c ${include_flags_str} \"${CMAKE_CURRENT_SOURCE_DIR}/${source_file}\" > \"${output_file}\"" + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${source_file} + COMMENT "Preprocessing ${source_file} to ${base_name}.daps" + VERBATIM + ) + endforeach() + + # Create custom target that depends on all output files + add_custom_target(${target_name} DEPENDS ${output_files}) + + # Make the target part of the ALL target so it gets built by default + # This ensures it gets built when building just this subdirectory + set_target_properties(${target_name} PROPERTIES + FOLDER "${CMAKE_CURRENT_SOURCE_DIR}" + EXCLUDE_FROM_ALL FALSE + ) + + # Set target properties + set_target_properties(${target_name} PROPERTIES + DAPS_OUTPUT_DIR ${output_dir} + DAPS_OUTPUT_FILES "${output_files}" + ) + + # Make the target available globally + set(${target_name}_OUTPUT_DIR ${output_dir} PARENT_SCOPE) + set(${target_name}_OUTPUT_FILES "${output_files}" PARENT_SCOPE) +endfunction() + +# Function to register a DAPSS target for later dependency addition +# Usage: register_daps_target(target_name) +# This stores the target name in a global property for later use +function(register_daps_target target_name) + # Store the target name in a global property + get_property(registered_targets GLOBAL PROPERTY DAPS_REGISTERED_TARGETS) + list(APPEND registered_targets ${target_name}) + set_property(GLOBAL PROPERTY DAPS_REGISTERED_TARGETS ${registered_targets}) + message(STATUS "Registered DAPSS target ${target_name} for later dependency addition") +endfunction() + +# Function to add all registered DAPSS targets as dependencies +# Usage: add_all_daps_dependencies([TARGET main_target] [CONDITION condition_expression]) +# This should be called from the main CMakeLists.txt after all subdirectories are processed +function(add_all_daps_dependencies) + set(options) + set(oneValueArgs TARGET CONDITION) + set(multiValueArgs) + cmake_parse_arguments(DAPS_ALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Default target is PROJECT_NAME + if(DAPS_ALL_TARGET) + set(dep_target ${DAPS_ALL_TARGET}) + else() + set(dep_target ${PROJECT_NAME}) + endif() + + # Get all registered targets + get_property(registered_targets GLOBAL PROPERTY DAPS_REGISTERED_TARGETS) + + if(registered_targets) + foreach(target_name ${registered_targets}) + if(TARGET ${target_name}) + if(DAPS_ALL_CONDITION) + if(${DAPS_ALL_CONDITION}) + add_dependencies(${dep_target} ${target_name}) + message(STATUS "Added registered DAPSS target ${target_name} as dependency of ${dep_target} (condition: ${DAPS_ALL_CONDITION})") + else() + message(STATUS "Skipped registered DAPSS target ${target_name} (condition: ${DAPS_ALL_CONDITION} not met)") + endif() + else() + add_dependencies(${dep_target} ${target_name}) + message(STATUS "Added registered DAPSS target ${target_name} as dependency of ${dep_target}") + endif() + else() + message(WARNING "Registered DAPSS target ${target_name} does not exist") + endif() + endforeach() + else() + message(STATUS "No DAPSS targets registered for dependency addition") + endif() +endfunction() diff --git a/devices/CMakeLists.txt b/devices/CMakeLists.txt new file mode 100644 index 0000000..17a6efc --- /dev/null +++ b/devices/CMakeLists.txt @@ -0,0 +1,13 @@ +add_subdirectory(bodies) + +add_daps_target(all_device_specs + SOURCES + avia0.dapss + win0.dapss +) + +# Register this target for later dependency addition from main CMakeLists.txt +register_daps_target(all_device_specs) +# Make the DAPSS target part of the ALL target for this subdirectory +# This ensures DAPSS targets are built when building just this subdirectory +set_property(TARGET all_device_specs PROPERTY FOLDER "devices") diff --git a/devices/bodies/CMakeLists.txt b/devices/bodies/CMakeLists.txt new file mode 100644 index 0000000..9da90e9 --- /dev/null +++ b/devices/bodies/CMakeLists.txt @@ -0,0 +1,17 @@ +add_daps_target(body_rpi5_persys + SOURCES + rpi5-persys.dapss +) + +add_daps_target(body_dell_laptop + SOURCES + dell-laptop.dapss +) + +# Register this target for later dependency addition from main CMakeLists.txt +register_daps_target(body_rpi5_persys) +register_daps_target(body_dell_laptop) +# Make the DAPSS target part of the ALL target for this subdirectory +# This ensures DAPSS targets are built when building just this subdirectory +set_property(TARGET body_rpi5_persys PROPERTY FOLDER "devices/bodies") +set_property(TARGET body_dell_laptop PROPERTY FOLDER "devices/bodies") diff --git a/devices/bodies/dell-laptop.dapss b/devices/bodies/dell-laptop.dapss new file mode 100644 index 0000000..8986ebc --- /dev/null +++ b/devices/bodies/dell-laptop.dapss @@ -0,0 +1,3 @@ +#include "../win0.dapss" +|| +#include "../avia0.dapss" diff --git a/devices/bodies/rpi5-persys.dapss b/devices/bodies/rpi5-persys.dapss new file mode 100644 index 0000000..8986ebc --- /dev/null +++ b/devices/bodies/rpi5-persys.dapss @@ -0,0 +1,3 @@ +#include "../win0.dapss" +|| +#include "../avia0.dapss"