diff --git a/.travis.yml b/.travis.yml index 3e9230aac..7f98d25d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,13 +15,11 @@ before_install: - sudo apt-get update -qq install: - - sudo apt-get --yes --force-yes install qtbase5-dev qtmultimedia5-dev qttools5-dev qttools5-dev-tools python3-pyqt5 curl gcc-arm-none-eabi libfox-1.6-dev libgtest-dev - - wget --quiet http://firmware.ardupilot.org/Tools/Travis/gcc-avr_1%253a4.8-2.1_amd64.deb - - wget --quiet http://firmware.ardupilot.org/Tools/Travis/libmpfr4_3.1.2-1_amd64.deb - - wget --quiet http://firmware.ardupilot.org/Tools/Travis/avr-libc_1%253a1.8.0-4.1_all.deb - - wget --quiet http://firmware.ardupilot.org/Tools/Travis/binutils-avr_2.23.1-2.1_amd64.deb - - wget --quiet http://firmware.ardupilot.org/Tools/Travis/libmpc3_1.0.1-1ubuntu1_amd64.deb - - sudo dpkg --install gcc-avr_1%3a4.8-2.1_amd64.deb avr-libc_1%3a1.8.0-4.1_all.deb libmpfr4_3.1.2-1_amd64.deb binutils-avr_2.23.1-2.1_amd64.deb libmpc3_1.0.1-1ubuntu1_amd64.deb + - sudo apt-get --yes --force-yes install qtbase5-dev qtmultimedia5-dev qttools5-dev qttools5-dev-tools python3-pyqt5 curl gcc-arm-none-eabi libmpfr4 libmpc3 libfox-1.6-dev libgtest-dev + - wget --quiet https://launchpad.net/ubuntu/+source/gcc-avr/1:4.9.2+Atmel3.5.0-1/+build/8403710/+files/gcc-avr_4.9.2+Atmel3.5.0-1_amd64.deb + - wget --quiet https://launchpad.net/ubuntu/+source/avr-libc/1:1.8.0+Atmel3.5.0-1/+build/8435473/+files/avr-libc_1.8.0+Atmel3.5.0-1_all.deb + - wget --quiet https://launchpad.net/ubuntu/+source/binutils-avr/2.25+Atmel3.5.0-2/+build/8435474/+files/binutils-avr_2.25+Atmel3.5.0-2_amd64.deb + - sudo dpkg --install gcc-avr_4.9.2+Atmel3.5.0-1_amd64.deb avr-libc_1.8.0+Atmel3.5.0-1_all.deb binutils-avr_2.25+Atmel3.5.0-2_amd64.deb script: - ./tools/commit-tests.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 865d38e5a..9edde34e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,9 @@ endif() if(POLICY CMP0043) cmake_policy(SET CMP0043 NEW) endif() +if(POLICY CMP0054) + cmake_policy(SET CMP0054 NEW) +endif() set(CMAKE_COLOR_MAKEFILE ON) @@ -28,11 +31,15 @@ set(CMAKE_CXX_STANDARD 11) set(RADIO_DIRECTORY ${PROJECT_SOURCE_DIR}/radio) set(RADIO_SRC_DIRECTORY ${RADIO_DIRECTORY}/src) set(COMPANION_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src) +set(SIMU_SRC_DIRECTORY ${COMPANION_SRC_DIRECTORY}/simulation) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) +# options shared by all targets +option(VERBOSE_CMAKELISTS "Show extra information while processing CMakeLists.txt files." OFF) +option(WARNINGS_AS_ERRORS "Treat any compiler warning as an error (adds -Werror flag)." OFF) if(WIN32) set(WIN_EXTRA_LIBS_PATH "C:/Programs" CACHE PATH "Base path to extra libs/headers on Windows (SDL, dirent, pthreads, msinttypes folders should be in here).") @@ -81,8 +88,19 @@ if(WIN32) if(MSVC) set(WIN_PTHREAD_BASE_PATH "${WIN_EXTRA_LIBS_PATH}/pthreads/Pre-built.2") list(APPEND WIN_INCLUDE_DIRS "${WIN_PTHREAD_BASE_PATH}/include" "${WIN_EXTRA_LIBS_PATH}/msinttypes") - list(APPEND WIN_LINK_LIBRARIES "${WIN_PTHREAD_BASE_PATH}/lib/pthreadVC2.lib") - endif(MSVC) + find_file(WIN_PTHREAD_LIB pthreadVC2.lib PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib NO_DEFAULT_PATH) + find_file(WIN_PTHREAD_DLL pthreadVC2.dll PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib dll/x86 dll NO_DEFAULT_PATH) + if(WIN_PTHREAD_LIB) + list(APPEND WIN_LINK_LIBRARIES "${WIN_PTHREAD_LIB}") + else() + message(SEND_ERROR "pthreadVC2.lib not found!") + endif() + else() + set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES OFF) + set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES OFF) + set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES OFF) + set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES OFF) + endif() endif() include(Macros) diff --git a/cmake/FindLupdate.cmake b/cmake/FindLupdate.cmake index 990b52eaf..0caf0ba30 100644 --- a/cmake/FindLupdate.cmake +++ b/cmake/FindLupdate.cmake @@ -9,8 +9,6 @@ FIND_PROGRAM( LUPDATE_EXECUTABLE lupdate lupdate-qt4 ) -MESSAGE( STATUS ${LUPDATE_EXECUTABLE} ) - # if the program is found then we have it IF( LUPDATE_EXECUTABLE ) SET( LUPDATE_FOUND "YES" ) diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake index 76f5cc874..50c301455 100644 --- a/cmake/Macros.cmake +++ b/cmake/Macros.cmake @@ -37,3 +37,35 @@ macro(git_id RESULT) set(${RESULT} 0) endif(WIN32) endmacro(git_id) + +macro(use_cxx11) + if (CMAKE_VERSION VERSION_LESS "3.1" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set (CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}") + endif () +endmacro(use_cxx11) + +macro(PrintTargetReport targetName) + if(CMAKE_CXX_COMPILER MATCHES "/cl\\.exe$") + set(cpp_version ${MSVC_VERSION}) + else() + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE cpp_version) + endif() + if(cpp_version) + string(STRIP "v${cpp_version}" cpp_version) + else() + set(cpp_version "WARNING: COMPILER NOT FOUND!") + endif() + message("TARGET ${targetName}: cpp compiler ${CMAKE_CXX_COMPILER} ${cpp_version}") + + if(VERBOSE_CMAKELISTS) + get_directory_property(DirOpts COMPILE_OPTIONS) + get_directory_property(DirDefs COMPILE_DEFINITIONS) + string(REPLACE ";" " " DirOpts "${DirOpts}") + string(REPLACE ";" "; " DirDefs "${DirDefs}") + string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type) + message("\twith cpp flags: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${build_type}} ${DirOpts}") + message("\twith link flags: ${CMAKE_EXE_LINKER_FLAGS}") + message("\twith defs: ${DirDefs}") + message("--------------") + endif() +endmacro(PrintTargetReport) diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index bdecaf96d..aad4a6934 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -53,41 +53,39 @@ else() remove_definitions(-DSIMU_AUDIO) endif() -find_package(Lupdate) -if(LUPDATE_FOUND) - message("Qt lupdate: " ${LUPDATE_EXECUTABLE}) -else() - message("Qt lupdate not found, 'translations' target will not be availabe.") -endif() - add_definitions(-DSIMU) add_definitions(-DQXT_STATIC) -if (NOT MSVC AND ${CMAKE_VERSION} VERSION_LESS 3.1.0}) - message("companion: adding -std=gnu++11") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") +if(NOT MSVC) + set(WARNING_FLAGS "${WARNING_FLAGS} -Wall") + if(WARNINGS_AS_ERRORS) + set(WARNING_FLAGS "${WARNING_FLAGS} -Werror") + endif() +else() + # silence lots of warnings regarding "insecure" use of functions (sprintf, strcpy, etc) + set(WARNING_FLAGS "${WARNING_FLAGS} /D_CRT_SECURE_NO_WARNINGS") + if(WARNINGS_AS_ERRORS) + set(WARNING_FLAGS "${WARNING_FLAGS} /WX") + endif() endif() if(WIN32) include_directories(SYSTEM ${WIN_INCLUDE_DIRS}) if(MSVC) - set(CMAKE_CXX_FLAGS "/EHsc /LD /MP") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /LD /MP") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,5.01") - message("companion: using MSVC with ${CMAKE_CXX_FLAGS}") elseif(MINGW) # struct packing breaks on MinGW w/out -mno-ms-bitfields: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 & http://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields -mwindows") - message("companion: using MinGW with ${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields") endif() else() set(PTHREAD_LIBRARY pthread) - add_definitions(-Wall) link_directories(/usr/local/lib) endif() -set(RADIO_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/radio/src) -set(SIMU_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src/simulation) -set(COMPANION_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}") + +use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1 include_directories( ${CMAKE_BINARY_DIR} @@ -101,6 +99,8 @@ include_directories( ${COMPANION_SRC_DIRECTORY}/storage ) +############# Supporting libraries ############### + add_subdirectory(shared) add_subdirectory(modeledit) add_subdirectory(generaledit) @@ -109,6 +109,8 @@ add_subdirectory(storage) add_subdirectory(thirdparty/qcustomplot) add_subdirectory(thirdparty/qxtcommandoptions) +############# Common lib ############### + set(common_SRCS eeprominterface.cpp firmwares/er9x/er9xeeprom.cpp @@ -124,6 +126,8 @@ qt5_wrap_cpp(common_SRCS) add_library(common ${common_SRCS}) qt5_use_modules(common Core Xml Widgets) +############# Companion ############### + set(companion_SRCS helpers.cpp helpers_html.cpp @@ -222,10 +226,7 @@ configure_file(${COMPANION_SRC_DIRECTORY}/companion.desktop.in ${CMAKE_CURRENT_B configure_file(${COMPANION_SRC_DIRECTORY}/simulator.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop @ONLY) if(WIN32) - set(companion_SRCS ${companion_SRCS} icon.rc) - if(NOT MSVC) - set(CMAKE_EXE_LINKER_FLAGS -mwindows) - endif() + list(APPEND companion_SRCS icon.rc) endif() include_directories(${CMAKE_BINARY_DIR}) @@ -233,7 +234,7 @@ include_directories(${CMAKE_SOURCE_DIR}) set(LANGUAGES he pl pt ru de fr es it sv cs fi nl cn) foreach(language ${LANGUAGES}) - set(companion_TS ${companion_TS} translations/companion_${language}.ts) + list(APPEND companion_TS translations/companion_${language}.ts) endforeach(language) qt5_wrap_ui(companion_SRCS ${companion_UIS}) @@ -251,11 +252,13 @@ qt5_use_modules(${COMPANION_NAME} Core Widgets Network) target_link_libraries(${COMPANION_NAME} PRIVATE generaledit modeledit simulation common qcustomplot shared storage ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES}) -############# Standalone simu ############### +PrintTargetReport("${COMPANION_NAME}") + +############# Standalone simulator ############### set(simu_SRCS modeledit/node.cpp - modeledit/edge.cpp # TODO not needed + modeledit/edge.cpp simulator.cpp ) @@ -266,15 +269,28 @@ set(simu_MOC_HDRS qt5_wrap_cpp(simu_SRCS ${simu_MOC_HDRS} ) if(WIN32) - set(simu_SRCS ${simu_SRCS} icon.rc) + list(APPEND simu_SRCS icon.rc) endif() add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE WIN32 ${simu_SRCS} ${companion_RCC}) add_dependencies(${SIMULATOR_NAME} gen_qrc) +qt5_use_modules(${SIMULATOR_NAME} Core Widgets Multimedia) -# TODO not the same link command than companion? -target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation common storage qxtcommandoptions ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${OPENTX_SIMULATOR_LIBS} ${WIN_LINK_LIBRARIES}) +target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation common storage qxtcommandoptions ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES}) + +############# Translations #################### + +find_package(Lupdate) +if(LUPDATE_FOUND) + message(STATUS "Qt lupdate: " ${LUPDATE_EXECUTABLE}) + add_custom_target(translations + WORKING_DIRECTORY ${COMPANION_SRC_DIRECTORY} + COMMAND ${LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR} -no-obsolete -ts ${companion_TS} + ) +else() + message(STATUS "Qt lupdate not found, 'translations' target will not be availabe.") +endif() ############# Install #################### @@ -316,11 +332,11 @@ elseif(WIN32) if(NOT WIN_DO_FULL_INSTALL) # Just copy supporting DLLs to build folder - set(INSTALL_DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + set(INSTALL_DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") message(STATUS "Partial install to " ${INSTALL_DESTINATION}) else() # Full Windows installation with all supporting files - set(INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}) + set(INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}") message(STATUS "Full install to " ${INSTALL_DESTINATION}) # companion & simulator binaries install(TARGETS ${COMPANION_NAME} DESTINATION ${INSTALL_DESTINATION}) @@ -341,30 +357,33 @@ elseif(WIN32) install(FILES ${QT_DLL_DIR}/../plugins/platforms/qwindows${INSTALL_TEMP_QTDLL_SFX}.dll DESTINATION ${INSTALL_DESTINATION}/platforms) # ICU dlls foreach(tmpfile ${INSTALL_TEMP_ICUDLL_FILES}) - # Qt5.7+ doesn't use icu dlls anymore (at least with MinGW), hence optional + # Qt5.7+ doesn't use icu dlls anymore, hence optional install(FILES ${QT_DLL_DIR}/${tmpfile}.dll DESTINATION ${INSTALL_DESTINATION} OPTIONAL) endforeach() # SDL dll if(SDL_FOUND AND SDL_LIBRARY_PATH AND EXISTS "${SDL_LIBRARY_PATH}/SDL.dll") set(SDL_DIR ${SDL_LIBRARY_PATH}) # this is also used by NSIS installer script install(FILES ${SDL_DIR}/SDL.dll DESTINATION ${INSTALL_DESTINATION}) - else() + elseif(SDL_FOUND) message(WARNING "Installer: SDL.dll not found!") endif() # C++/system dlls, depends on compiler if(MSVC) - set(WIN_SYSDIR "$ENV{windir}/SysWOW64") # This would be "system32" for a 64-bit build or on x86... but how to tell? - if(IS_DIRECTORY ${WIN_SYSDIR}) - install(FILES ${WIN_SYSDIR}/msvcp140.dll ${WIN_SYSDIR}/vcruntime140.dll DESTINATION ${INSTALL_DESTINATION} OPTIONAL) + string(REPLACE "\\" "/" WIN_SYSDIR "$ENV{windir}") + set(WIN_SYSDIR "${WIN_SYSDIR}/SysWOW64") # This would be "system32" for a 64-bit build or on x86... but how to tell? + if(IS_DIRECTORY "${WIN_SYSDIR}") + install(FILES "${WIN_SYSDIR}/msvcp140.dll" "${WIN_SYSDIR}/vcruntime140.dll" DESTINATION ${INSTALL_DESTINATION} OPTIONAL) + endif() + if(WIN_PTHREAD_DLL) + install(FILES "${WIN_PTHREAD_DLL}" DESTINATION ${INSTALL_DESTINATION}) endif() - install(FILES "${WIN_PTHREAD_BASE_PATH}/lib/pthreadVC2.dll" DESTINATION ${INSTALL_DESTINATION}) elseif(MINGW) get_filename_component(MINGW_DIR ${CMAKE_CXX_COMPILER} PATH) if(IS_DIRECTORY ${MINGW_DIR}) - install(FILES ${MINGW_DIR}/libgcc_s_dw2-1.dll ${MINGW_DIR}/libstdc++-6.dll ${MINGW_DIR}/libwinpthread-1.dll DESTINATION ${INSTALL_DESTINATION}) + install(FILES "${MINGW_DIR}/libgcc_s_dw2-1.dll" "${MINGW_DIR}/libstdc++-6.dll" "${MINGW_DIR}/libwinpthread-1.dll" DESTINATION ${INSTALL_DESTINATION}) set(MINGW_DIR "${MINGW_DIR}/../opt/bin") # SSL support - install(FILES ${MINGW_DIR}/libeay32.dll ${MINGW_DIR}/ssleay32.dll DESTINATION ${INSTALL_DESTINATION} OPTIONAL) + install(FILES "${MINGW_DIR}/libeay32.dll" "${MINGW_DIR}/ssleay32.dll" DESTINATION ${INSTALL_DESTINATION} OPTIONAL) endif() endif() @@ -410,17 +429,6 @@ if(WIN32) ) endif() -if(LUPDATE_FOUND) - add_custom_target(translations - WORKING_DIRECTORY ${COMPANION_SRC_DIRECTORY} - COMMAND ${LUPDATE_EXECUTABLE} ${COMPANION_SRC_DIRECTORY} -no-obsolete -ts ${companion_TS} - ) -else() - add_custom_target(translations - COMMAND echo "Sorry, QT lupdate was not found." - ) -endif() - set(CPACK_PACKAGE_NAME "companion${C9X_NAME_SUFFIX}") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Models and settings editor for the OpenTX open source firmware") string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_PACKAGE_NAME_LOWERCASE) diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index a65b7d2f7..42242645e 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -1,15 +1,25 @@ include(CMakeForceCompiler) include(Bitmaps) -set(PCB "X9D+" CACHE STRING "Radio type") -set(TRANSLATIONS "EN" CACHE STRING "Radio language") +set(PCB_TYPES X9D X9D+ X9E X7 HORUS 9X 9XR 9X128 9XR128 SKY9X 9XRPRO AR9X 9X2561 GRUVIN9X MEGA2560) +set(GUI_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU NL) +set(TTS_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU) + +set(PCB "X9D+" CACHE STRING "Radio type, one of: ${PCB_TYPES}") +set_property(CACHE PCB PROPERTY STRINGS ${PCB_TYPES}) +set(TRANSLATIONS "EN" CACHE STRING "Radio language, one of: ${GUI_LANGUAGES}") +set_property(CACHE TRANSLATIONS PROPERTY STRINGS ${GUI_LANGUAGES}) +set(SPLASH "DEFAULT" CACHE STRING "Splash (DEFAULT/OFF/FRSKY)") +set_property(CACHE SPLASH PROPERTY STRINGS DEFAULT OFF FRSKY) +set(PPM_UNIT "PERCENT_PREC1" CACHE STRING "PPM display unit (US/PERCENT_PREC1/PERCENT_PREC0)") +set_property(CACHE PPM_UNIT PROPERTY STRINGS US PERCENT_PREC1 PERCENT_PREC0) +set(DEFAULT_MODE "" CACHE STRING "Default sticks mode") + option(HELI "Heli menu" ON) option(FLIGHT_MODES "Flight Modes" ON) option(CURVES "Curves" ON) option(GVARS "Global variables" OFF) option(GUI "GUI enabled" ON) -set(SPLASH "DEFAULT" CACHE STRING "Splash (DEFAULT/OFF/FRSKY)") -set(PPM_UNIT "PERCENT_PREC1" CACHE STRING "PPM display unit (US/PERCENT_PREC1/PERCENT_PREC0)") option(PPM_CENTER_ADJUSTABLE "PPM center adjustable" ON) option(PPM_LIMITS_SYMETRICAL "PPM limits symetrical" OFF) option(OVERRIDE_CHANNEL_FUNCTION "OverrideChannel function available" ON) @@ -24,9 +34,13 @@ option(SIMU_DISKIO "Enable disk IO simulation in simulator. Simulator will use F option(SIMU_LUA_COMPILER "Pre-compile and save Lua scripts in simulator." ON) option(FAS_PROTOTYPE "Support of old FAS prototypes (different resistors)" OFF) option(TEMPLATES "Model templates menu" OFF) -option(WARNINGS_AS_ERRORS "Treat all compiler warnings as error" OFF) option(TRACE_SIMPGMSPACE "Turn on traces in simpgmspace.cpp" ON) -set(DEFAULT_MODE "" CACHE STRING "Default sticks mode") + +# since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags. +set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).") +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).") +set(FIRMWARE_CXX_FLAGS "" CACHE STRING "Additional flags for firmware target c++ compiler (note: all CMAKE_CXX_FLAGS[_*] are ignored for firmware/bootloader).") +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).") # Python check find_package("PythonInterp") @@ -34,21 +48,15 @@ if(PYTHONINTERP_FOUND) message(STATUS "Python found, version: ${PYTHON_VERSION_STRING}") else() message(WARNING "Python not found! Most firmware and simu flavors not buildable.") - set(LUA OFF) + set(LUA NO) endif() -enable_language(ASM) -set(OPT s) - set(THIRDPARTY_DIR thirdparty) set(LUA_DIR ${THIRDPARTY_DIR}/Lua/src) set(COOS_DIR ${THIRDPARTY_DIR}/CoOS) set(FATFS_DIR ${THIRDPARTY_DIR}/FatFs) set(RADIO_BIN_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) -set(GUI_LANGUAGES cz de en es fr it pt sk se pl hu nl) -set(TTS_LANGUAGES cz de en es fr it pt sk se pl hu) - configure_file(stamp.h.in stamp.h @ONLY) add_subdirectory(translations) @@ -138,9 +146,8 @@ endif() include_directories(targets/${TARGET_DIR} ${THIRDPARTY_DIR}) foreach(LANGUAGE ${GUI_LANGUAGES}) - string(TOUPPER ${LANGUAGE} LANGUAGE_CAPITALIZED) - if(TRANSLATIONS STREQUAL ${LANGUAGE_CAPITALIZED}) - add_definitions(-DTRANSLATIONS_${LANGUAGE_CAPITALIZED} -DTRANSLATIONS="${LANGUAGE_CAPITALIZED}") + if(TRANSLATIONS STREQUAL ${LANGUAGE}) + add_definitions(-DTRANSLATIONS_${LANGUAGE} -DTRANSLATIONS="${LANGUAGE}") endif() endforeach() @@ -205,6 +212,10 @@ if(NOT LUA STREQUAL NO) foreach(FILE ${LUA_SRC}) set(SRC ${SRC} ${LUA_DIR}/${FILE}) endforeach() + if(MSVC) + # silence lots of warnings regarding "insecure" use of functions (sprintf, strcpy, etc) from Lua code + set(WARNING_FLAGS "${WARNING_FLAGS} /D_CRT_SECURE_NO_WARNINGS") + endif() endif() if(HELI) @@ -347,37 +358,58 @@ endforeach() add_definitions(-DCORRECT_NEGATIVE_SHIFTS) if(NOT MSVC) - add_definitions(-Wall -Wno-strict-aliasing -Wformat -Wreturn-type -Wunused -Wuninitialized -Wunknown-pragmas -Wno-switch -Wtype-limits) + set(WARNING_FLAGS "${WARNING_FLAGS} -Wall -Wno-strict-aliasing -Wformat -Wreturn-type -Wunused -Wuninitialized -Wunknown-pragmas -Wno-switch -Wtype-limits") if(WARNINGS_AS_ERRORS) - set(WARNING_FLAGS -Werror) + set(WARNING_FLAGS "${WARNING_FLAGS} -Werror") endif(WARNINGS_AS_ERRORS) else() - add_definitions(-DHAVE_STRUCT_TIMESPEC) + add_definitions(-DHAVE_STRUCT_TIMESPEC) # this is for pthread.h + if(WARNINGS_AS_ERRORS) + set(WARNING_FLAGS "${WARNING_FLAGS} /WX") + endif(WARNINGS_AS_ERRORS) endif() add_subdirectory(targets/simu) -if(NOT WIN32) +if(NOT MSVC) add_subdirectory(tests) endif() set(SRC ${SRC} ${FIRMWARE_SRC}) -# trick to remove the -rdynamic and --out-implib issues + +##### firmware target ##### + set(CMAKE_EXECUTABLE_SUFFIX ".elf") +# trick to remove the -rdynamic and --out-implib issues set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") -set(CMAKE_COMMON_FLAGS "") # similar for -mmacosx-version-min=" set(CMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG "") set(CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG "") +# reset some CMake default flags which assume optimization levels/etc +set(CMAKE_C_FLAGS "${FIRMWARE_C_FLAGS}") +set(CMAKE_C_FLAGS_DEBUG "${FIRMWARE_C_FLAGS_DEBUG}") +set(CMAKE_C_FLAGS_RELEASE "") +set(CMAKE_C_FLAGS_MINSIZEREL "") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "") +set(CMAKE_CXX_FLAGS "${FIRMWARE_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS_DEBUG "${FIRMWARE_CXX_FLAGS_DEBUG}") +set(CMAKE_CXX_FLAGS_RELEASE "") +set(CMAKE_CXX_FLAGS_MINSIZEREL "") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "") +# customize linker command set(CMAKE_EXE_LINKER_FLAGS "") -# similar for -Wl,-search_paths_first (fix "arch_paths_first" warning) -set(CMAKE_CXX_LINK_FLAGS "") -set(CMAKE_C_LINK_EXECUTABLE " -o ") -set(CMAKE_CXX_LINK_EXECUTABLE " -o ") +set(CMAKE_C_LINK_EXECUTABLE " -o ") +set(CMAKE_CXX_LINK_EXECUTABLE " -o ") + +use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1 if(NOT MSVC) + set(OPT s) + if(ARCH STREQUAL ARM) + + enable_language(ASM) set(CMAKE_C_COMPILER arm-none-eabi-gcc) set(CMAKE_CXX_COMPILER arm-none-eabi-g++) set(CMAKE_ASM_COMPILER arm-none-eabi-as) @@ -387,21 +419,12 @@ if(NOT MSVC) set(CMAKE_ASM_COMPILE_OBJECT " -o ") 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}") - # Remove once the minimum cmake version is set to 3.1 in the main CmakeLists.tx - if (${CMAKE_VERSION} VERSION_LESS 3.1.0}) - set(COMMON_CPP_FLAGS "${COMMON_FLAGS} -std=gnu++11") - else() - set(COMMON_CPP_FLAGS ${COMMON_FLAGS}) - endif() - set(CMAKE_C_FLAGS "${COMMON_FLAGS} -Wimplicit") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${COMMON_FLAGS} -Wimplicit -g") - set(CMAKE_C_FLAGS_RELEASE "${COMMON_FLAGS} -Wimplicit") - set(CMAKE_C_FLAGS_DEBUG "${COMMON_FLAGS} -Wimplicit -g") - set(CMAKE_CXX_FLAGS "${COMMON_CPP_FLAGS}") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${COMMON_CPP_FLAGS} -g") - set(CMAKE_CXX_FLAGS_RELEASE "${COMMON_CPP_FLAGS}") - set(CMAKE_CXX_FLAGS_DEBUG "${COMMON_CPP_FLAGS} -g") - set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${MCU} -mthumb -lm -T${RADIO_SRC_DIRECTORY}/${LINKER_SCRIPT} -Wl,-Map=firmware.map,--cref,--no-warn-mismatch,--gc-sections") + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS} -Wimplicit") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}") + + # these are in addition to CMAKE_CXX_FLAGS + set(CMAKE_EXE_LINKER_FLAGS "-lm -T${RADIO_SRC_DIRECTORY}/${LINKER_SCRIPT} -Wl,-Map=firmware.map,--cref,--no-warn-mismatch,--gc-sections") if(PCB STREQUAL X9D OR PCB STREQUAL X9D+ OR PCB STREQUAL X9E OR PCB STREQUAL X7) add_subdirectory(targets/${TARGET_DIR}/bootloader) @@ -433,15 +456,16 @@ if(NOT MSVC) DEPENDS firmware WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) - else() + + else() # AVR + set(CMAKE_C_COMPILER avr-gcc) set(CMAKE_CXX_COMPILER avr-gcc) - set(CMAKE_CXX_FLAGS "-mmcu=${MCU} -DF_CPU=16000000UL -O${OPT} -gdwarf-2 -fno-exceptions -flto -fwhole-program -fno-inline-small-functions -mstrict-X ${WARNING_FLAGS}") - - # Remove once the minimum cmake version is set to 3.1 in the main CmakeLists.tx - if (${CMAKE_VERSION} VERSION_LESS 3.1.0}) - set(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}") - endif() + + 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}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "-Wno-uninitialized") # bogus "uninitialized" warnings from ld include_directories(storage gui/${GUI_DIR}) @@ -473,7 +497,8 @@ if(NOT MSVC) DEPENDS firmware WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) - endif() + + endif() # ARM or AVR if(CPU_FAMILY STREQUAL STM32) add_custom_target(flash @@ -488,6 +513,7 @@ if(NOT MSVC) WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) endif() -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + + PrintTargetReport("firmware") + endif(NOT MSVC) diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index 25d20d956..9744fe3f0 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -1,4 +1,5 @@ set(TIMERS 3 CACHE STRING "Timers count (2 or 3)") +set_property(CACHE TIMERS PROPERTY STRINGS 2 3) option(CLI "Command Line Interface" OFF) option(DEBUG "Debug mode" OFF) option(LOG_TELEMETRY "Telemetry Logs on SD card" OFF) @@ -82,7 +83,8 @@ add_definitions(-DBOLD_FONT -DBATTGRAPH -DTHRTRACE -DGAUGES) add_definitions(-DREQUIRED_SDCARD_VERSION="${SDCARD_VERSION}") include_directories(${COOS_DIR} ${COOS_DIR}/kernel ${COOS_DIR}/portable) foreach(LANGUAGE ${TTS_LANGUAGES}) - set(SRC ${SRC} translations/tts_${LANGUAGE}.cpp) + string(TOLOWER ${LANGUAGE} lang_lower) + set(SRC ${SRC} translations/tts_${lang_lower}.cpp) endforeach() set(SRC ${SRC} diff --git a/radio/src/targets/common/arm/stm32/CMakeLists.txt b/radio/src/targets/common/arm/stm32/CMakeLists.txt index 66af38aad..ef680e053 100644 --- a/radio/src/targets/common/arm/stm32/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/CMakeLists.txt @@ -1,7 +1,10 @@ set(LUA "NO" CACHE STRING "Lua scripts (YES/NO/NO_MODEL_SCRIPTS)") -option(LUA_COMPILER "Pre-compile and save Lua scripts" OFF) +set_property(CACHE LUA PROPERTY STRINGS YES NO NO_MODEL_SCRIPTS) set(LUA_SCRIPT_LOAD_MODE "" CACHE STRING "Script loading mode and compilation flags [btTxcd] (see loadScript() API docs). Blank for default ('bt' on radio, 'T' on SIMU/DEBUG builds)") set(USB "JOYSTICK" CACHE STRING "USB option (JOYSTICK/MASSSTORAGE/SERIAL)") +set_property(CACHE USB PROPERTY STRINGS JOYSTICK MASSSTORAGE SERIAL) +option(LUA_COMPILER "Pre-compile and save Lua scripts" OFF) + set(ARCH ARM) set(STM32USB_DIR ${THIRDPARTY_DIR}/STM32_USB-Host-Device_Lib_V2.2.0/Libraries) add_definitions(-DSTM32 -DLUA_INPUTS -DVARIO -DSBUS -DCROSSFIRE) diff --git a/radio/src/targets/common/avr/CMakeLists.txt b/radio/src/targets/common/avr/CMakeLists.txt index cde78c8c1..f3e565fa4 100644 --- a/radio/src/targets/common/avr/CMakeLists.txt +++ b/radio/src/targets/common/avr/CMakeLists.txt @@ -5,9 +5,14 @@ option(GRAPHICS "Additional graphics" ON) option(BOLD "Bold font" ON) option(BATTGRAPH "Battery graph" OFF) option(HAPTIC "Haptic support" OFF) -set(TTS "EN" CACHE STRING "TTS language") -set(LCD "DEFAULT" CACHE STRING "LCD type (DEFAULT/ST7565P/ST7565R/ERC12864FSF/ST7920/KS108)") -set(DSM2 "NO" CACHE STRING "LCD type (NO/PPM/SERIAL)") +set(TTS "EN" CACHE STRING "TTS language, one of: ${TTS_LANGUAGES}") +set_property(CACHE TTS PROPERTY STRINGS ${TTS_LANGUAGES}) +set(LCD_TYPES DEFAULT ST7565P ST7565R ERC12864FSF ST7920 KS108) +set(LCD "DEFAULT" CACHE STRING "LCD type (${LCD_TYPES})") +set_property(CACHE LCD PROPERTY STRINGS ${LCD_TYPES}) +set(DSM2 "NO" CACHE STRING "DSM2 support/interface (NO/PPM/SERIAL)") +set_property(CACHE DSM2 PROPERTY STRINGS NO PPM SERIAL) + set(LUA NO) set(PULSES_SRC pulses_avr.cpp) set(SRC ${SRC} main_avr.cpp) @@ -38,10 +43,10 @@ if(VOICE) add_definitions(-DVOICE) set(TARGET_SRC ${TARGET_SRC} voice.cpp) foreach(LANGUAGE ${TTS_LANGUAGES}) - string(TOUPPER ${LANGUAGE} LANGUAGE_CAPITALIZED) - if(TTS STREQUAL ${LANGUAGE_CAPITALIZED}) - add_definitions(-DTTS_${LANGUAGE_CAPITALIZED}) - set(SRC ${SRC} translations/tts_${LANGUAGE}.cpp) + if(TTS STREQUAL ${LANGUAGE}) + add_definitions(-DTTS_${LANGUAGE}) + string(TOLOWER ${LANGUAGE} lang_lower) + set(SRC ${SRC} translations/tts_${lang_lower}.cpp) endif() endforeach() endif() diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index d6a25c048..0800e3da4 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -6,7 +6,7 @@ if(${PCBREV} GREATER 10) else() option(INTERNAL_GPS "Internal GPS installed" NO) if(NOT INTERNAL_GPS) - message("Internal GPS is optional, use INTERNAL_GPS=YES option to enable it") + message("Horus: Internal GPS is optional, use INTERNAL_GPS=YES option to enable it") endif() endif() option(BLUETOOTH_CLI_PASSTHROUGH "Enable direct communicaton with Bluetooth module from CLI" NO) @@ -69,7 +69,7 @@ endif() if(INTERNAL_GPS) set(SRC ${SRC} gps.cpp) add_definitions(-DINTERNAL_GPS) - message("Internal GPS enabled") + message("Horus: Internal GPS enabled") endif() set(SERIAL2_DRIVER ../common/arm/stm32/serial2_driver.cpp) set(GVAR_SCREEN model_gvars.cpp) @@ -92,7 +92,7 @@ set(FIRMWARE_TARGET_SRC ) if(BLUETOOTH_CLI_PASSTHROUGH) add_definitions(-DBLUETOOTH_CLI_PASSTHROUGH) - message("Bluetooth pass-trough enabled") + message("Horus: Bluetooth pass-trough enabled") endif() set(STM32LIB_SRC STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c diff --git a/radio/src/targets/simu/CMakeLists.txt b/radio/src/targets/simu/CMakeLists.txt index 3d49e4b85..448e8c1b3 100644 --- a/radio/src/targets/simu/CMakeLists.txt +++ b/radio/src/targets/simu/CMakeLists.txt @@ -41,22 +41,21 @@ endif(WIN32) if(MSVC) set(CMAKE_CXX_FLAGS "/EHsc /LD /MP") - message("simu: using MSVC with ${CMAKE_CXX_FLAGS}") else() - if (${CMAKE_VERSION} VERSION_LESS 3.1.0}) - message("simu: adding -std=gnu++11") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") - endif() if(MINGW) # struct packing breaks on MinGW w/out -mno-ms-bitfields: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 & http://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields -mwindows") - message("simu: using MinGW with ${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields") endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") endif() -if((NOT WIN32) AND FOX_FOUND) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}") + +use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1 + +if(FOX_FOUND) if(SIMU_DISKIO) add_definitions(-DSIMU_DISKIO) set(SIMU_SRC ${SIMU_SRC} ${FATFS_DIR}/FatFs/ff.c ${FATFS_DIR}/option/ccsbcs.c) @@ -90,3 +89,5 @@ if(APPLE) endforeach() add_custom_target(opentx-simulators-bundle DEPENDS ${SIMULATOR_BUNDLES}) endif(APPLE) + +PrintTargetReport("simu/libsimulator") diff --git a/radio/src/targets/taranis/bootloader/CMakeLists.txt b/radio/src/targets/taranis/bootloader/CMakeLists.txt index 43851a3f8..ede2e1796 100644 --- a/radio/src/targets/taranis/bootloader/CMakeLists.txt +++ b/radio/src/targets/taranis/bootloader/CMakeLists.txt @@ -69,10 +69,15 @@ set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${MCU} -mthumb -nostartfiles -lm -T${RADIO_SRC add_executable(bootloader ${BOOTLOADER_SRC}) add_dependencies(bootloader ${BITMAPS_TARGET} firmware_translations) +add_custom_command( + TARGET bootloader POST_BUILD + COMMAND arm-none-eabi-objcopy -O binary bootloader.elf bootloader.bin +) if(PYTHONINTERP_FOUND) add_custom_command( TARGET bootloader POST_BUILD - COMMAND arm-none-eabi-objcopy -O binary bootloader.elf bootloader.bin COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/bin2lbm.py bootloader.bin bootloader.lbm ) endif() + +PrintTargetReport("bootloader") diff --git a/radio/src/tests/CMakeLists.txt b/radio/src/tests/CMakeLists.txt index 1f51cfebf..a3611ac49 100644 --- a/radio/src/tests/CMakeLists.txt +++ b/radio/src/tests/CMakeLists.txt @@ -1,38 +1,46 @@ -set(GTEST_INCDIR /usr/include/gtest CACHE string "Location of Google Test includes") -set(GTEST_SRCDIR /usr/src/gtest CACHE string "Location of Google Test directory") +set(GTEST_ROOT /usr CACHE string "Base path to Google Test headers and source.") -if(EXISTS "${GTEST_SRCDIR}/src/gtest-all.cc") - if(Qt5Widgets_FOUND) - add_library(gtests-lib STATIC EXCLUDE_FROM_ALL ${GTEST_SRCDIR}/src/gtest-all.cc ) - target_include_directories(gtests-lib PUBLIC ${GTEST_INCDIR} PUBLIC ${GTEST_SRCDIR}) - add_definitions(-DSIMU) - set(TESTS_PATH ${RADIO_SRC_DIRECTORY}) - configure_file(${RADIO_SRC_DIRECTORY}/tests/location.h.in ${CMAKE_CURRENT_BINARY_DIR}/location.h @ONLY) - include_directories(${CMAKE_CURRENT_BINARY_DIR}) +find_path(GTEST_INCDIR gtest/gtest.h HINTS "${GTEST_ROOT}/include" DOC "Path to Google Test header files folder ('gtest/gtest.h').") +find_path(GTEST_SRCDIR src/gtest-all.cc HINTS "${GTEST_ROOT}" "${GTEST_ROOT}/src/gtest" DOC "Path of Google Test 'src' folder.") - foreach(FILE ${SRC}) - set(RADIO_SRC ${RADIO_SRC} ../${FILE}) - endforeach() - - file(GLOB TEST_SRC_FILES ${RADIO_SRC_DIRECTORY}/tests/*.cpp) - - if (${CMAKE_VERSION} VERSION_LESS 3.1.0}) - set(COMMON_CPP_FLAGS "${COMMON_FLAGS} -std=gnu++11") - message("USING -std=gnu++11") - else() - set(COMMON_CPP_FLAGS ${COMMON_FLAGS}) - endif() - set(CMAKE_C_FLAGS_DEBUG "${COMMON_FLAGS} -g -O0") - set(CMAKE_CXX_FLAGS_DEBUG "${COMMON_CPP_FLAGS} -g -O0") - - add_executable(gtests EXCLUDE_FROM_ALL ${TEST_SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/location.h ${RADIO_SRC} ../targets/simu/simpgmspace.cpp ../targets/simu/simueeprom.cpp) - qt5_use_modules(gtests Core Widgets) - add_dependencies(gtests ${FIRMWARE_DEPENDENCIES} gtests-lib) - target_link_libraries(gtests gtests-lib pthread) - message("Added optional gtests target") - else() - message("WARNING: Qt5 widgets not found, gtest target will not be available!") +if(GTEST_INCDIR AND GTEST_SRCDIR AND Qt5Widgets_FOUND) + add_library(gtests-lib STATIC EXCLUDE_FROM_ALL ${GTEST_SRCDIR}/src/gtest-all.cc ) + target_include_directories(gtests-lib PUBLIC ${GTEST_INCDIR} ${GTEST_INCDIR}/gtest ${GTEST_SRCDIR}) + add_definitions(-DSIMU) + set(TESTS_PATH ${RADIO_SRC_DIRECTORY}) + configure_file(${RADIO_SRC_DIRECTORY}/tests/location.h.in ${CMAKE_CURRENT_BINARY_DIR}/location.h @ONLY) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + + if(WIN32) + target_include_directories(gtests-lib PUBLIC ${WIN_INCLUDE_DIRS}) + target_link_libraries(gtests-lib PRIVATE ${WIN_LINK_LIBRARIES}) + endif(WIN32) + + if(SDL_FOUND AND SIMU_AUDIO) + target_include_directories(gtests-lib PUBLIC ${SDL_INCLUDE_DIR}) + target_link_libraries(gtests-lib PRIVATE ${SDL_LIBRARY}) endif() + + foreach(FILE ${SRC}) + set(RADIO_SRC ${RADIO_SRC} ../${FILE}) + endforeach() + + file(GLOB TEST_SRC_FILES ${RADIO_SRC_DIRECTORY}/tests/*.cpp) + + if(MINGW) + # struct packing breaks on MinGW w/out -mno-ms-bitfields: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 & http://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields") + endif() + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") + + use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1 + + add_executable(gtests EXCLUDE_FROM_ALL ${TEST_SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/location.h ${RADIO_SRC} ../targets/simu/simpgmspace.cpp ../targets/simu/simueeprom.cpp) + qt5_use_modules(gtests Core Widgets) + add_dependencies(gtests ${FIRMWARE_DEPENDENCIES} gtests-lib) + target_link_libraries(gtests gtests-lib pthread) + message(STATUS "Added optional gtests target") else() - message("WARNING: can't find gtests source, gtest target will not be available!") + message(WARNING "WARNING: gtests target will not be available (check that GTEST_INCDIR, GTEST_SRCDIR, and Qt5Widgets are configured).") endif() diff --git a/radio/src/tests/gtests.cpp b/radio/src/tests/gtests.cpp index 76bf16065..98493ade7 100644 --- a/radio/src/tests/gtests.cpp +++ b/radio/src/tests/gtests.cpp @@ -19,8 +19,106 @@ */ #include +#include +#include +#include +#include #include "gtests.h" +using ::testing::TestEventListener; +using ::testing::EmptyTestEventListener; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; +using ::testing::InitGoogleTest; + +namespace { + +void printColorCode(int color) +{ +#if !GTEST_OS_WINDOWS + if (isatty(fileno(stdout))) + fprintf(stdout, "\033[0;%dm", color); +#endif +} + +/** + * Replaces gtest's PrettyUnitTestResultPrinter with something less verbose. + * Uses the default printer if/when the messages might be interesting, + * e.g. for full error info or tests summary. +*/ +class TersePrinter : public EmptyTestEventListener { + public: + explicit TersePrinter(TestEventListener * prettyPrinter) + : prettyPrinter(prettyPrinter), currentTestInfo(NULL) + { + } + void OnTestProgramStart(const UnitTest & unit_test) + { + prettyPrinter->OnTestProgramStart(unit_test); + } + void OnTestIterationStart(const UnitTest & unit_test, int iteration) + { + printColorCode(36); + fprintf(stdout, "############ "); + fprintf(stdout, "Running %d test(s) from %d test case(s), iteration: %d.\n", unit_test.test_to_run_count(), unit_test.test_case_to_run_count(), iteration + 1); + printColorCode(0); + fflush(stdout); + } + void OnTestCaseStart(const TestCase & test_case) + { + prettyPrinter->OnTestCaseStart(test_case); + } + void OnTestStart(const TestInfo & test_info) + { + currentTestInfo = &test_info; + } + void OnTestPartResult(const TestPartResult & test_part_result) + { + if (test_part_result.failed()) { + prettyPrinter->OnTestStart(*currentTestInfo); + prettyPrinter->OnTestPartResult(test_part_result); + } + } + void OnTestEnd(const TestInfo & test_info) + { + currentTestInfo = NULL; + if (test_info.result()->Failed()) { + prettyPrinter->OnTestEnd(test_info); + } + else { + printColorCode(32); + fprintf(stdout, "+"); + printColorCode(0); + fflush(stdout); + } + } + void OnTestCaseEnd(const TestCase & test_case) + { + fprintf(stdout, "\n"); + fflush(stdout); + } + void OnTestIterationEnd(const UnitTest & unit_test, int iteration) + { + prettyPrinter->OnTestIterationEnd(unit_test, iteration); + } + void OnTestProgramEnd(const UnitTest & unit_test) + { + prettyPrinter->OnTestProgramEnd(unit_test); + } + + private: + // gtest's default unit test result printer. + std::unique_ptr prettyPrinter; + // The currently running TestInfo, if any. + const TestInfo * currentTestInfo; +}; + +} // anonymous namespace + int32_t lastAct = 0; uint16_t anaInValues[NUM_STICKS+NUM_POTS+NUM_SLIDERS] = { 0 }; uint16_t anaIn(uint8_t chan) @@ -53,6 +151,18 @@ int main(int argc, char **argv) StartEepromThread(NULL); menuLevel = 0; menuHandlers[0] = menuMainView; - ::testing::InitGoogleTest(&argc, argv); + InitGoogleTest(&argc, argv); + + // use --verbose option to revert to gtest's default output format + bool verbose = false; + if (argc > 1 && !strcmp(argv[1], "--verbose")) + verbose = true; + + if (!verbose) { + TestEventListeners & listeners = UnitTest::GetInstance()->listeners(); + TestEventListener * defaultPrinter = listeners.Release(listeners.default_result_printer()); + listeners.Append(new TersePrinter(defaultPrinter)); + } + return RUN_ALL_TESTS(); } diff --git a/tools/commit-tests.sh b/tools/commit-tests.sh index 9c030e413..a276add84 100755 --- a/tools/commit-tests.sh +++ b/tools/commit-tests.sh @@ -27,7 +27,7 @@ else fi SRCDIR=$(dirname "$SCRIPT")/.. -COMMON_OPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=/opt/qt55" +COMMON_OPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=/opt/qt55 -DWARNINGS_AS_ERRORS=YES -DVERBOSE_CMAKELISTS=YES -DCMAKE_RULE_MESSAGES=OFF -Wno-dev" mkdir build || true cd build @@ -86,42 +86,42 @@ make -j${CORES} gtests ; ./gtests --gtest_shuffle --gtest_repeat=5 --gtest_break # OpenTX on X7 rm -rf * -cmake ${COMMON_OPTIONS} -DPCB=X7 -DHELI=YES -DWARNINGS_AS_ERRORS=YES ${SRCDIR} +cmake ${COMMON_OPTIONS} -DPCB=X7 -DHELI=YES ${SRCDIR} make -j${CORES} firmware make -j${CORES} simu make -j${CORES} gtests ; ./gtests --gtest_shuffle --gtest_repeat=5 --gtest_break_on_failure # OpenTX on X9D rm -rf * -cmake ${COMMON_OPTIONS} -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES -DWARNINGS_AS_ERRORS=YES ${SRCDIR} +cmake ${COMMON_OPTIONS} -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} firmware make -j${CORES} simu make -j${CORES} gtests ; ./gtests --gtest_shuffle --gtest_repeat=5 --gtest_break_on_failure # OpenTX on X9D+ rm -rf * -cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES -DWARNINGS_AS_ERRORS=YES ${SRCDIR} +cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} firmware make -j${CORES} simu make -j${CORES} gtests ; ./gtests --gtest_shuffle --gtest_repeat=5 --gtest_break_on_failure # OpenTX on Taranis X9E rm -rf * -cmake ${COMMON_OPTIONS} -DPCB=X9E -DHELI=YES -DLUA=YES -DGVARS=YES -DWARNINGS_AS_ERRORS=YES -DPPM_UNIT=PERCENT_PREC1 ${SRCDIR} +cmake ${COMMON_OPTIONS} -DPCB=X9E -DHELI=YES -DLUA=YES -DGVARS=YES -DPPM_UNIT=PERCENT_PREC1 ${SRCDIR} make -j${CORES} firmware make -j${CORES} simu make -j${CORES} gtests ; ./gtests --gtest_shuffle --gtest_repeat=5 --gtest_break_on_failure # OpenTX on Horus beta boards rm -rf * -cmake ${COMMON_OPTIONS} -DPCB=HORUS -DPCBREV=10 -DHELI=YES -DLUA=YES -DGVARS=YES -DWARNINGS_AS_ERRORS=YES ${SRCDIR} +cmake ${COMMON_OPTIONS} -DPCB=HORUS -DPCBREV=10 -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} firmware make -j${CORES} simu make -j${CORES} gtests ; ./gtests --gtest_shuffle --gtest_repeat=5 --gtest_break_on_failure # OpenTX on Horus rm -rf * -cmake ${COMMON_OPTIONS} -DPCB=HORUS -DHELI=YES -DLUA=YES -DGVARS=YES -DWARNINGS_AS_ERRORS=YES ${SRCDIR} +cmake ${COMMON_OPTIONS} -DPCB=HORUS -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} firmware make -j${CORES} simu make -j${CORES} gtests ; ./gtests --gtest_shuffle --gtest_repeat=5 --gtest_break_on_failure