Stack overflow on Horus
[opentx.git] / CMakeLists.txt
blobfafd8c5373a169e228a8541ba93aa3aee0008a5f
1 project(OpenTX)
3 set(VERSION_MAJOR "2")
4 set(VERSION_MINOR "3")
5 set(VERSION_REVISION "3")
6 set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
7 set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
8 set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
9 set(SDCARD_REVISION "0025")
10 set(SDCARD_VERSION  ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
12 cmake_minimum_required(VERSION 2.8)
13 cmake_policy(SET CMP0020 NEW)
14 cmake_policy(SET CMP0023 OLD)
15 if(POLICY CMP0042)
16   cmake_policy(SET CMP0042 NEW)
17 endif()
18 if(POLICY CMP0043)
19   cmake_policy(SET CMP0043 NEW)
20 endif()
21 if(POLICY CMP0054)
22   cmake_policy(SET CMP0054 NEW)
23 endif()
24 if(POLICY CMP0058)
25   cmake_policy(SET CMP0058 NEW)  # for ninja
26 endif()
28 set(CMAKE_COLOR_MAKEFILE ON)
30 set(CMAKE_CXX_STANDARD 11)
32 set(RADIO_DIRECTORY ${PROJECT_SOURCE_DIR}/radio)
33 set(RADIO_SRC_DIRECTORY ${RADIO_DIRECTORY}/src)
34 set(COMPANION_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src)
35 set(SIMU_SRC_DIRECTORY ${COMPANION_SRC_DIRECTORY}/simulation)
37 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
38 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
39 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
41 include(Macros)
42 today(DATE)
43 now(TIME)
44 git_id(GIT_STR)
46 message(STATUS "OpenTX ${VERSION} @${GIT_STR}")
48 # options shared by all targets
50 option(APP_CUSTOM_DBG_HANDLER "Use custom message handler for debug output in all Qt apps." ON)
51 set(APP_CUSTOM_DBG_LEVEL "0" CACHE STRING
52   "Debug output level: 0=debug+; 1=info+; 2=warn+; 3=critical+; 4=fatal only.")
53 set(APP_CUSTOM_DBG_SHOW_FILE "DEFAULT" CACHE STRING
54   "Show source file names in debug output. 1/0/DEFAULT (default is ON with DEBUG builds).")
56 option(VERBOSE_CMAKELISTS "Show extra information while processing CMakeLists.txt files." OFF)
57 option(WARNINGS_AS_ERRORS "Treat any compiler warning as an error (adds -Werror flag)." OFF)
59 if(WIN32)
60   set(WIN_EXTRA_LIBS_PATH "C:/Programs" CACHE PATH
61     "Base path to extra libs/headers on Windows (SDL & pthreads folders should be in here).")
62   list(APPEND CMAKE_PREFIX_PATH "${WIN_EXTRA_LIBS_PATH}" "${WIN_EXTRA_LIBS_PATH}/SDL")  # hints for FindSDL
63 endif()
65 # Python check
66 find_package("PythonInterp")
67 if(PYTHONINTERP_FOUND)
68   message(STATUS "Python found, version: ${PYTHON_VERSION_STRING}")
69   get_filename_component(PYTHON_DIRECTORY ${PYTHON_EXECUTABLE} DIRECTORY)
70 else()
71   message(WARNING "Python not found! Most firmware and simu flavors not buildable.")
72   set(LUA NO)
73 endif()
75 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")  # regular Clang or AppleClang
76   set(CLANG TRUE)
77 endif()
79 option(DISABLE_COMPANION "Disable building companion and simulators" OFF)
81 if(NOT DISABLE_COMPANION)  # FIXME cosmetics/style
83 if(APPLE AND EXISTS /usr/local/opt/qt5)
84         # Homebrew installs Qt5 (up to at least 5.9.1) in
85         # /usr/local/qt5, ensure it can be found by CMake since
86         # it is not in the default /usr/local prefix.
87         list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/qt5")
88 endif()
90 find_package(Qt5Core)
91 find_package(Qt5Widgets)
92 find_package(Qt5Xml)
93 find_package(Qt5LinguistTools)
94 find_package(Qt5PrintSupport)
95 find_package(Qt5Multimedia)
96 find_package(Qt5Svg)
98 if(Qt5Core_FOUND)
99   message(STATUS "Qt Version: ${Qt5Core_VERSION}")
101   ### Get locations of Qt binary executables & libs (libs are for distros, not for linking)
102   # first set up some hints
103   get_target_property(QtCore_LOCATION Qt5::Core LOCATION)
104   get_filename_component(qt_core_path ${QtCore_LOCATION} PATH)
105   if(APPLE)
106     get_filename_component(qt_core_path "${qt_core_path}/.." ABSOLUTE)
107   endif()
109   set(QT_LIB_DIR ${qt_core_path} CACHE PATH "Path to Qt libraries (.dll|.framework|.so).")
110   find_path(QT_BIN_DIR NAMES "qmake" "qmake.exe" HINTS "${CMAKE_PREFIX_PATH}/bin" "${qt_core_path}/../bin" "${qt_core_path}" DOC "Path to Qt binaries (qmake, lupdate, etc.).")
111   find_program(QT_QMAKE_EXECUTABLE qmake HINTS "${QT_BIN_DIR}" DOC "Location of qmake program.")
112   find_program(QT_LUPDATE_EXECUTABLE lupdate HINTS "${QT_BIN_DIR}" DOC "Location of Qt's 'lupdate' program for updating translation files.")
114   # Try to find Qt translations
115   if(QT_QMAKE_EXECUTABLE)
116     execute_process(
117       COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
118       OUTPUT_VARIABLE qt_translations_hint
119       OUTPUT_STRIP_TRAILING_WHITESPACE
120       )
121   endif()
122   find_path(QT_TRANSLATIONS_DIR NAMES "qt_en.qm" HINTS "${qt_translations_hint}" DOC "Path to prebuilt Qt translations (qt_*.qm).")
124   ### Common definitions for the Qt-based apps
125   list(APPEND APP_COMMON_DEFINES -DSIMU)
126   list(APPEND APP_COMMON_DEFINES -DQXT_STATIC)
127   list(APPEND APP_COMMON_DEFINES -DQT_USE_QSTRINGBUILDER)  # more efficient QString construction using % operator
129   if(MSVC)
130     list(APPEND APP_COMMON_DEFINES -D__STDC_LIMIT_MACROS)
131   endif()
132   if(APP_CUSTOM_DBG_HANDLER)
133     # provide full qDebug log context to our custom handler. This may also affect libsimulator, which is why it is here
134     list(APPEND APP_COMMON_DEFINES -DQT_MESSAGELOGCONTEXT)
135     list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=1)
136     if(APP_CUSTOM_DBG_LEVEL GREATER -1 AND APP_CUSTOM_DBG_LEVEL LESS 5)
137       list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_DEFAULT_LEVEL=${APP_CUSTOM_DBG_LEVEL})
138     endif()
139     if(NOT APP_CUSTOM_DBG_SHOW_FILE STREQUAL "DEFAULT" AND (APP_CUSTOM_DBG_SHOW_FILE STREQUAL "1" OR APP_CUSTOM_DBG_SHOW_FILE STREQUAL "0"))
140       list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_SHOW_SRC_PATH=${APP_CUSTOM_DBG_SHOW_FILE})
141     endif()
142   else()
143     list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=0)
144   endif()
146 else()
147   message(WARNING "Qt not found! Companion and Simulator builds disabled.")
148 endif()
150 if(NOT WIN32)
151   find_package(Fox QUIET)  # QUIET not working on WIN32?
152   if (FOX_FOUND)
153     message(STATUS "Foxlib found at ${FOX_LIBRARY}")
154   else() # if(NOT WIN32)
155     message("Libfox not found, simu target will not be available")
156   endif()
157 endif()
159 if(Qt5Core_FOUND OR FOX_FOUND)
160   set(SDL_BUILDING_LIBRARY YES)  # this prevents FindSDL from appending SDLmain lib to the results, which we don't want
161   find_package("SDL")
162   if(SDL_FOUND)
163     message(STATUS "SDL Lib: ${SDL_LIBRARY}; Headers: ${SDL_INCLUDE_DIR}; Version: ${SDL_VERSION_STRING}")
164     if (NOT ${SDL_VERSION_STRING} VERSION_LESS "2.0")
165       message(FATAL_ERROR "OpenTX requires SDL 1.x, not 2.x")
166     endif()
167   else()
168     message(STATUS "SDL not found! Simulator audio, and joystick inputs, will not work.")
169   endif()
170 endif()
171 endif(NOT DISABLE_COMPANION)
173 # Check for a file that is typically left from a OpenTX 2.1 build and abort if found
174 if (EXISTS ${RADIO_SRC_DIRECTORY}/stamp.h OR EXISTS ${RADIO_SRC_DIRECTORY}/translations/en.h)
175    message(FATAL_ERROR "Source directory contains files leftover from a OpenTX 2.1 build. Please run `git clean -f` in source directory (Careful: Will remove any extra files) or do a new clean git checkout")
176 endif()
178 # Windows-specific includes and libs shared by sub-projects
179 if(WIN32)
180   list(APPEND WIN_INCLUDE_DIRS "${RADIO_SRC_DIRECTORY}/thirdparty/windows/dirent")
181   if(MSVC)
182     list(APPEND WIN_INCLUDE_DIRS "${RADIO_SRC_DIRECTORY}/thirdparty/windows/msinttypes")
183     set(WIN_PTHREAD_BASE_PATH "${WIN_EXTRA_LIBS_PATH}/pthreads/Pre-built.2" CACHE PATH "Where to find pthreads include and lib folders.")
184     list(APPEND WIN_INCLUDE_DIRS "${WIN_PTHREAD_BASE_PATH}/include")
185     find_file(WIN_PTHREAD_LIB pthreadVC2.lib PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib NO_DEFAULT_PATH)
186     find_file(WIN_PTHREAD_DLL pthreadVC2.dll PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib dll/x86 dll NO_DEFAULT_PATH)
187     if(WIN_PTHREAD_LIB)
188       list(APPEND WIN_LINK_LIBRARIES "${WIN_PTHREAD_LIB}")
189     else()
190       message(SEND_ERROR "pthreadVC2.lib not found!")
191     endif()
192   else()
193     set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
194     set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)
195     set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
196     set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)
197   endif()
198 endif()
200 set(GTEST_ROOT /usr CACHE STRING "Base path to Google Test headers and source.")
202 find_path(GTEST_INCDIR gtest/gtest.h HINTS "${GTEST_ROOT}/include" DOC "Path to Google Test header files folder ('gtest/gtest.h').")
203 find_path(GTEST_SRCDIR src/gtest-all.cc HINTS "${GTEST_ROOT}" "${GTEST_ROOT}/src/gtest" DOC "Path of Google Test 'src' folder.")
205 if(NOT GTEST_INCDIR OR NOT GTEST_SRCDIR)
206   message(STATUS "Googletest will be downloaded")
208   set(GTEST_VERSION 1.8.1)
210   set(GTEST_SRCDIR "${RADIO_SRC_DIRECTORY}/tests/googletest-release-${GTEST_VERSION}/googletest")
211   set(GTEST_INCDIR "${GTEST_SRCDIR}/include")
213   set(GTEST_URL     "https://github.com/google/googletest/archive/release-${GTEST_VERSION}.tar.gz")
214   set(GTEST_ARCHIVE "${RADIO_SRC_DIRECTORY}/tests/gtest-${GTEST_VERSION}.tar.gz")
216   if (NOT EXISTS "${GTEST_SRCDIR}")
217     file(DOWNLOAD "${GTEST_URL}" ${GTEST_ARCHIVE} SHOW_PROGRESS)
218     execute_process(
219       COMMAND ${CMAKE_COMMAND} -E tar -xf ${GTEST_ARCHIVE}
220       WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY}/tests)
221     execute_process(
222       COMMAND ${CMAKE_COMMAND} -E remove -f ${GTEST_ARCHIVE})
223   endif()
224 endif()
226 add_subdirectory(${RADIO_SRC_DIRECTORY})
228 add_custom_target(tests-radio
229   COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-radio
230   DEPENDS gtests-radio
231   )
233 if(Qt5Core_FOUND AND NOT DISABLE_COMPANION)
234   add_subdirectory(${COMPANION_SRC_DIRECTORY})
235   add_custom_target(tests-companion
236     COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-companion
237     DEPENDS gtests-companion
238     )
239   add_custom_target(gtests
240     DEPENDS gtests-radio gtests-companion
241     )
242   add_custom_target(tests
243     DEPENDS tests-radio tests-companion
244   )
245 else()
246   add_custom_target(gtests
247     DEPENDS gtests-radio
248     )
249   add_custom_target(tests
250     DEPENDS tests-radio
251   )
252 endif()