message(STATUS "Using CMake version ${CMAKE_VERSION}") cmake_minimum_required(VERSION 3.10...${CMAKE_VERSION}) SET(InfiniTime_DIR "${CMAKE_SOURCE_DIR}/InfiniTime" CACHE PATH "Path to InfiniTime source path to use for simulator") if(NOT EXISTS ${InfiniTime_DIR}) message(FATAL_ERROR "Can't access folder '${InfiniTime_DIR}'. Try `git submodule update --init --recursive` to initialize the git submodule of InfiniTime") endif() if(NOT EXISTS ${InfiniTime_DIR}/src/libs/lvgl) message(FATAL_ERROR "Can't access folder '${InfiniTime_DIR}/src/libs/lvgl'. Try `git submodule update --init --recursive` to initialize the git submodule of lvgl inside InfiniTime") endif() # try to extract the PineTime project version file(READ "${InfiniTime_DIR}/CMakeLists.txt" main_cmake) string(REGEX MATCH "project\\(pinetime VERSION ([0-9]*\.[0-9]*\.[0-9]*)" _ ${main_cmake}) set(PROJECT_VERSION ${CMAKE_MATCH_1}) message(STATUS "InfiniTime PROJECT_VERSION extracted: ${PROJECT_VERSION}") project(InfiniSim VERSION ${PROJECT_VERSION} LANGUAGES C CXX) # https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html string(COMPARE EQUAL "${CMAKE_CXX_STANDARD}" "" no_cmake_cxx_standard_set) if(no_cmake_cxx_standard_set) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) message(STATUS "Using default C++ standard ${CMAKE_CXX_STANDARD}") else() message(STATUS "Using user specified C++ standard ${CMAKE_CXX_STANDARD}") endif() set(CMAKE_C_STANDARD 11)#C11 # copy lv_conf.h from InfiniTime project and do little modifications file(READ "${InfiniTime_DIR}/src/libs/lv_conf.h" lv_conf_main) # set '#define LV_TICK_CUSTOM 0' string(REGEX REPLACE "#define[ ]+LV_TICK_CUSTOM[ ]+1" "#define LV_TICK_CUSTOM 0" lv_conf_main "${lv_conf_main}") # allow more memory in debug mode for the simulator #define LV_MEM_SIZE (14U * 1024U) string(REGEX REPLACE "#define[ ]+LV_MEM_SIZE[ ]+\\([^\)]*\\)" "#ifdef NDEBUG #define LV_MEM_SIZE (14U * 1024U) #else // debug mode -> allow more memory #define LV_MEM_SIZE (28U * 1024U) #endif" lv_conf_main "${lv_conf_main}") # write to temporary file and overwrite file to use only if lv_conf changed to keep useless recompiles # at a minimum file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lv_conf_modified.h" "${lv_conf_main}") configure_file( "${CMAKE_CURRENT_BINARY_DIR}/lv_conf_modified.h" "${CMAKE_CURRENT_BINARY_DIR}/lv_conf.h" COPYONLY) file(GLOB_RECURSE INCLUDES "lv_drivers/*.h" "${InfiniTime_DIR}/src/libs/lvgl/src/*.h" "./*.h" ) file(GLOB_RECURSE SOURCES "lv_drivers/*.c" "${InfiniTime_DIR}/src/libs/lvgl/src/*.c" ) add_executable(infinisim main.cpp ${SOURCES} ${INCLUDES}) set(MONITOR_ZOOM 1 CACHE STRING "Scale simulator window by this factor") if(MONITOR_ZOOM MATCHES "^[0-9]\.?[0-9]*") message(STATUS "Using MONITOR_ZOOM=${MONITOR_ZOOM}") target_compile_definitions(infinisim PRIVATE MONITOR_ZOOM=${MONITOR_ZOOM}) else() message(FATAL_ERROR "variable MONITOR_ZOOM=${MONITOR_ZOOM} must be a positive number") endif() # include the generated lv_conf.h file before anything else target_include_directories(infinisim PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") # add simulator files target_sources(infinisim PUBLIC sim/displayapp/LittleVgl.h sim/displayapp/LittleVgl.cpp sim/displayapp/screens/Missing.h sim/displayapp/screens/Missing.cpp sim/components/battery/BatteryController.h sim/components/battery/BatteryController.cpp sim/components/ble/AlertNotificationService.h sim/components/ble/AlertNotificationService.cpp sim/components/ble/MusicService.h sim/components/ble/MusicService.cpp sim/components/ble/NavigationService.h sim/components/ble/NavigationService.cpp sim/components/ble/NimbleController.h sim/components/ble/NimbleController.cpp sim/components/ble/weather/WeatherService.h sim/components/ble/weather/WeatherService.cpp sim/components/brightness/BrightnessController.h sim/components/brightness/BrightnessController.cpp sim/components/firmwarevalidator/FirmwareValidator.h sim/components/firmwarevalidator/FirmwareValidator.cpp sim/components/heartrate/HeartRateController.h sim/components/heartrate/HeartRateController.cpp sim/components/motion/MotionController.h sim/components/motion/MotionController.cpp sim/components/motor/MotorController.h sim/components/motor/MotorController.cpp sim/drivers/Watchdog.h sim/drivers/Watchdog.cpp sim/drivers/Bma421.h sim/drivers/Bma421.cpp sim/drivers/Cst816s.h sim/drivers/Cst816s.cpp sim/drivers/Hrs3300.h sim/drivers/Hrs3300.cpp sim/drivers/SpiMaster.h sim/drivers/SpiMaster.cpp sim/drivers/TwiMaster.h sim/drivers/TwiMaster.cpp sim/drivers/SpiNorFlash.h sim/drivers/SpiNorFlash.cpp sim/heartratetask/HeartRateTask.h sim/heartratetask/HeartRateTask.cpp # FreeRTOS sim/FreeRTOS.h sim/FreeRTOS.cpp sim/task.h sim/task.cpp sim/timers.h sim/timers.cpp sim/queue.h sim/queue.cpp # src/FreeRTOS sim/portmacro_cmsis.h sim/portmacro_cmsis.cpp # nrf sim/libraries/log/nrf_log.h sim/libraries/delay/nrf_delay.h sim/libraries/delay/nrf_delay.cpp sim/nrfx/nrfx_log.h sim/nrfx/drivers/include/nrfx_twi.h sim/nrfx/hal/nrf_gpio.h sim/nrfx/hal/nrf_gpio.cpp sim/nrfx/hal/nrfx_gpiote.h # includes hal/nrf_gpio.h sim/nrfx/hal/nrf_rtc.h sim/nrfx/hal/nrf_rtc.cpp # nrf/components/libraries/timer sim/libraries/timer/app_timer.h sim/libraries/timer/app_timer.cpp sim/libraries/gpiote/app_gpiote.h # includes hal/nrf_gpio.h ) target_include_directories(infinisim PRIVATE "sim") target_include_directories(infinisim PRIVATE "sim/libraries/log") # for nrf_log.h target_include_directories(infinisim PRIVATE "sim/libraries/timer") # for app_timer.h target_include_directories(infinisim PRIVATE "sim/nrfx") # for nrfx_log.h and others target_include_directories(infinisim PRIVATE "sim/nrfx/hal") # for nrfx_log.h target_compile_definitions(infinisim PRIVATE LV_CONF_INCLUDE_SIMPLE) target_include_directories(infinisim PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") target_include_directories(infinisim PRIVATE "${InfiniTime_DIR}/src/libs") target_include_directories(infinisim PRIVATE "lv_drivers") # add dates library target_include_directories(infinisim SYSTEM PRIVATE "${InfiniTime_DIR}/src/libs/date/includes") # add Screens, fonts and icons with a globbing expression, # to enable easier CI test-runs for PRs adding new Screens/Fonts/Icons file(GLOB InfiniTime_SCREENS "${InfiniTime_DIR}/src/displayapp/screens/*.h" "${InfiniTime_DIR}/src/displayapp/screens/*.cpp" "${InfiniTime_DIR}/src/displayapp/screens/settings/*.h" "${InfiniTime_DIR}/src/displayapp/screens/settings/*.cpp" ) file(GLOB InfiniTime_FONTS "${InfiniTime_DIR}/src/displayapp/fonts/*.c" ) file(GLOB InfiniTime_ICONS "${InfiniTime_DIR}/src/displayapp/icons/*.c" ) file(GLOB InfiniTime_WIDGETS "${InfiniTime_DIR}/src/displayapp/widgets/*.cpp" "${InfiniTime_DIR}/src/displayapp/widgets/*.h" ) set(LITTLEFS_SRC ${InfiniTime_DIR}/src/libs/littlefs/lfs_util.h ${InfiniTime_DIR}/src/libs/littlefs/lfs.h ${InfiniTime_DIR}/src/libs/littlefs/lfs_util.c ${InfiniTime_DIR}/src/libs/littlefs/lfs.c ) target_sources(infinisim PUBLIC ${InfiniTime_SCREENS}) target_sources(infinisim PUBLIC ${InfiniTime_FONTS}) target_sources(infinisim PUBLIC ${InfiniTime_ICONS}) target_sources(infinisim PUBLIC ${InfiniTime_WIDGETS}) target_sources(infinisim PUBLIC ${LITTLEFS_SRC}) # add files directly from InfiniTime sources target_include_directories(infinisim PRIVATE "${InfiniTime_DIR}/src") target_include_directories(infinisim PRIVATE "${InfiniTime_DIR}/src/libs/littlefs") target_sources(infinisim PUBLIC ${InfiniTime_DIR}/src/BootloaderVersion.h ${InfiniTime_DIR}/src/BootloaderVersion.cpp ${InfiniTime_DIR}/src/displayapp/Colors.h ${InfiniTime_DIR}/src/displayapp/Colors.cpp ${InfiniTime_DIR}/src/displayapp/DisplayApp.h ${InfiniTime_DIR}/src/displayapp/DisplayApp.cpp ${InfiniTime_DIR}/src/displayapp/lv_pinetime_theme.h ${InfiniTime_DIR}/src/displayapp/lv_pinetime_theme.c ${InfiniTime_DIR}/src/displayapp/icons/bg_clock.c # used by WatchFaceAnalog.cpp ${InfiniTime_DIR}/src/buttonhandler/ButtonHandler.h ${InfiniTime_DIR}/src/buttonhandler/ButtonHandler.cpp ${InfiniTime_DIR}/src/components/alarm/AlarmController.h ${InfiniTime_DIR}/src/components/alarm/AlarmController.cpp ${InfiniTime_DIR}/src/components/ble/BleController.h ${InfiniTime_DIR}/src/components/ble/BleController.cpp ${InfiniTime_DIR}/src/components/datetime/DateTimeController.h ${InfiniTime_DIR}/src/components/datetime/DateTimeController.cpp ${InfiniTime_DIR}/src/components/settings/Settings.h ${InfiniTime_DIR}/src/components/settings/Settings.cpp ${InfiniTime_DIR}/src/components/ble/NotificationManager.h ${InfiniTime_DIR}/src/components/ble/NotificationManager.cpp ${InfiniTime_DIR}/src/components/fs/FS.h ${InfiniTime_DIR}/src/components/fs/FS.cpp ${InfiniTime_DIR}/src/components/timer/TimerController.h ${InfiniTime_DIR}/src/components/timer/TimerController.cpp ${InfiniTime_DIR}/src/drivers/PinMap.h ${InfiniTime_DIR}/src/drivers/Spi.h ${InfiniTime_DIR}/src/drivers/Spi.cpp ${InfiniTime_DIR}/src/drivers/St7789.h ${InfiniTime_DIR}/src/drivers/St7789.cpp ${InfiniTime_DIR}/src/touchhandler/TouchHandler.h ${InfiniTime_DIR}/src/touchhandler/TouchHandler.cpp ${InfiniTime_DIR}/src/systemtask/SystemTask.h ${InfiniTime_DIR}/src/systemtask/SystemTask.cpp ${InfiniTime_DIR}/src/systemtask/SystemMonitor.h ${InfiniTime_DIR}/src/systemtask/SystemMonitor.cpp ) # QCBOR add_library(QCBOR STATIC ${InfiniTime_DIR}/src/libs/QCBOR/src/ieee754.c ${InfiniTime_DIR}/src/libs/QCBOR/src/qcbor_decode.c ${InfiniTime_DIR}/src/libs/QCBOR/src/qcbor_encode.c ${InfiniTime_DIR}/src/libs/QCBOR/src/qcbor_err_to_str.c ${InfiniTime_DIR}/src/libs/QCBOR/src/UsefulBuf.c) target_include_directories(QCBOR SYSTEM PUBLIC ${InfiniTime_DIR}/src/libs/QCBOR/inc) # This is required with the current configuration target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_FLOAT_HW_USE) # These are for space-saving target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_PREFERRED_FLOAT) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_EXP_AND_MANTISSA) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS) #target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS) target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_UNCOMMON_TAGS) target_compile_definitions(QCBOR PUBLIC USEFULBUF_CONFIG_LITTLE_ENDIAN) set_target_properties(QCBOR PROPERTIES LINKER_LANGUAGE C) #target_compile_options(QCBOR PRIVATE # $<$,$>: ${COMMON_FLAGS} -O0 -g3> # $<$,$>: ${COMMON_FLAGS} -O3> # $<$: -MP -MD -x assembler-with-cpp> # ) target_link_libraries(infinisim PRIVATE QCBOR) if(EXISTS ${InfiniTime_DIR}/src/displayapp/fonts/CMakeLists.txt) # available since https://github.com/InfiniTimeOrg/InfiniTime/pull/1097 message(STATUS "add subdirectory ${InfiniTime_DIR}/src/displayapp/fonts for 'infinitime_fonts' target") add_subdirectory(${InfiniTime_DIR}/src/displayapp/fonts fonts) target_link_libraries(infinisim PRIVATE infinitime_fonts) endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Special case for SDL2 dependency, goal is to find a config that exports SDL2::SDL2 target # libsdl2-dev has a `sdl2-config.cmake` that doesn't export this, but vcpkg does.. find_package(SDL2 CONFIG QUIET) if(NOT TARGET SDL2::SDL2) find_package(SDL2 MODULE REQUIRED) endif() target_link_libraries(infinisim PRIVATE SDL2::SDL2) # Get the latest abbreviated commit hash of the working branch execute_process( COMMAND ${GIT_EXECUTABLE} log -1 --format=%h WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE PROJECT_GIT_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ) set(VERSION_EDIT_WARNING "// Do not edit this file, it is automatically generated by CMAKE!") configure_file("${InfiniTime_DIR}/src/Version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/Version.h") option(WITH_PNG "Compile with libpng support to dump current screen as png" ON) if(WITH_PNG) target_compile_definitions(infinisim PRIVATE WITH_PNG) add_subdirectory(libpng EXCLUDE_FROM_ALL) target_include_directories(infinisim PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") target_include_directories(infinisim PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/libpng") target_link_libraries(infinisim PRIVATE png_static) endif() install(TARGETS infinisim DESTINATION bin)