Ver Fonte

cmake: Add Arduino cross-compiling and package gen

Add a `hydrogen-arduino-package` target which generates
`hydrogen-crypto.zip` for inclusion into Arduino Sketch projects.

Add a toolchain file for Arduino/AVR. Passing
`-DCMAKE_TOOLCHAIN_FILE=cmake/arduino-avr-toolchain.cmake` to the CMake
command line configures cross-compilation for Arduino. A target device
identifier can be specified via `-DARDUINO_AVR_TARGET_DEVICE=...`
(default: `atmega328p`), which configures -mmcu=... and enables the
appropriate `HYDRO_TARGET_DEVICE_*` C preprocessor flag (e.g.,
`HYDRO_TARGET_DEVICE_ATMEGA328`). The path to the Arduino SDK home
directory can be specified via `-DARDUINO_AVR_SDK_DIR=...`; if not set,
the toolchain file checks for the `ARDUINO_SDK_PATH` environment
variable, and then guesses a few locations based on the host OS (e.g.,
`/Applications/Arduino.app/Contents/Java` for macOS).
Michael Smith há 6 anos atrás
pai
commit
da795dafb7
3 ficheiros alterados com 145 adições e 1 exclusões
  1. 0 1
      .gitignore
  2. 19 0
      CMakeLists.txt
  3. 126 0
      cmake/arduino-avr-toolchain.cmake

+ 0 - 1
.gitignore

@@ -1,5 +1,4 @@
 *.bc
 *.bc
-*.cmake
 *.dSYM
 *.dSYM
 *.done
 *.done
 *.final
 *.final

+ 19 - 0
CMakeLists.txt

@@ -37,6 +37,9 @@ set(header_files
 set(test_files
 set(test_files
         "tests/tests.c")
         "tests/tests.c")
 
 
+set(arduino_files
+        "library.properties")
+
 # Compile options
 # Compile options
 
 
 get_setting(target_arch STRING "Target system architecture (fed to the compiler's -march=...).")
 get_setting(target_arch STRING "Target system architecture (fed to the compiler's -march=...).")
@@ -77,6 +80,7 @@ endfunction()
 prefix_project_paths(source_files)
 prefix_project_paths(source_files)
 prefix_project_paths(header_files)
 prefix_project_paths(header_files)
 prefix_project_paths(test_files)
 prefix_project_paths(test_files)
+prefix_project_paths(arduino_files)
 
 
 # Main library
 # Main library
 
 
@@ -163,3 +167,18 @@ else()
             WORKING_DIRECTORY "${PROJECT_BINARY_DIR}")
             WORKING_DIRECTORY "${PROJECT_BINARY_DIR}")
     add_custom_target("${tests_run_target}" ALL DEPENDS "${tests_run_file}")
     add_custom_target("${tests_run_target}" ALL DEPENDS "${tests_run_file}")
 endif()
 endif()
+
+# Generate Arduino package
+
+set(arduino_package_file "${PROJECT_BINARY_DIR}/hydrogen-crypto.zip")
+
+# Use the relative versions of the file path lists or else the full paths will
+# end up in the generated archive.
+add_custom_command(OUTPUT "${arduino_package_file}"
+        COMMAND cmake
+            ARGS -E tar cf "${arduino_package_file}" --format=zip
+                -- ${source_files} ${header_files} ${arduino_files}
+        WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
+
+add_custom_target("${PROJECT_NAME}-arduino-package"
+        DEPENDS "${arduino_package_file}")

+ 126 - 0
cmake/arduino-avr-toolchain.cmake

@@ -0,0 +1,126 @@
+# Cross-compilation file for the Arduino/AVR toolchain.
+
+# To use, pass -DCMAKE_TOOLCHAIN_FILE=cmake/arduino-avr-toolchain.cmake in your
+# CMake command line.
+
+cmake_minimum_required(VERSION 3.12)
+
+set(setting_prefix ARDUINO_AVR)
+function(get_setting setting_name setting_type setting_description)
+    string(TOUPPER "${setting_prefix}_${setting_name}" setting_external_name)
+    set("${setting_external_name}" "" CACHE "${setting_type}" "${setting_description}")
+    set("${setting_name}" "${${setting_external_name}}" PARENT_SCOPE)
+endfunction()
+
+# Target device setting
+
+get_setting(target_device STRING "Target Arduino device MCU identifier.")
+if(NOT target_device)
+    set(target_device atmega328p)
+endif()
+
+if("${target_device}" STREQUAL atmega328p)
+    set(hw_type ATMEGA328)
+else()
+    message(FATAL_ERROR "Unrecognized ${setting_prefix}_TARGET_DEVICE value ${target_device}")
+endif()
+
+# Find Arduino SDK home
+
+get_setting(sdk_dir PATH "Arduino SDK home directory.")
+
+# Try ARDUINO_SDK_PATH environment variable.
+if(NOT sdk_dir)
+    if(DEFINED ENV{ARDUINO_SDK_PATH})
+        set(sdk_dir "$ENV{ARDUINO_SDK_PATH}")
+    endif()
+endif()
+
+# Try some platform-specific guesses.
+if(NOT sdk_dir)
+    # Windows
+    if(WIN32)
+        list(APPEND arduino_home_dir_guesses
+                "C:/Program Files (x86)/Arduino"
+                "C:/Program Files/Arduino")
+    endif()
+
+    # macOS
+    if(APPLE)
+        list(APPEND arduino_home_dir_guesses
+                "/Applications/Arduino.app/Contents/Java")
+    endif()
+
+    # Linux/Unix
+    if(UNIX AND NOT APPLE)
+        list(APPEND arduino_home_dir_guesses
+                "/usr/share/arduino"
+                "/usr/local/share/arduino")
+    endif()
+
+    if(DEFINED arduino_home_dir_guesses)
+        foreach(arduino_home_dir_guess IN LISTS arduino_home_dir_guesses)
+            if(IS_DIRECTORY "${arduino_home_dir_guess}")
+                set(sdk_dir "${arduino_home_dir_guess}")
+                break()
+            endif()
+        endforeach()
+    endif()
+endif()
+
+if(NOT sdk_dir)
+    message(FATAL_ERROR
+            "Couldn't determine Arduino SDK home directory. "
+            "Try passing -D${setting_prefix}_SDK_DIR=... to the CMake command line, or "
+            "set the ARDUINO_SDK_PATH environment variable.")
+endif()
+
+# Locate toolchain programs
+
+set(arduino_tools_dir "${sdk_dir}/hardware/tools/avr/bin")
+set(program_prefix "${setting_prefix}_PROGRAM")
+function(find_in_toolchain program_name)
+    string(TOUPPER "${program_prefix}_${program_name}" program_external_name)
+    string(REPLACE "_" "-" program_file_name "${program_name}")
+
+    find_program("${program_external_name}" "${program_file_name}"
+            PATHS "${arduino_tools_dir}" NO_DEFAULT_PATH)
+
+    if("${${program_external_name}}" STREQUAL "${program_external_name}-NOTFOUND")
+        message(FATAL_ERROR
+                "Couldn't find program ${program_file_name} "
+                "in Arduino/AVR toolchain at ${arduino_tools_dir}")
+    else()
+        set("${program_name}" "${${program_external_name}}" PARENT_SCOPE)
+    endif()
+endfunction()
+
+find_in_toolchain(avr_gcc)
+find_in_toolchain(avr_gcc_ranlib)
+find_in_toolchain(avr_gcc_ar)
+
+# Configure CMake toolchain settings
+
+set(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_C_COMPILER "${avr_gcc}")
+set(CMAKE_ASM_COMPILER "${avr_gcc}")
+set(CMAKE_RANLIB "${avr_gcc_ranlib}")
+set(CMAKE_AR "${avr_gcc_ar}")
+
+SET(CMAKE_C_OUTPUT_EXTENSION .o)
+SET(CMAKE_ASM_OUTPUT_EXTENSION .o)
+
+# Add compile flags
+
+string(APPEND CMAKE_C_FLAGS
+        " -mmcu=${target_device} -Os -mcall-prologues -fno-exceptions"
+        " -ffunction-sections -fdata-sections -flto"
+        " -DHYDRO_TARGET_DEVICE_${hw_type}")
+
+# Add include directories
+
+include_directories(SYSTEM
+        "${sdk_dir}/hardware/arduino/avr/cores/arduino"
+        "${sdk_dir}/hardware/arduino/avr/variants/standard"
+        "${sdk_dir}/hardware/arduino/cores/arduino"
+        "${sdk_dir}/hardware/arduino/variants/standard")