From d5759423db996d4dbce45177fb970c498b6ac4a1 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Wed, 13 Jan 2021 16:30:35 +0100 Subject: [PATCH] fxsdk: helpers for CMake build systems --- fxsdk/cmake/FX9860G.cmake | 22 +++++++++++++ fxsdk/cmake/FXCG50.cmake | 22 +++++++++++++ fxsdk/cmake/FindGint.cmake | 57 ++++++++++++++++++++++++++++++++ fxsdk/cmake/Fxconv.cmake | 2 ++ fxsdk/cmake/GenerateG1A.cmake | 49 ++++++++++++++++++++++++++++ fxsdk/cmake/GenerateG3A.cmake | 61 +++++++++++++++++++++++++++++++++++ 6 files changed, 213 insertions(+) create mode 100644 fxsdk/cmake/FX9860G.cmake create mode 100644 fxsdk/cmake/FXCG50.cmake create mode 100644 fxsdk/cmake/FindGint.cmake create mode 100644 fxsdk/cmake/Fxconv.cmake create mode 100644 fxsdk/cmake/GenerateG1A.cmake create mode 100644 fxsdk/cmake/GenerateG3A.cmake diff --git a/fxsdk/cmake/FX9860G.cmake b/fxsdk/cmake/FX9860G.cmake new file mode 100644 index 0000000..085468c --- /dev/null +++ b/fxsdk/cmake/FX9860G.cmake @@ -0,0 +1,22 @@ +# fxSDK toolchain file for Casio graphing calculators +# Models: Almost every model of the fx-9750G and fx-9860G families +# Target triplet: sh-elf (custom sh3eb-elf supporting sh3 and sh4-nofpu) + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_VERSION 1) + +set(FXSDK_PLATFORM fx) +set(FXSDK_PLATFORM_LONG fx9860G) + +set(CMAKE_C_COMPILER sh-elf-gcc) +set(CMAKE_CXX_COMPILER sh-elf-g++) + +add_compile_options(-m3 -mb -ffreestanding -nostdlib) +add_link_options(-nostdlib) +link_libraries(-lgcc) +add_compile_definitions(TARGET_FX9860G) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/fxsdk/cmake/FXCG50.cmake b/fxsdk/cmake/FXCG50.cmake new file mode 100644 index 0000000..f22079b --- /dev/null +++ b/fxsdk/cmake/FXCG50.cmake @@ -0,0 +1,22 @@ +# fxSDK toolchain file for Casio graphing calculators +# Models: Prizm fx-CG 10, fx-CG 20, fx-CG 50, fx-CG 50 emulator +# Target triplet: sh-elf (custom sh3eb-elf supporting sh3 and sh4-nofpu) + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_VERSION 1) + +set(FXSDK_PLATFORM cg) +set(FXSDK_PLATFORM_LONG fxCG50) + +set(CMAKE_C_COMPILER sh-elf-gcc) +set(CMAKE_CXX_COMPILER sh-elf-g++) + +add_compile_options(-m4-nofpu -mb -ffreestanding -nostdlib) +add_link_options(-nostdlib) +link_libraries(-lgcc) +add_compile_definitions(TARGET_FXCG50) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/fxsdk/cmake/FindGint.cmake b/fxsdk/cmake/FindGint.cmake new file mode 100644 index 0000000..d555738 --- /dev/null +++ b/fxsdk/cmake/FindGint.cmake @@ -0,0 +1,57 @@ +# Determine platform Code +if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50) + set(PC cg) + set(INTF_DEFN FXCG50) + set(INTF_LINK "-T;fxcg50.ld") +elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G) + set(PC fx) + set(INTF_DEFN FX9860G) + set(INTF_LINK "-T;fx9860g.ld") +else() + message(FATAL_ERROR "gint: unknown fxSDK platform '${FXSDK_PLATFORM}'") +endif() + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-file-name=libgint-${PC}.a + OUTPUT_VARIABLE GINT_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE +) +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-file-name=include/gint/config.h + OUTPUT_VARIABLE GINT_CONFIG_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(GINT_CONFIG_PATH) + execute_process( + COMMAND sed -E "s/#define.*GINT_VERSION\\s+\"(\\S+)\"$/\\1/p; d" ${GINT_CONFIG_PATH} + OUTPUT_VARIABLE GINT_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif() + +if("${GINT_PATH}" STREQUAL "libgint-${PC}.a") + set(COMPILER_HAS_LIBRARY FALSE) +else() + set(COMPILER_HAS_LIBRARY TRUE) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Gint + REQUIRED_VARS COMPILER_HAS_LIBRARY + VERSION_VAR GINT_VERSION +) + +if(Gint_FOUND) + if(NOT TARGET Gint::Gint) + add_library(Gint::Gint UNKNOWN IMPORTED) + endif() + # No include directory or library path to specify, GCC handles that + set_target_properties(Gint::Gint PROPERTIES + IMPORTED_LOCATION "${GINT_PATH}" + INTERFACE_COMPILE_OPTIONS -fstrict-volatile-bitfields + INTERFACE_COMPILE_DEFINITIONS "${INTF_DEFN}" + INTERFACE_LINK_LIBRARIES -lgcc + INTERFACE_LINK_OPTIONS "${INTF_LINK}" + ) +endif() diff --git a/fxsdk/cmake/Fxconv.cmake b/fxsdk/cmake/Fxconv.cmake new file mode 100644 index 0000000..35335af --- /dev/null +++ b/fxsdk/cmake/Fxconv.cmake @@ -0,0 +1,2 @@ +set(CMAKE_FXCONV_COMPILE_OBJECT + "fxconv -o --toolchain=sh-elf --${FXSDK_PLATFORM}") diff --git a/fxsdk/cmake/GenerateG1A.cmake b/fxsdk/cmake/GenerateG1A.cmake new file mode 100644 index 0000000..7276bf3 --- /dev/null +++ b/fxsdk/cmake/GenerateG1A.cmake @@ -0,0 +1,49 @@ +function(generate_g1a) + cmake_parse_arguments(G1A "" "TARGET;OUTPUT;NAME;INTERNAL;VERSION;DATE;ICON" "" ${ARGN}) + + # Check arguments + + if(DEFINED G1A_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "generate_g1a: Unrecognized arguments ${G1A_UNPARSED_ARGUMENTS}") + endif() + + if(NOT DEFINED G1A_TARGET) + message(FATAL_ERROR "generate_g1a: TARGET argument is required") + endif() + + # Find output file name + + if(DEFINED G1A_OUTPUT) + get_filename_component(G1A_OUTPUT "${G1A_OUTPUT}" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + else() + set(G1A_OUTPUT "${G1A_TARGET}.g1a") + endif() + + # Compute the set of fxg1a arguments + + set(FXG1A_ARGS "") + + # Support empty names enen though they're not normally used in g1a files + if(DEFINED G1A_NAME OR "NAME" IN_LIST G1A_KEYWORDS_MISSING_VALUES) + list(APPEND FXG1A_ARGS "-n" "${G1A_NAME}") + endif() + + if(DEFINED G1A_ICON) + get_filename_component(G1A_ICON "${G1A_ICON}" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + list(APPEND FXG1A_ARGS "-i" "${G1A_ICON}") + endif() + + string(REPLACE "gcc" "objcopy" OBJCOPY "${CMAKE_C_COMPILER}") + + add_custom_command( + TARGET "${G1A_TARGET}" POST_BUILD + COMMAND "${OBJCOPY}" -O binary -R .bss -R .gint_bss "${G1A_TARGET}" "${G1A_TARGET}.bin" + COMMAND fxg1a "${G1A_TARGET}.bin" ${FXG1A_ARGS} -o "${G1A_OUTPUT}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) + if(DEFINED G1A_ICON) + set_target_properties("${G1A_TARGET}" PROPERTIES LINK_DEPENDS "${G1A_ICON}") + endif() +endfunction() diff --git a/fxsdk/cmake/GenerateG3A.cmake b/fxsdk/cmake/GenerateG3A.cmake new file mode 100644 index 0000000..5888f59 --- /dev/null +++ b/fxsdk/cmake/GenerateG3A.cmake @@ -0,0 +1,61 @@ +function(generate_g3a) + cmake_parse_arguments(G3A "" "TARGET;OUTPUT;NAME" "ICONS" ${ARGN}) + + # Check arguments + + if(DEFINED G3A_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "generate_g3a: Unrecognized arguments ${G3A_UNPARSED_ARGUMENTS}") + endif() + + if(NOT DEFINED G3A_TARGET) + message(FATAL_ERROR "generate_g3a: TARGET argument is required") + endif() + + list(LENGTH G3A_ICONS G3A_ICONS_LENGTH) + if(DEFINED G3A_ICONS AND NOT ("${G3A_ICONS_LENGTH}" EQUAL 2)) + message(ERROR "generate_g3a: ICONS expects exactly 2 files") + endif() + + # Find output file name + + if(DEFINED G3A_OUTPUT) + get_filename_component(G3A_OUTPUT "${G3A_OUTPUT}" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + else() + set(G3A_OUTPUT "${G3A_TARGET}.g3a") + endif() + + # Compute the set of mkg3a arguments + + set(MKG3A_ARGS "") + + # Empty names are commonly used to avoid having the file name printed over + # the icon, but using ARGN in cmake_parse_arguments() drops the empty string. + # Check in KEYWORDS_MISSING_VALUES as a complement. + if(DEFINED G3A_NAME OR "NAME" IN_LIST G3A_KEYWORDS_MISSING_VALUES) + list(APPEND MKG3A_ARGS "-n" "basic:${G3A_NAME}") + endif() + + if(DEFINED G3A_ICONS) + list(GET G3A_ICONS 0 G3A_ICON1) + list(GET G3A_ICONS 1 G3A_ICON2) + get_filename_component(G3A_ICON1 "${G3A_ICON1}" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + get_filename_component(G3A_ICON2 "${G3A_ICON2}" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + list(APPEND MKG3A_ARGS "-i" "uns:${G3A_ICON1}" "-i" "sel:${G3A_ICON2}") + endif() + + string(REPLACE "gcc" "objcopy" OBJCOPY "${CMAKE_C_COMPILER}") + + add_custom_command( + TARGET "${G3A_TARGET}" POST_BUILD + COMMAND "${OBJCOPY}" -O binary -R .bss -R .gint_bss "${G3A_TARGET}" "${G3A_TARGET}.bin" + COMMAND mkg3a "${G3A_TARGET}.bin" ${MKG3A_ARGS} "${G3A_OUTPUT}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) + if(DEFINED G3A_ICONS) + set_target_properties("${G3A_TARGET}" PROPERTIES + LINK_DEPENDS "${G3A_ICON1};${G3A_ICON2}") + endif() +endfunction()