2 ## This file is part of the SmuView project.
4 ## Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
5 ## Copyright (C) 2012-2013 Alexandru Gagniuc <mr.nuke.me@gmail.com>
6 ## Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>
8 ## This program is free software: you can redistribute it and/or modify
9 ## it under the terms of the GNU General Public License as published by
10 ## the Free Software Foundation, either version 3 of the License, or
11 ## (at your option) any later version.
13 ## This program is distributed in the hope that it will be useful,
14 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ## GNU General Public License for more details.
18 ## You should have received a copy of the GNU General Public License
19 ## along with this program. If not, see <http://www.gnu.org/licenses/>.
22 cmake_minimum_required(VERSION 3.6)
24 project(smuview C CXX)
26 include(GNUInstallDirs)
28 list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake")
31 #===============================================================================
33 #-------------------------------------------------------------------------------
35 option(DISABLE_WERROR "Build without -Werror" FALSE)
36 option(ENABLE_SIGNALS "Build with UNIX signals" TRUE)
37 option(ENABLE_TESTS "Enable unit tests" TRUE)
38 option(STATIC_PKGDEPS_LIBS "Statically link to (pkg-config) libraries" FALSE)
40 # Let AUTOMOC and AUTOUIC process GENERATED files.
42 cmake_policy(SET CMP0071 NEW)
45 # Only interpret if() arguments as variables or keywords when unquoted.
47 cmake_policy(SET CMP0054 NEW)
50 # SmuView, QCodeEditor and pybind11 only need C++11, but the macOS build
53 set(CMAKE_CXX_STANDARD 17)
55 set(CMAKE_CXX_STANDARD 11)
59 # On Windows/MinGW we need to statically link to libraries.
60 # This option is user configurable, but enable it by default on win32.
61 set(STATIC_PKGDEPS_LIBS TRUE)
63 # Windows does not support UNIX signals.
64 set(ENABLE_SIGNALS FALSE)
66 # When cross compiling this is needed for pkg-config
67 set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
70 if(NOT CMAKE_BUILD_TYPE)
71 set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
72 "Choose the type of build (None, Debug, Release, RelWithDebInfo, MinSizeRel)."
76 # Generate compile_commands.json in build/ for analyzers like clang-tidy.
77 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
79 message(STATUS "DISABLE_WERROR: ${DISABLE_WERROR}")
80 message(STATUS "ENABLE_SIGNALS: ${ENABLE_SIGNALS}")
81 message(STATUS "ENABLE_TESTS: ${ENABLE_TESTS}")
82 message(STATUS "STATIC_PKGDEPS_LIBS: ${STATIC_PKGDEPS_LIBS}")
84 #===============================================================================
86 #-------------------------------------------------------------------------------
88 list(APPEND PKGDEPS glib-2.0>=2.28.0)
89 list(APPEND PKGDEPS glibmm-2.4>=2.28.0)
91 set(LIBSR_CXX_BINDING "libsigrokcxx>=0.5.2")
92 list(APPEND PKGDEPS "${LIBSR_CXX_BINDING}")
94 find_package(PkgConfig)
95 pkg_check_modules(LIBSRCXX ${LIBSR_CXX_BINDING} IMPORTED_TARGET)
96 if(NOT LIBSRCXX_FOUND OR NOT LIBSRCXX_VERSION)
97 message(FATAL_ERROR "libsigrok C++ bindings missing, check libsigrok's 'configure' output (missing dependencies?)")
99 pkg_check_modules(PKGDEPS REQUIRED IMPORTED_TARGET ${PKGDEPS})
101 include(CheckSigrokFeatures)
102 if(STATIC_PKGDEPS_LIBS)
103 check_libsigrok_features("${LIBSRCXX_STATIC_INCLUDE_DIRS}" PkgConfig::PKGDEPS)
105 check_libsigrok_features("${LIBSRCXX_INCLUDE_DIRS}" PkgConfig::PKGDEPS)
108 set(CMAKE_INCLUDE_CURRENT_DIR ON)
109 set(CMAKE_AUTOMOC ON)
111 find_package(Qt5 5.7 COMPONENTS Core Gui Widgets Svg REQUIRED)
114 # MXE workaround: Use pkg-config to find Qt5 libs.
115 # https://github.com/mxe/mxe/issues/1642
116 # Not required (and doesn't work) on MSYS2.
117 if(NOT DEFINED ENV{MSYSTEM})
118 pkg_check_modules(QT5ALL REQUIRED Qt5Widgets Qt5Gui Qt5Svg)
122 set(QT_LIBRARIES Qt5::Gui Qt5::Widgets Qt5::Svg)
124 find_package(Qwt 6.1.2 REQUIRED)
126 # Only boost::config and boost::multiprecision are required, so no need to
127 # specify any boost libraries
128 find_package(Boost 1.54 REQUIRED)
130 # Find the platform's thread library (needed for C++11 threads).
131 # This will set ${CMAKE_THREAD_LIBS_INIT} to the correct, OS-specific value.
132 find_package(Threads REQUIRED)
135 # MXE workaround: Use PkgConfig to find the supplied Python 3.4 (see MXE build
136 # script sigrok-cross-mingw-smuview in sigrok-util) and disable the find
137 # python functionality in pybind11
138 set(PYBIND11_NOPYTHON ON)
140 # This is not needed atm, but might come in handy in the future:
141 # Python 3.8 no longer links to libpython, but it provides a python3-embed.pc
142 # now, so let's try using that first and only fall back on the normal case if
144 # See: https://docs.python.org/3.8/whatsnew/3.8.html#debug-build-uses-the-same-abi-as-release-build
145 pkg_check_modules(PYTHON3 python3-embed)
146 if(NOT PYTHON3_FOUND)
147 pkg_check_modules(PYTHON3 python3)
151 # SmuView has its own copy of pybind11
153 # Use pybind11 2.9.2 vanilla for the MXE build. 2.9.2 is the last pybind11
154 # version that supports Python 3.4.4 which is used for static linking in the
156 add_subdirectory(external/pybind11_2.9.2)
158 # Use pybind11 2.11 dev1 with the emum_docstring patch for all other builds
159 add_subdirectory(external/pybind11_2.11_dev1)
161 # SmuView has its own copy of QCodeEditor
162 add_subdirectory(external/QCodeEditor)
163 # SmuView has its own copy of QtFindReplaceDialog
164 add_subdirectory(external/QtFindReplaceDialog/dialogs)
167 #===============================================================================
168 #= System Introspection
169 #-------------------------------------------------------------------------------
172 memaccess_check_unaligned_le(HAVE_UNALIGNED_LITTLE_ENDIAN_ACCESS)
175 #===============================================================================
177 #-------------------------------------------------------------------------------
179 set(SV_TITLE SmuView)
180 set(SV_VERSION_STRING "0.0.6")
182 # Append the revision hash unless we are exactly on a tagged release.
183 include(GetGitRevisionDescription)
184 git_describe(SV_TAG_VERSION_STRING --match "v${SV_VERSION_STRING}" --exact-match)
185 if(NOT SV_TAG_VERSION_STRING)
186 get_git_head_revision(SV_REVSPEC SV_HASH)
188 string(SUBSTRING "${SV_HASH}" 0 7 SV_SHORTHASH)
189 set(SV_VERSION_STRING "${SV_VERSION_STRING}-git-${SV_SHORTHASH}")
192 # Non-tagged releases use the continuous manual
193 set(SV_MANUAL_VERSION "continuous")
195 # Tagged releases use a fixed manual version
196 set(SV_MANUAL_VERSION ${SV_VERSION_STRING})
199 if(SV_VERSION_STRING MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-[-0-9a-z]*)?$")
200 set(SV_VERSION_MAJOR ${CMAKE_MATCH_1})
201 set(SV_VERSION_MINOR ${CMAKE_MATCH_2})
202 set(SV_VERSION_MICRO ${CMAKE_MATCH_3})
203 set(SV_VERSION_SUFFIX ${CMAKE_MATCH_4})
206 message(STATUS "${SV_TITLE} version: ${SV_VERSION_STRING}")
209 set(SV_GLIBMM_VERSION ${PKGDEPS_glibmm-2.4_VERSION})
210 set(SV_PYBIND11_VERSION ${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH})
212 # MXE workaround: Use PkgConfig to find Python
213 set(SV_PYTHON_VERSION ${PYTHON3_VERSION})
215 set(SV_PYTHON_VERSION ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
219 ${PROJECT_SOURCE_DIR}/config.h.in
220 ${PROJECT_BINARY_DIR}/config.h
223 ${PROJECT_SOURCE_DIR}/contrib/config_version.sh.in
224 ${PROJECT_BINARY_DIR}/contrib/config_version.sh
228 #===============================================================================
230 #-------------------------------------------------------------------------------
235 src/devicemanager.cpp
238 src/settingsmanager.cpp
240 src/channels/addscchannel.cpp
241 src/channels/basechannel.cpp
242 src/channels/dividechannel.cpp
243 src/channels/hardwarechannel.cpp
244 src/channels/integratechannel.cpp
245 src/channels/mathchannel.cpp
246 src/channels/movingavgchannel.cpp
247 src/channels/multiplysfchannel.cpp
248 src/channels/multiplysschannel.cpp
249 src/channels/userchannel.cpp
250 src/data/analogbasesignal.cpp
251 src/data/analogsamplesignal.cpp
252 src/data/analogtimesignal.cpp
253 src/data/basesignal.cpp
254 src/data/datautil.cpp
255 src/data/properties/baseproperty.cpp
256 src/data/properties/boolproperty.cpp
257 src/data/properties/doubleproperty.cpp
258 src/data/properties/doublerangeproperty.cpp
259 src/data/properties/int32property.cpp
260 src/data/properties/measuredquantityproperty.cpp
261 src/data/properties/rationalproperty.cpp
262 src/data/properties/stringproperty.cpp
263 src/data/properties/uint64property.cpp
264 src/data/properties/uint64rangeproperty.cpp
265 src/devices/basedevice.cpp
266 src/devices/configurable.cpp
267 src/devices/deviceutil.cpp
268 src/devices/hardwaredevice.cpp
269 src/devices/measurementdevice.cpp
270 src/devices/sourcesinkdevice.cpp
271 src/devices/userdevice.cpp
273 src/python/bindings.cpp
274 src/python/pystreambuf.cpp
275 src/python/pystreamredirect.hpp
276 src/python/smuscriptrunner.cpp
277 src/python/uihelper.cpp
278 src/python/uiproxy.cpp
280 src/ui/data/quantitycombobox.cpp
281 src/ui/data/quantityflagslist.cpp
282 src/ui/data/unitcombobox.cpp
283 src/ui/datatypes/basewidget.cpp
284 src/ui/datatypes/boolbutton.cpp
285 src/ui/datatypes/boolcheckbox.cpp
286 src/ui/datatypes/boolled.cpp
287 src/ui/datatypes/datatypehelper.cpp
288 src/ui/datatypes/doublecontrol.cpp
289 src/ui/datatypes/doubledisplay.cpp
290 src/ui/datatypes/doubleknob.cpp
291 src/ui/datatypes/doublerangecombobox.cpp
292 src/ui/datatypes/doubleslider.cpp
293 src/ui/datatypes/doublesmallcontrol.cpp
294 src/ui/datatypes/doublespinbox.cpp
295 src/ui/datatypes/int32spinbox.cpp
296 src/ui/datatypes/measuredquantitycombobox.cpp
297 src/ui/datatypes/rationalcombobox.cpp
298 src/ui/datatypes/stringcombobox.cpp
299 src/ui/datatypes/stringlabel.cpp
300 src/ui/datatypes/stringled.cpp
301 src/ui/datatypes/thresholdcontrol.cpp
302 src/ui/datatypes/uint64combobox.cpp
303 src/ui/datatypes/uint64label.cpp
304 src/ui/datatypes/uint64rangecombobox.cpp
305 src/ui/datatypes/uint64spinbox.cpp
306 src/ui/devices/channelcombobox.cpp
307 src/ui/devices/channelgroupcombobox.cpp
308 src/ui/devices/configkeycombobox.cpp
309 src/ui/devices/configurablecombobox.cpp
310 src/ui/devices/devicecombobox.cpp
311 src/ui/devices/selectconfigurableform.cpp
312 src/ui/devices/selectpropertyform.cpp
313 src/ui/devices/selectsignalwidget.cpp
314 src/ui/devices/signalcombobox.cpp
315 src/ui/devices/devicetree/devicetreemodel.cpp
316 src/ui/devices/devicetree/devicetreeview.cpp
317 src/ui/devices/devicetree/treeitem.cpp
318 src/ui/dialogs/aboutdialog.cpp
319 src/ui/dialogs/addmathchanneldialog.cpp
320 src/ui/dialogs/adduserchanneldialog.cpp
321 src/ui/dialogs/addviewdialog.cpp
322 src/ui/dialogs/addviewdialog.cpp
323 src/ui/dialogs/connectdialog.cpp
324 src/ui/dialogs/generatewaveformdialog.cpp
325 src/ui/dialogs/plotconfigdialog.cpp
326 src/ui/dialogs/plotcurveconfigdialog.cpp
327 src/ui/dialogs/plotdiffmarkerdialog.cpp
328 src/ui/dialogs/selectsignaldialog.cpp
329 src/ui/dialogs/selectxysignalsdialog.cpp
330 src/ui/dialogs/signalsavedialog.cpp
331 src/ui/tabs/basetab.cpp
332 src/ui/tabs/devicetab.cpp
333 src/ui/tabs/measurementtab.cpp
334 src/ui/tabs/smuscripttab.cpp
335 src/ui/tabs/sourcesinktab.cpp
336 src/ui/tabs/tabdockwidget.cpp
337 src/ui/tabs/tabhelper.cpp
338 src/ui/tabs/usertab.cpp
339 src/ui/tabs/welcometab.cpp
340 src/ui/views/baseplotview.cpp
341 src/ui/views/baseview.cpp
342 src/ui/views/dataview.cpp
343 src/ui/views/devicesview.cpp
344 src/ui/views/democontrolview.cpp
345 src/ui/views/genericcontrolview.cpp
346 src/ui/views/measurementcontrolview.cpp
347 src/ui/views/powerpanelview.cpp
348 src/ui/views/sequenceoutputview.cpp
349 src/ui/views/smuscriptoutputview.cpp
350 src/ui/views/smuscripttreeview.cpp
351 src/ui/views/smuscriptview.cpp
352 src/ui/views/sourcesinkcontrolview.cpp
353 src/ui/views/timeplotview.cpp
354 src/ui/views/valuepanelview.cpp
355 src/ui/views/viewhelper.cpp
356 src/ui/views/xyplotview.cpp
357 src/ui/widgets/clickablelabel.cpp
358 src/ui/widgets/colorbutton.cpp
359 src/ui/widgets/lcddisplay.cpp
360 src/ui/widgets/monofontdisplay.cpp
361 src/ui/widgets/popup.cpp
362 src/ui/widgets/valuedisplay.cpp
363 src/ui/widgets/plot/axislocklabel.cpp
364 src/ui/widgets/plot/axispopup.cpp
365 src/ui/widgets/plot/basecurvedata.cpp
366 src/ui/widgets/plot/curve.cpp
367 src/ui/widgets/plot/plot.cpp
368 src/ui/widgets/plot/plotmagnifier.cpp
369 src/ui/widgets/plot/plotscalepicker.cpp
370 src/ui/widgets/plot/timecurvedata.cpp
371 src/ui/widgets/plot/xycurvedata.cpp
375 list(APPEND smuview_SOURCES signalhandler.cpp)
378 set(smuview_RESOURCES
383 # Use the sigrok icon for the smuview.exe executable.
384 set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_RC_COMPILER} -O coff -I${CMAKE_CURRENT_SOURCE_DIR} <SOURCE> <OBJECT>")
386 list(APPEND smuview_SOURCES smuviewico.rc)
389 qt5_add_resources(smuview_RESOURCES_RCC ${smuview_RESOURCES})
392 #===============================================================================
393 #= Global Definitions
394 #-------------------------------------------------------------------------------
396 add_definitions(-DQT_NO_KEYWORDS)
397 add_definitions(-D__STDC_LIMIT_MACROS)
398 add_definitions(-Wall -Wextra -Woverloaded-virtual -Wdeprecated-declarations) # -Weffc++ -Wconversion -Wsign-conversion)
399 add_definitions(-DBOOST_MATH_DISABLE_FLOAT128=1)
402 add_definitions(-std=c++17)
404 add_definitions(-std=c++11)
407 if(NOT DISABLE_WERROR)
408 #add_definitions(-Werror -pedantic-errors)
409 add_definitions(-Werror=pedantic -pedantic-errors)
413 add_definitions(-DENABLE_SIGNALS)
417 # MXE workaround: Prevents compile error:
418 # mxe-git-x86_64/usr/lib/gcc/x86_64-w64-mingw32.static.posix/5.5.0/include/c++/cmath:1147:11: error: '::hypot' has not been declared
420 # Alternativ solution:
421 # Add "#include <cmath>" before the pybind11 includes in bindings.cpp and smuscriptrunner.cpp
422 add_compile_options(-D_hypot=hypot)
425 if(MINGW AND ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
426 # Fix error "too many sections (37653)" and "file too big" for mingw/MXE when building for Debug
427 add_definitions(-Wa,-mbig-obj)
430 #===============================================================================
431 #= Global Include Directories
432 #-------------------------------------------------------------------------------
435 ${CMAKE_CURRENT_BINARY_DIR}
436 ${CMAKE_CURRENT_SOURCE_DIR}
438 ${Boost_INCLUDE_DIRS}
442 # MXE workaround: Use PkgConfig to find Python
443 include_directories(${PYTHON3_INCLUDE_DIRS})
446 if(STATIC_PKGDEPS_LIBS)
447 include_directories(${PKGDEPS_STATIC_INCLUDE_DIRS})
449 include_directories(${PKGDEPS_INCLUDE_DIRS})
453 #===============================================================================
454 #= Linker Configuration
455 #-------------------------------------------------------------------------------
457 link_directories(${Boost_LIBRARY_DIRS})
459 set(SMUVIEW_LINK_LIBS
463 ${CMAKE_THREAD_LIBS_INIT}
464 #${LIBATOMIC_LIBRARY}
472 # MXE workaround: Use PkgConfig to find Python
473 if(PYTHON3_LINK_LIBRARIES)
474 # Try to use the fully qualified name for cross compiling
475 list(APPEND SMUVIEW_LINK_LIBS ${PYTHON3_LINK_LIBRARIES})
477 list(APPEND SMUVIEW_LINK_LIBS ${PYTHON3_LIBRARIES})
482 # On Windows we need to statically link the libqsvg imageformat
483 # plugin (and the QtSvg component) for SVG graphics/icons to work.
484 # We also need QWindowsIntegrationPlugin, Qt5PlatformSupport, and all
485 # Qt libs and their dependencies.
486 add_definitions(-DQT_STATICPLUGIN)
487 list(APPEND SMUVIEW_LINK_LIBS Qt5::QSvgPlugin)
488 list(APPEND SMUVIEW_LINK_LIBS Qt5::QWindowsIntegrationPlugin)
490 # Form Qt 5.8 on, Qt5PlatformSupport is split into several plugins:
491 # QtAccessibilitySupport QtCliboardSupport QtEventDispatcherSupport
492 # QtFontDatabaseSupport QtGraphicsSupport QtThemeSupport
493 # TODO: Some of the plugins are wrong?
494 if(Qt5Core_VERSION VERSION_LESS "5.8.0")
495 list(APPEND SMUVIEW_LINK_LIBS -lQt5PlatformSupport ${QT5ALL_LDFLAGS})
497 list(APPEND SMUVIEW_LINK_LIBS -lQt5AccessibilitySupport)
498 list(APPEND SMUVIEW_LINK_LIBS -lQt5EventDispatcherSupport)
499 list(APPEND SMUVIEW_LINK_LIBS -lQt5FontDatabaseSupport)
500 list(APPEND SMUVIEW_LINK_LIBS -lQt5ThemeSupport)
501 #list(APPEND SMUVIEW_LINK_LIBS -lQt5ClipboardSupport)
502 #list(APPEND SMUVIEW_LINK_LIBS -lQt5GraphicsSupport)
503 list(APPEND SMUVIEW_LINK_LIBS ${QT5ALL_LDFLAGS})
507 add_executable(${PROJECT_NAME} ${smuview_SOURCES} ${smuview_RESOURCES_RCC})
509 target_link_libraries(${PROJECT_NAME} ${SMUVIEW_LINK_LIBS})
511 if(WIN32 AND NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
512 # Pass -mwindows so that no "DOS box" opens when SmuView is started.
513 set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-mwindows")
517 #===============================================================================
519 #-------------------------------------------------------------------------------
521 # Install the executable.
522 install(TARGETS ${PROJECT_NAME} DESTINATION bin/)
524 # Install the manpage.
525 install(FILES doc/smuview.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT doc)
527 # Install the desktop file.
528 install(FILES contrib/org.sigrok.SmuView.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
530 # Install the AppData/AppStream file.
531 install(FILES contrib/org.sigrok.SmuView.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo)
533 # Install the SmuView icons.
534 install(FILES icons/smuview.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps)
535 install(FILES icons/smuview.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps)
537 # Install the SmuScript examples.
538 install(DIRECTORY smuscript/ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/smuscript)
540 # Generate Windows installer script.
541 configure_file(contrib/smuview_cross.nsi.in ${CMAKE_CURRENT_BINARY_DIR}/contrib/smuview_cross.nsi @ONLY)
544 #===============================================================================
546 #-------------------------------------------------------------------------------
548 add_subdirectory(manual)
551 #===============================================================================
552 #= Packaging (handled by CPack)
553 #-------------------------------------------------------------------------------
556 #===============================================================================
558 #-------------------------------------------------------------------------------