Add SQT5 that was missing in 2.2 (#5179)
[opentx.git] / radio / src / CMakeLists.txt
blobe34b07ec6a5f8c4efc0b2557884ba36e475bad55
1 include(CMakeForceCompiler)
2 include(Bitmaps)
4 set(PCB_TYPES X7 X7S X9D X9D+ X9E X10 X12S 9X 9XR 9X128 9XR128 9X2561 GRUVIN9X MEGA2560 SKY9X 9XRPRO AR9X)
5 set(GUI_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU NL)
6 set(TTS_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU)
8 set(PCB "X9D+" CACHE STRING "Radio type, one of: ${PCB_TYPES}")
9 set_property(CACHE PCB PROPERTY STRINGS ${PCB_TYPES})
10 set(TRANSLATIONS "EN" CACHE STRING "Radio language, one of: ${GUI_LANGUAGES}")
11 set_property(CACHE TRANSLATIONS PROPERTY STRINGS ${GUI_LANGUAGES})
12 set(SPLASH "DEFAULT" CACHE STRING "Splash (DEFAULT/OFF/FRSKY)")
13 set_property(CACHE SPLASH PROPERTY STRINGS DEFAULT OFF FRSKY)
14 set(PPM_UNIT "PERCENT_PREC1" CACHE STRING "PPM display unit (US/PERCENT_PREC1/PERCENT_PREC0)")
15 set_property(CACHE PPM_UNIT PROPERTY STRINGS US PERCENT_PREC1 PERCENT_PREC0)
16 set(DEFAULT_MODE "" CACHE STRING "Default sticks mode")
17 set(FONT "STD" CACHE STRING "Choose font : STD or SQT5")
18 set_property(CACHE FONT PROPERTY STRINGS SQT5)
20 option(HELI "Heli menu" ON)
21 option(FLIGHT_MODES "Flight Modes" ON)
22 option(CURVES "Curves" ON)
23 option(GVARS "Global variables" OFF)
24 option(GUI "GUI enabled" ON)
25 option(PPM_CENTER_ADJUSTABLE "PPM center adjustable" ON)
26 option(PPM_LIMITS_SYMETRICAL "PPM limits symetrical" OFF)
27 option(OVERRIDE_CHANNEL_FUNCTION "OverrideChannel function available" ON)
28 option(DANGEROUS_MODULE_FUNCTIONS "Dangerous module functions (RangeCheck / Bind / Module OFF, etc.) available" OFF)
29 option(FAI "Competition mode (no telemetry)" OFF)
30 option(AUTOSOURCE "Automatic source detection in menus" ON)
31 option(AUTOSWITCH "Automatic switch detection in menus" ON)
32 option(SEMIHOSTING "Enable debugger semihosting" OFF)
33 option(JITTER_MEASURE "Enable ADC jitter measurement" OFF)
34 option(WATCHDOG_DISABLED "Disable hardware Watchdog" OFF)
35 if(SDL_FOUND)
36   option(SIMU_AUDIO "Enable simulator audio." ON)
37 endif()
38 option(SIMU_DISKIO "Enable disk IO simulation in simulator. Simulator will use FatFs module and simulated IO layer that  uses \"./sdcard.image\" file as image of SD card. This file must contain whole SD card from first to last sector" OFF)
39 option(SIMU_LUA_COMPILER "Pre-compile and save Lua scripts in simulator." ON)
40 option(FAS_PROTOTYPE "Support of old FAS prototypes (different resistors)" OFF)
41 option(TEMPLATES "Model templates menu" OFF)
42 option(TRACE_SIMPGMSPACE "Turn on traces in simpgmspace.cpp" ON)
43 option(TRACE_LUA_INTERNALS "Turn on traces for Lua internals" OFF)
44 option(BINDING_OPTIONS "Allow advanced frsky bindings" OFF)
45 option(FRSKY_STICKS "Reverse sticks for FrSky sticks" OFF)
46 option(NANO "Use nano newlib and binalloc")
48 # since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags.
49 set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).")
50 set(FIRMWARE_C_FLAGS_DEBUG "-g" CACHE STRING "Additional flags for firmware target (Debug config) c compiler (note: CMAKE_C_FLAGS_DEBUG is ignored for firmware/bootloader).")
51 set(FIRMWARE_CXX_FLAGS "" CACHE STRING "Additional flags for firmware target c++ compiler (note: all CMAKE_CXX_FLAGS[_*] are ignored for firmware/bootloader).")
52 set(FIRMWARE_CXX_FLAGS_DEBUG "-g" CACHE STRING "Additional flags for firmware target (Debug config) c++ compiler (note: CMAKE_CXX_FLAGS_DEBUG is ignored for firmware/bootloader).")
54 # Python check
55 find_package("PythonInterp")
56 if(PYTHONINTERP_FOUND)
57   message(STATUS "Python found, version: ${PYTHON_VERSION_STRING}")
58 else()
59   message(WARNING "Python not found! Most firmware and simu flavors not buildable.")
60   set(LUA NO)
61 endif()
63 set(THIRDPARTY_DIR thirdparty)
64 set(LUA_DIR ${THIRDPARTY_DIR}/Lua/src)
65 set(COOS_DIR ${THIRDPARTY_DIR}/CoOS)
66 set(FATFS_DIR ${THIRDPARTY_DIR}/FatFs)
67 set(RADIO_BIN_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
69 configure_file(stamp.h.in stamp.h @ONLY)
71 add_subdirectory(translations)
72 add_subdirectory(bitmaps)
73 add_subdirectory(fonts)
75 set(EEPROM_VARIANT  0)
76 set(GVARS_VARIANT   1)
77 set(FRSKY_VARIANT   2)
78 set(3POS_VARIANT    4)
79 set(MAVLINK_VARIANT 8)
80 set(M2561_VARIANT   16384)
81 set(M128_VARIANT    32768)
83 set(FIRMWARE_DEPENDENCIES firmware_translations)
85 set(FATFS_SRC
86   ${FATFS_DIR}/ff.c
87   ${FATFS_DIR}/fattime.c
88   ${FATFS_DIR}/option/ccsbcs.c
91 if(PCB STREQUAL X12S OR PCB STREQUAL X10)
92   include(targets/horus/CMakeLists.txt)
93 elseif(PCB STREQUAL X9E OR PCB STREQUAL X9D+ OR PCB STREQUAL X9D OR PCB STREQUAL X7 OR PCB STREQUAL X7S)
94   include(targets/taranis/CMakeLists.txt)
95 elseif(PCB STREQUAL SKY9X OR PCB STREQUAL 9XRPRO OR PCB STREQUAL AR9X)
96   include(targets/sky9x/CMakeLists.txt)
97 elseif(PCB STREQUAL 9X OR PCB STREQUAL 9XR OR PCB STREQUAL 9X128 OR PCB STREQUAL 9XR128)
98   include(targets/9x/CMakeLists.txt)
99 elseif(PCB STREQUAL 9X2561)
100   set(ARCH AVR)
101   set(MCU atmega2561)
102   string(TOLOWER ${PCB} FLAVOUR)
103   set(EEPROM EEPROM_RLC)
104   set(SDCARD NO)
105   add_definitions(-DEEPROM_VARIANT=${M2561_VARIANT})
106   set(GUI_DIR 128x64)
107   set(TARGET_DIR 9x)
108   set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps)
109   add_definitions(-DPCBSTD -DPCB${PCB} -DCPUM2561)
110   set(TARGET_SRC ${TARGET_SRC} board.cpp)
111   set(GUI_SRC
112     ${GUI_SRC}
113     model_inputs_mixes.cpp
114     radio_diagkeys.cpp
115     radio_diaganas.cpp)
116   if(SP22)
117     add_definitions(-DSP22)
118   endif()
119   if(PWM_BACKLIGHT)
120     add_definitions(-DPWM_BACKLIGHT)
121   endif()
122   set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} lcd_driver.cpp)
123 elseif(PCB STREQUAL GRUVIN9X)
124   include(targets/gruvin9x/CMakeLists.txt)
125 elseif(PCB STREQUAL MEGA2560)
126   include(targets/mega2560/CMakeLists.txt)
127 else()
128   message(FATAL_ERROR "Unknown PCB '${PCB}'")
129 endif()
131 if(NOT PCB STREQUAL 9XR AND NOT PCB STREQUAL 9XRPRO)
132   option(DBLKEYS "Double Keys" ON)
133   if(DBLKEYS)
134     add_definitions(-DDBLKEYS)
135   endif()
136 endif()
138 if(CPU_TYPE STREQUAL STM32F4)
139   include(targets/common/arm/stm32/f4/CMakeLists.txt)
140 endif()
142 if(CPU_TYPE STREQUAL STM32F2)
143   include(targets/common/arm/stm32/f2/CMakeLists.txt)
144 endif()
146 if(CPU_FAMILY STREQUAL STM32)
147   include(targets/common/arm/stm32/CMakeLists.txt)
148 endif()
150 if(ARCH STREQUAL ARM)
151   include(targets/common/arm/CMakeLists.txt)
152 else()
153   include(targets/common/avr/CMakeLists.txt)
154 endif()
156 include_directories(targets/${TARGET_DIR} ${THIRDPARTY_DIR})
158 foreach(LANGUAGE ${GUI_LANGUAGES})
159   if(TRANSLATIONS STREQUAL ${LANGUAGE})
160     add_definitions(-DTRANSLATIONS_${LANGUAGE} -DTRANSLATIONS="${LANGUAGE}")
161   endif()
162 endforeach()
164 set(SRC ${SRC} debug.cpp)
166 if(${EEPROM} STREQUAL SDCARD)
167   set(SRC ${SRC} storage/storage_common.cpp storage/sdcard_raw.cpp)
168 elseif(${EEPROM} STREQUAL EEPROM_RLC)
169   set(SRC ${SRC} storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_rlc.cpp)
170   add_definitions(-DEEPROM -DEEPROM_RLC)
171 else()
172   set(SRC ${SRC} storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_raw.cpp)
173   add_definitions(-DEEPROM -DEEPROM_RAW)
174 endif()
176 if(ARCH STREQUAL ARM AND NOT PCB STREQUAL X12S AND NOT PCB STREQUAL X10 AND NOT PCB STREQUAL FLAMENCO)
177   set(SRC ${SRC} storage/eeprom_conversions.cpp)
178 endif()
180 add_definitions(-DFLAVOUR="${FLAVOUR}")
182 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
183 include_directories(${CMAKE_CURRENT_BINARY_DIR})
184 include_directories(${CMAKE_CURRENT_BINARY_DIR}/bitmaps/${GUI_DIR})
186 add_subdirectory(lua)
187 include(gui/CMakeLists.txt)
189 if(RAMBACKUP)
190   add_definitions(-DRAMBACKUP)
191   set(SRC ${SRC} storage/rambackup.cpp storage/rlc.cpp)
192 endif()
194 if(TEMPLATES)
195   add_definitions(-DTEMPLATES)
196   set(SRC ${SRC} templates.cpp)
197   set(GUI_SRC ${GUI_SRC} model_templates.cpp)
198 endif()
200 if(NOT LUA STREQUAL NO)
201   add_definitions(-DLUA)
202   if(LUA_COMPILER)
203     add_definitions(-DLUA_COMPILER)
204   endif()
205   if(NOT "${LUA_SCRIPT_LOAD_MODE}" STREQUAL "")
206     add_definitions(-DLUA_SCRIPT_LOAD_MODE="${LUA_SCRIPT_LOAD_MODE}")
207   endif()
208   include_directories(${LUA_DIR})
209   set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} ${LUA_EXPORT})
210   if(LUA STREQUAL YES)
211     add_definitions(-DLUA_MODEL_SCRIPTS)
212     set(GUI_SRC ${GUI_SRC} model_custom_scripts.cpp)
213   endif()
214   set(SRC ${SRC} lua/interface.cpp lua/api_general.cpp lua/api_lcd.cpp lua/api_model.cpp)
215   if(PCB STREQUAL X12S OR PCB STREQUAL X10)
216     set(SRC ${SRC} lua/widgets.cpp)
217   endif()
218   set(LUA_SRC lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c
219     lstate.c lstring.c ltable.c lrotable.c ltm.c lundump.c lvm.c lzio.c linit.c
220     lbaselib.c lmathlib.c lbitlib.c loadlib.c lauxlib.c ltablib.c lcorolib.c liolib.c lstrlib.c
221     )
222   foreach(FILE ${LUA_SRC})
223     set(SRC ${SRC} ${LUA_DIR}/${FILE})
224   endforeach()
225   if(MSVC)
226     # silence lots of warnings regarding "insecure" use of functions (sprintf, strcpy, etc) from Lua code
227     set(WARNING_FLAGS "${WARNING_FLAGS} /D_CRT_SECURE_NO_WARNINGS")
228   endif()
229 endif()
231 if(HELI)
232   add_definitions(-DHELI)
233 endif()
235 if(FLIGHT_MODES)
236   add_definitions(-DFLIGHT_MODES)
237   set(GUI_SRC ${GUI_SRC} model_flightmodes.cpp)
238 endif()
240 if(CURVES)
241   add_definitions(-DCURVES)
242   set(SRC ${SRC} curves.cpp)
243 endif()
245 if(GVARS)
246   add_definitions(-DGVARS)
247   set(SRC ${SRC} gvars.cpp)
248   math(EXPR EEPROM_VARIANT ${EEPROM_VARIANT}+${GVARS_VARIANT})
249 endif()
251 if(FAI STREQUAL YES)
252   add_definitions(-DFAI)
253 elseif(FAI STREQUAL CHOICE)
254   add_definitions(-DFAI_CHOICE)
255 endif()
257 if(FAS_PROTOTYPE)
258   add_definitions(-DFAS_PROTOTYPE)
259 endif()
261 if(AUTOSOURCE)
262   add_definitions(-DAUTOSOURCE)
263 endif()
265 if(AUTOSWITCH)
266   add_definitions(-DAUTOSWITCH)
267 endif()
269 if(JITTER_MEASURE)
270   add_definitions(-DJITTER_MEASURE)
271 endif()
273 if(WATCHDOG_DISABLED)
274   add_definitions(-DWATCHDOG_DISABLED)
275 endif()
277 if(SIMU_AUDIO)
278   add_definitions(-DSIMU_AUDIO)
279 endif()
281 if(SDCARD)
282   add_definitions(-DSDCARD)
283   include_directories(${FATFS_DIR} ${FATFS_DIR}/option)
284   set(SRC ${SRC} sdcard.cpp rtc.cpp logs.cpp)
285   set(FIRMWARE_SRC ${FIRMWARE_SRC} ${FATFS_SRC})
286 endif()
288 if(SHUTDOWN_CONFIRMATION)
289   add_definitions(-DSHUTDOWN_CONFIRMATION)
290 endif()
292 if(PPM_UNIT STREQUAL US)
293   add_definitions(-DPPM_UNIT_US)
294 elseif(PPM_UNIT STREQUAL PERCENT_PREC1)
295   add_definitions(-DPPM_UNIT_PERCENT_PREC1)
296 else()
297   add_definitions(-DPPM_UNIT_PERCENT_PREC0)
298 endif()
300 if(PPM_CENTER_ADJUSTABLE)
301   add_definitions(-DPPM_CENTER_ADJUSTABLE)
302 endif()
304 if(PPM_LIMITS_SYMETRICAL)
305   add_definitions(-DPPM_LIMITS_SYMETRICAL)
306 endif()
308 if(OVERRIDE_CHANNEL_FUNCTION)
309   add_definitions(-DOVERRIDE_CHANNEL_FUNCTION)
310 endif()
312 if(DANGEROUS_MODULE_FUNCTIONS)
313   add_definitions(-DDANGEROUS_MODULE_FUNCTIONS)
314 endif()
316 if(SPLASH STREQUAL FRSKY)
317   add_definitions(-DSPLASH -DSPLASH_FRSKY)
318 elseif(NOT SPLASH STREQUAL OFF)
319   add_definitions(-DSPLASH)
320 endif()
322 if(NOT DEFAULT_MODE STREQUAL "")
323   add_definitions(-DDEFAULT_MODE=${DEFAULT_MODE})
324 endif()
326 if(TRACE_SIMPGMSPACE)
327   add_definitions(-DTRACE_SIMPGMSPACE)
328 endif()
330 if(TRACE_LUA_INTERNALS)
331   add_definitions(-DTRACE_LUA_INTERNALS_ENABLED)
332 endif()
334 if(BINDING_OPTIONS)
335   add_definitions(-DBINDING_OPTIONS)
336 endif()
338 if(FRSKY_STICKS)
339   add_definitions(-DFRSKY_STICKS)
340 endif()
342 if(NOT FONT STREQUAL "")
343   add_definitions(-DFONT=${DEFAULT_MODE})
344 endif()
346 if(EEPROM_VARIANT_NEEDED)
347   add_definitions(-DEEPROM_VARIANT=${EEPROM_VARIANT})
348 endif()
350 set(SRC
351   ${SRC}
352   opentx.cpp
353   functions.cpp
354   strhelpers.cpp
355   switches.cpp
356   mixer.cpp
357   stamp.cpp
358   timers.cpp
359   trainer_input.cpp
360   )
362 if(GUI)
363   add_definitions(-DGUI)
364   set(SRC
365     ${SRC}
366     keys.cpp
367     maths.cpp
368     translations.cpp
369     gui/gui_common.cpp
370     )
371   foreach(FILE ${GUI_SRC})
372     set(SRC ${SRC} gui/${GUI_DIR}/${FILE})
373   endforeach()
374   if(ARCH STREQUAL ARM)
375     set(SRC
376       ${SRC}
377       gui/gui_common_arm.cpp
378       )
379   endif()
380 endif()
382 foreach(FILE ${TARGET_SRC})
383   set(SRC targets/${TARGET_DIR}/${FILE} ${SRC})
384 endforeach()
386 foreach(FILE ${FIRMWARE_TARGET_SRC})
387   set(FIRMWARE_SRC ${FIRMWARE_SRC} targets/${TARGET_DIR}/${FILE})
388 endforeach()
390 foreach(FILE ${PULSES_SRC})
391   set(SRC ${SRC} pulses/${FILE})
392 endforeach()
394 add_definitions(-DCORRECT_NEGATIVE_SHIFTS)
396 if(NOT MSVC)
397   set(WARNING_FLAGS "${WARNING_FLAGS} -Wall -Wno-strict-aliasing -Wformat -Wreturn-type -Wunused -Wuninitialized -Wunknown-pragmas -Wno-switch -Wtype-limits")
398   if(WARNINGS_AS_ERRORS)
399     set(WARNING_FLAGS "${WARNING_FLAGS} -Werror")
400   endif(WARNINGS_AS_ERRORS)
401 else()
402   add_definitions(-DHAVE_STRUCT_TIMESPEC)  # this is for pthread.h
403   if(WARNINGS_AS_ERRORS)
404     set(WARNING_FLAGS "${WARNING_FLAGS} /WX")
405   endif(WARNINGS_AS_ERRORS)
406 endif()
408 add_subdirectory(targets/simu)
409 if(NOT MSVC)
410   add_subdirectory(tests)
411 endif()
413 set(SRC ${SRC} ${FIRMWARE_SRC})
416 ##### firmware target #####
418 option(FIRMWARE_TARGET "Configure Firmware target (can be turned of for compiling Companion only)" ON)
419 if(NOT FIRMWARE_TARGET)
420   message(STATUS "firmware target disabled")
421   return()
422 endif()
424 set(CMAKE_EXECUTABLE_SUFFIX ".elf")
425 # trick to remove the -rdynamic and --out-implib issues
426 set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
427 set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
428 # similar for -mmacosx-version-min="
429 set(CMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG "")
430 set(CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG "")
431 # reset some CMake default flags which assume optimization levels/etc
432 set(CMAKE_C_FLAGS "${FIRMWARE_C_FLAGS}")
433 set(CMAKE_C_FLAGS_DEBUG "${FIRMWARE_C_FLAGS_DEBUG}")
434 set(CMAKE_C_FLAGS_RELEASE "")
435 set(CMAKE_C_FLAGS_MINSIZEREL "")
436 set(CMAKE_C_FLAGS_RELWITHDEBINFO "")
437 set(CMAKE_CXX_FLAGS "${FIRMWARE_CXX_FLAGS}")
438 set(CMAKE_CXX_FLAGS_DEBUG "${FIRMWARE_CXX_FLAGS_DEBUG}")
439 set(CMAKE_CXX_FLAGS_RELEASE "")
440 set(CMAKE_CXX_FLAGS_MINSIZEREL "")
441 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
442 # customize linker command
443 set(CMAKE_EXE_LINKER_FLAGS "")
444 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET>")
445 set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET>")
447 use_cxx11()  # ensure gnu++11 in CXX_FLAGS with CMake < 3.1
449 find_program(BASH bash HINTS "c:/cygwin/bin/" "c:/msys/bin/" DOC "bash shell for firmware size report (eg. c:/cygwin/bin/bash.exe on Windows).")
451 if(NOT MSVC)
452   set(OPT s)
454   if(ARCH STREQUAL ARM)
456     enable_language(ASM)
457     set(CMAKE_C_COMPILER arm-none-eabi-gcc)
458     set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
459     set(CMAKE_ASM_COMPILER arm-none-eabi-as)
461     set(CMAKE_SYSTEM_NAME Generic)
462     set(CMAKE_SYSTEM_VERSION 1)
463     set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -o <OBJECT> <SOURCE>")
465     set(COMMON_FLAGS "-mcpu=${MCU} -mthumb -fomit-frame-pointer -fverbose-asm -Wa,-ahlms=firmware.lst -O${OPT} -gdwarf-2 -DHSE_VALUE=${HSE_VALUE} -fno-exceptions -fdata-sections -ffunction-sections ${WARNING_FLAGS}")
466     set(COMMON_FLAGS "${COMMON_FLAGS} ${FPU_FLAGS}")
468     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS} -Wimplicit")
469     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}")
471     # these are in addition to CMAKE_CXX_FLAGS
472     set(CMAKE_EXE_LINKER_FLAGS "-lm -T${RADIO_SRC_DIRECTORY}/${LINKER_SCRIPT} -Wl,-Map=firmware.map,--cref,--no-warn-mismatch,--gc-sections")
473     if(SEMIHOSTING)
474       add_definitions(-DSEMIHOSTING)
475       set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --specs=rdimon.specs")
476     endif()
477     # Use newlib nano, which saves a few kilobytes.
478     if(NOT NANO STREQUAL NO)
479       set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --specs=nano.specs")
480       if(NOT LUA STREQUAL NO)
481         # Lua needs %g and %f
482         set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u _printf_float -u _scanf_float")
483       endif()
484       # Nano's malloc does work well with lua, use our own
485       add_definitions(-DUSE_BIN_ALLOCATOR)
486       set(SRC ${SRC} bin_allocator.cpp)
487     endif()
489     
490     if(PCB STREQUAL X9D OR PCB STREQUAL X9D+ OR PCB STREQUAL X9E OR PCB STREQUAL X7 OR PCB STREQUAL X7S)
491       add_subdirectory(targets/${TARGET_DIR}/bootloader)
492       include_directories(${CMAKE_CURRENT_BINARY_DIR}/targets/${TARGET_DIR}/bootloader)
493       set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} bootloader)
494     elseif(OPENRC_BOOTLOADER)
495       # We fetch Mike's bootloader as it is not included inside OpenTX
496       message(STATUS "Downloading Mike's bootloader: https://github.com/MikeBland/OpenRcBootloader/releases/download/V1.9/${OPENRC_BOOTLOADER}")
497       file(DOWNLOAD https://github.com/MikeBland/OpenRcBootloader/releases/download/V1.9/${OPENRC_BOOTLOADER} ${CMAKE_CURRENT_BINARY_DIR}/bootloader.lbm STATUS status)
498       list(GET status 0 error_code)
499       if(error_code)
500         list(GET status 1 error_message)
501         message(FATAL_ERROR "Download failed: ${error_message}")
502       endif()
503     endif()
505     add_executable(firmware ${SRC} ${FIRMWARE_HEADERS})
506     link_libraries(firmware -lstdc++)
507     add_dependencies(firmware ${FIRMWARE_DEPENDENCIES})
509     add_custom_command(
510       TARGET firmware POST_BUILD
511       COMMAND arm-none-eabi-objcopy -O binary firmware.elf firmware.bin
512       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
513     )
515     find_program(GAWK gawk HINTS "c:/cygwin/bin/" "c:/msys/bin/" DOC "gawk for firmware size report.")  # OS X might only have "awk"
516     if (BASH AND GAWK)
517       add_custom_target(firmware-size
518         COMMAND ${BASH} -kc '${RADIO_DIRECTORY}/util/elf-size-report.sh --mcu=${CPU_TYPE_FULL} ${SIZE_TARGET_MEM_DEFINE} firmware.elf'
519         DEPENDS firmware
520         WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
521         )
522     else()
523       add_custom_target(firmware-size
524         COMMAND arm-none-eabi-size -A firmware.elf
525         DEPENDS firmware
526         WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
527         )
528     endif()
530   else()  # AVR
532     set(CMAKE_C_COMPILER avr-gcc)
533     set(CMAKE_CXX_COMPILER avr-gcc)
535     set(COMMON_FLAGS "-mmcu=${MCU} -DF_CPU=16000000UL -O${OPT} -gdwarf-2 -fno-exceptions -flto -fwhole-program -fno-inline-small-functions -mstrict-X ${WARNING_FLAGS}")
536     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS}")
537     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}")
538     set(CMAKE_EXE_LINKER_FLAGS "-Wno-uninitialized")  # bogus "uninitialized" warnings from ld
540     include_directories(storage gui/${GUI_DIR})
542     set(ALLSRC ${PROJECT_BINARY_DIR}/allsrc.cpp)
543     if (BASH AND NOT WIN32)
544       add_custom_command(
545         OUTPUT ${ALLSRC}
546         COMMAND ${BASH} -kc 'rm -f ${ALLSRC}\; for f in ${SRC}\; do echo "\\# 1 \\\"$$f\\\"" >> ${ALLSRC}\; cat "$$f" >> ${ALLSRC}\; done'
547         WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY}
548         DEPENDS ${SRC}
549         )
550     elseif(WIN32)
551       string(REPLACE "/" "\\" SRC_WIN "${SRC}")
552       string(REPLACE "/" "\\" ALLSRC_WIN "${ALLSRC}")
553       set(ALLSRC_BAT
554           "setlocal EnableDelayedExpansion"
555           "del \"${ALLSRC_WIN}\""
556           "for %%f in (${SRC_WIN}) do ("
557             "set p=\"%%f\""
558             "set p=!p:^\\=/! \necho \# 1 !p! >> \"${ALLSRC_WIN}\""
559             "type %%f >> \"${ALLSRC_WIN}\""
560           ")\n"
561         )
562       string(REPLACE ";" "\n" ALLSRC_BAT "${ALLSRC_BAT}")
563       file(WRITE "${ALLSRC}.bat" "${ALLSRC_BAT}")
564       add_custom_command(
565         OUTPUT ${ALLSRC}
566         COMMAND "${ALLSRC}.bat"
567         WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY}
568         DEPENDS ${SRC}
569         )
570     else()
571       set(ALLSRC ${SRC})
572     endif()
573     add_executable(firmware ${ALLSRC})
575     add_dependencies(firmware ${FIRMWARE_DEPENDENCIES})
577     add_custom_command(
578       TARGET firmware POST_BUILD
579       COMMAND avr-objcopy -O ihex -R .eeprom firmware.elf firmware.hex
580       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
581       )
583     add_custom_target(firmware.lss
584       COMMAND avr-objdump -h -S firmware.elf > firmware.lss
585       DEPENDS firmware
586       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
587       )
589     add_custom_target(firmware-size
590       COMMAND avr-size --format=avr --mcu=${MCU} firmware.elf
591       DEPENDS firmware
592       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
593       )
595   endif()  # ARM or AVR
597   if(CPU_FAMILY STREQUAL STM32)
598     add_custom_target(flash
599       COMMAND dfu-util --alt 0 --dfuse-address 0x08000000:leave -d 0483:df11 -D firmware.bin
600       DEPENDS firmware
601       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
602     )
604     add_custom_target(jtag-flash
605       COMMAND st-flash --reset write firmware.bin 0x8000000
606       DEPENDS firmware
607       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
608       )
609   else()
610     add_custom_target(flash
611       COMMAND avrdude -c usbasp -p ${AVRDUDE_MCU} -U flash:w:firmware.hex:i
612       DEPENDS firmware
613       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
614       )
615   endif()
617   PrintTargetReport("firmware")
619 endif(NOT MSVC)