-
Notifications
You must be signed in to change notification settings - Fork 156
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
387 lines (334 loc) · 16.2 KB
/
CMakeLists.txt
File metadata and controls
387 lines (334 loc) · 16.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
cmake_minimum_required(VERSION 3.20)
project(ngscopeclient VERSION 0.1)
include_directories(cmake) #WORKAROUND needed for find_package(Vulkan) for Vulkan SDK
enable_language(CXX)
# Warn if platform is not 64-bit
if(NOT (CMAKE_SIZEOF_VOID_P EQUAL 8))
message(WARNING "You are attempting to build on a 32-bit platform. While this may work and we may accept fixes "
"upstream, it will most likely fail and is unsupported.")
endif()
# Check for Vulkan SDK env var and prepend it to CMAKE_PREFIX_PATH if set to prefer Vulkan SDK packages if available
if(DEFINED ENV{VULKAN_SDK})
#WORKAROUND: Vulkan SDK is incompatible with MinGW due to C++ linkage
if(WIN32 AND (NOT CMAKE_GENERATOR MATCHES "Visual Studio"))
message(WARNING "Detected VULKAN_SDK at $ENV{VULKAN_SDK}.")
message(WARNING "Compiling and linking against the Vulkan SDK is not supported with MSYS. The build system "
"will ignore the SDK and you will need to have the Vulkan packages installed from the MSYS repositories.")
else()
message("Detected and using VULKAN_SDK at $ENV{VULKAN_SDK}")
cmake_path(CONVERT "$ENV{VULKAN_SDK}" TO_CMAKE_PATH_LIST VULKAN_SDK_PATH NORMALIZE)
list(PREPEND CMAKE_PREFIX_PATH ${VULKAN_SDK_PATH})
endif()
endif()
# Git is used for git-describe based version generation if we have it
find_package(Git)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/release-info.cmake")
message("Release-info file is present")
include("${CMAKE_CURRENT_SOURCE_DIR}/release-info.cmake")
endif ()
#Set up versioning (with a dummy string for now if Git isn't present)
if(Git_FOUND OR NGSCOPECLIENT_PACKAGE_VERSION)
if(NOT NGSCOPECLIENT_PACKAGE_VERSION)
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --always --tags
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE NGSCOPECLIENT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
message("Git reports scopehal-apps version ${NGSCOPECLIENT_VERSION}")
else ()
set(NGSCOPECLIENT_VERSION "${NGSCOPECLIENT_PACKAGE_VERSION}")
message("External release version is ${NGSCOPECLIENT_VERSION}")
endif ()
if(NOT NGSCOPECLIENT_PACKAGE_VERSION_LONG)
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --always --tags --long
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE NGSCOPECLIENT_VERSION_LONG
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
set(NGSCOPECLIENT_VERSION_LONG "${NGSCOPECLIENT_PACKAGE_VERSION_LONG}")
message("External long release version is ${NGSCOPECLIENT_VERSION_LONG}")
endif ()
# For point releases make MSI version 10x+9. This limits us to 9 release candidates which should be ok??
# ex: 0.1.2-rc2 is 0.1.22
# ex: 0.1.2 is 0.1.29
# Ugly string parsing to make windows build happy
# First path: release candidate tags for primary releases
if(NGSCOPECLIENT_VERSION_LONG MATCHES "v([0-9]*).([0-9]*)-rc([0-9])-([0-9]*)")
set(MSI_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}.${CMAKE_MATCH_4}")
# Release candidates for point releases
elseif(NGSCOPECLIENT_VERSION_LONG MATCHES "v([0-9]*).([0-9]*).([0-9]*)-rc([0-9])-([0-9]*)")
set(MSI_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}${CMAKE_MATCH_4}.${CMAKE_MATCH_5}")
# Release tags
elseif(NGSCOPECLIENT_VERSION_LONG MATCHES "v([0-9]*).([0-9]*)-([0-9]*)")
set(MSI_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.9.${CMAKE_MATCH_3}")
# Release tags for point releases
elseif(NGSCOPECLIENT_VERSION_LONG MATCHES "v([0-9]*).([0-9]*).([0-9]*)-([0-9]*)")
set(MSI_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}9.${CMAKE_MATCH_4}")
# No release matched
else()
message(FATAL_ERROR "Unrecognized version tag ${NGSCOPECLIENT_VERSION} / ${NGSCOPECLIENT_VERSION_LONG}, can't create a VERSIONINFO from it. Must be of format v1.2, v1.2.3, v1.2-rc3, v1.2.3-rc4")
endif()
else()
set(NGSCOPECLIENT_VERSION "unknown")
set(MSI_VERSION "0.1")
message("Git not detected, scopehal-apps version unknown")
endif()
set(PROJECT_VERSION "${NGSCOPECLIENT_VERSION}")
include(CTest)
# Configuration settings
set(BUILD_DOCS CACHE BOOL "Build end user documentation")
set(BUILD_DEVDOCS CACHE BOOL "Build developer documentation")
set(ANALYZE CACHE BOOL "Run static analysis on the code, requires cppcheck and clang-analyzer to be installed")
set(DISABLE_PCH CACHE BOOL "Disable precompiled headers as this may break certain configurations")
set(BUILD_TESTING CACHE BOOL "Build unit tests")
# Build with C++ 17 on Linux for maximum compatibility with older system
# but for Windows, enable C++ 20 to bypass a deprecation warning
# (workaround for https://github.com/KhronosGroup/Vulkan-Hpp/issues/2034)
# even though we do not yet use any C++ 20 features in our codebase
if(WIN32)
set(CMAKE_CXX_STANDARD 20)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wno-error=c2y-extensions)
endif()
else()
set(CMAKE_CXX_STANDARD 17)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON) # error if compiler doesn't support c++17
set(CMAKE_CXX_EXTENSIONS OFF) # use c++17 instead of gnu++17
# PCH needs to be disabled before targets are created/added/PCH is added to them
if(DISABLE_PCH)
set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
endif()
# Compiler warnings for GCC/Clang
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wuninitialized)
add_compile_options(-Wshadow -Wpedantic -Wcast-align -Wwrite-strings)
add_compile_options(-Wmissing-declarations -Wvla)
add_compile_options(-Werror -Wno-error=deprecated-declarations -Wno-error=unused-parameter -Wno-error=unused-variable -Wno-error=unused-result -Wno-error=shadow)
endif()
# Compiler warnings specific to GCC or Clang
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13)
add_compile_options(-Woverloaded-virtual=1)
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Woverloaded-virtual -Wpointer-sign -Wno-gnu-zero-variadic-macro-arguments -Wno-unknown-warning-option)
endif()
add_compile_options(-mtune=native)
add_compile_options("$<$<CONFIG:RELEASE>:-O3>")
add_compile_options("$<$<CONFIG:RELWITHDEBINFO>:-O3;-g>")
add_compile_options("$<$<CONFIG:DEBUG>:-Og;-D_DEBUG;-g>")
add_compile_options("$<$<CONFIG:DEBUGNOOPT>:-O0;-D_DEBUG;-g>")
# Needed for %zu/%zd on MSYS2, must be added here to avoid redefinition
if(WIN32 AND (NOT MSVC))
add_compile_definitions(__USE_MINGW_ANSI_STDIO=1)
endif()
# Default build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
if(SANITIZE)
add_compile_options(-fsanitize=address -fsanitize=undefined)
add_link_options(-fsanitize=address -fsanitize=undefined)
endif()
if(WIN32)
add_compile_options(-D_USE_MATH_DEFINES -D_POSIX_THREAD_SAFE_FUNCTIONS)
endif()
# Package detection
find_package(PkgConfig MODULE REQUIRED)
# yaml-cpp is used in scopehal and ngscopeclient
find_package(yaml-cpp REQUIRED)
#WORKAROUND Needed for Debian Bullseye, which does not provide a yaml-cpp::yaml-cpp target
if(NOT TARGET yaml-cpp::yaml-cpp)
find_library(YAML_CPP_LIBRARIES_FILES NAMES ${YAML_CPP_LIBRARIES})
if(YAML_CPP_LIBRARIES_FILES MATCHES ".so$")
add_library(yaml-cpp::yaml-cpp SHARED IMPORTED)
elseif(YAML_CPP_LIBRARIES_FILES MATCHES ".a$")
add_library(yaml-cpp::yaml-cpp STATIC IMPORTED)
else()
message(FATAL_ERROR "Unexpected partially-installed yaml-cpp, is it installed correctly?")
endif()
set_property(TARGET yaml-cpp::yaml-cpp PROPERTY IMPORTED_LOCATION ${YAML_CPP_LIBRARIES_FILES})
#WORKAROUND The cmake file for yaml-cpp on debian bullseye is broken and provides a wrong YAML_CPP_INCLUDE_DIR
find_path(YAML_CPP_INCLUDEFILES_DIR yaml-cpp/yaml.h REQUIRED)
cmake_path(GET YAML_CPP_INCLUDEFILES_DIR PARENT_PATH YAML_CPP_INCLUDE_DIR)
set_property(TARGET yaml-cpp::yaml-cpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${YAML_CPP_INCLUDEFILES_DIR})
endif()
pkg_check_modules(SIGCXX QUIET IMPORTED_TARGET sigc++-3.0) # look for latest version first
if(NOT SIGCXX_FOUND)
pkg_check_modules(SIGCXX QUIET IMPORTED_TARGET sigc++-2.0) # look for older version too
endif()
if(NOT SIGCXX_FOUND)
message(FATAL_ERROR "Unable to find any version of sigc++; this is required to build ngscopeclient.")
endif()
# Check if the user has provided a path for nvtx3 (not autodetected currently)
include(CheckIncludeFileCXX)
if(NVTX_PATH)
check_include_file_cxx("${NVTX_PATH}/include/nvtx3/nvtx3.hpp" NVTX_FOUND)
if(NVTX_FOUND)
message("-- Found NVIDIA NVTX3: ${NVTX_PATH}")
include_directories("${NVTX_PATH}/include")
add_compile_definitions(HAVE_NVTX=1)
endif()
endif()
# We still use gtk on Linux for the file browser dialog in "native" mode)
if(LINUX)
pkg_check_modules(GTK QUIET IMPORTED_TARGET REQUIRED gtk+-3.0)
pkg_search_module(WAYLAND_CLIENT wayland-client IMPORTED_TARGET GLOBAL REQUIRED)
endif()
#WORKAROUND Fedora 38 does not include Threads from the glslang .cmake file, fixed in Fedora 39+
find_package(Threads MODULE REQUIRED)
# Configure and enable OpenMP
find_package(OpenMP MODULE)
if(NOT OpenMP_CXX_FOUND)
message(FATAL_ERROR "ngscopeclient requires OpenMP but your C++ compiler does not appear to support it.")
endif()
# GLFW is required
find_package(glfw3 3.2 REQUIRED)
# Find Vulkan-related packages
#WORKAROUND glslang does not look for SPIRV-Tools-opt but needs it on macOS, harmless elsewhere
find_package(SPIRV-Tools-opt REQUIRED)
if(DEFINED VULKAN_SDK_PATH)
#WORKAROUND The Vulkan SDK ships incomplete cmake config files.
# Work around this, which does require FindVulkan.cmake.
# FindVulkan does not find glslang correctly on macOS
find_package(Vulkan REQUIRED COMPONENTS glslc shaderc_combined SPIRV-Tools)
find_package(glslang REQUIRED)
add_library(Vulkan::Loader ALIAS Vulkan::Vulkan)
else()
find_package(glslang REQUIRED)
find_package(VulkanHeaders REQUIRED)
find_package(VulkanLoader QUIET)
if(NOT VulkanLoader_FOUND) #WORKAROUND Alpine Linux has missing cmake files for VulkanLoader
find_library(VulkanLoader_LIB libvulkan.so REQUIRED)
cmake_path(GET VulkanLoader_LIB FILENAME VulkanLoader_LIB_NAME)
add_library(Vulkan::Loader SHARED IMPORTED)
set_property(TARGET Vulkan::Loader PROPERTY IMPORTED_LOCATION ${VulkanLoader_LIB})
endif()
endif()
# The following should work regardless of Vulkan SDK or individual components
# shaderc does not provide a .cmake file, but does provide a pkgconfig file
# pkgconfig file is not provided by Vulkan SDK, however
pkg_check_modules(SHADERC shaderc QUIET IMPORTED_TARGET)
# This is needed due to shaderc not providing a programmatic way to derive the path of the glslc executable
if(SHADERC_FOUND)
cmake_path(GET SHADERC_INCLUDE_DIRS PARENT_PATH SHADERC_PREFIX)
endif()
# This should find glslc from either shaderc or the Vulkan SDK
find_program(Vulkan_GLSLC_EXECUTABLE glslc HINTS SHADERC_PREFIX)
if(NOT Vulkan_GLSLC_EXECUTABLE)
message(FATAL_ERROR "glslc not found. This is needed to compile shaders. Please install shaderc or load the Vulkan SDK.")
else()
message("-- Found glslc: ${Vulkan_GLSLC_EXECUTABLE}")
endif()
# This is needed due to VkFFT not using a standard path for glslang_c_interface.h
get_target_property(glslang_INCLUDE_DIR glslang::glslang INTERFACE_INCLUDE_DIRECTORIES)
# Find MoltenVK on macOS, no need to link it later
if(APPLE)
find_library(MOLTENVK_LIBRARIES NAMES MoltenVK libMoltenVK)
if( NOT MOLTENVK_LIBRARIES )
message( FATAL_ERROR "scopehal-apps requires MoltenVK to be installed in order to function on macOS.")
endif()
endif()
if(NOT WIN32)
include(GNUInstallDirs)
endif()
# Documentation
add_subdirectory("${PROJECT_SOURCE_DIR}/doc")
if(NOT BUILD_DOCS)
set_property(TARGET doc PROPERTY EXCLUDE_FROM_ALL ON)
endif()
# Static analysis
if(ANALYZE)
find_program(CPPCHECK_PATH cppcheck DOC "Path to cppcheck when ANALYZE is enabled")
if(CPPCHECK_PATH)
execute_process(COMMAND ${CPPCHECK_PATH} "--version" OUTPUT_VARIABLE CPPCHECK_VER_STR ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE "Cppcheck " "" CPPCHECK_VERSION ${CPPCHECK_VER_STR})
if(CPPCHECK_VERSION VERSION_GREATER_EQUAL "2")
set(CMAKE_CXX_CPPCHECK "${CPPCHECK_PATH};-DFT_USE_AUTOCONF_SIZEOF_TYPES;-D__GNUC__;--enable=warning,performance,portability;--suppress=*:*sigc*;--suppress=*:*glibmm*;--suppress=*:*gtkmm*;--inline-suppr;-q;--std=c++11")
message(STATUS "Found CPPCheck: ${CPPCHECK_PATH} (found version \"${CPPCHECK_VERSION}\")")
else()
message(STATUS "Found CPPCheck: ${CPPCHECK_PATH} but ignored it as it was ${CPPCHECK_VERSION} < 2")
endif()
else()
message(FATAL_ERROR "CPPCheck not found, required for ANALYZE")
endif()
# The actual clang-analyzer compiler wrapper doesn't get installed on $PATH, only scan-build which is useless to us
find_program(CLANGANALYZER_SCANBUILD_PATH scan-build DOC "Path to clang-analyzer's scan-build tool, used as a hint to find the rest of the clang-analyzer")
get_filename_component(CLANGANALYZER_SCANBUILD_BIN ${CLANGANALYZER_SCANBUILD_PATH} REALPATH)
get_filename_component(CLANGANALYZER_BIN_PATH ${CLANGANALYZER_SCANBUILD_BIN} DIRECTORY)
find_program(CLANGANALYZER_CXXANALYZER_PATH "c++-analyzer" HINTS "${CLANGANALYZER_BIN_PATH}/../libexec" DOC "Path to clang-analyzer's c++-analyzer")
if(CLANGANALYZER_CXXANALYZER_PATH)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CLANGANALYZER_CXXANALYZER_PATH}")
message(STATUS "Found clang-analyzer: ${CLANGANALYZER_CXXANALYZER_PATH}")
else()
message(FATAL_ERROR "clang-analyzer not found, required for ANALYZE")
endif()
endif()
# Main project code
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/scopehal")
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/scopeprotocols")
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/xptools")
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/log")
add_subdirectory("${PROJECT_SOURCE_DIR}/src/ngscopeclient")
add_subdirectory("${PROJECT_SOURCE_DIR}/src/nativefiledialog-extended")
add_subdirectory(devdoc)
# Unit tests
if(Git_FOUND AND BUILD_TESTING)
find_package(Catch2 REQUIRED)
include(Catch)
#Catch2 v3.x.y have a breaking change:
# Must include catch2/catch_all.hpp instead of catch2/catch.hpp
# So we set a compile flag to let the code know.
if(NOT Catch2_VERSION MATCHES "^[0-2]\\.")
add_compile_options(-D_CATCH2_V3)
endif()
add_subdirectory("${PROJECT_SOURCE_DIR}/tests")
endif()
# Example code and other utilities, don't build on non-POSIX yet
if(NOT WIN32)
add_subdirectory("${PROJECT_SOURCE_DIR}/src/examples/curvetrace")
#add_subdirectory("${PROJECT_SOURCE_DIR}/src/examples/usbcsv")
endif()
# Make sure all of our shared libraries are built relocatable
set_property(TARGET scopehal PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET log PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET xptools PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET scopeprotocols PROPERTY POSITION_INDEPENDENT_CODE ON)
# CPack package generation
set(CPACK_PACKAGE_NAME "ngscopeclient")
set(CPACK_PACKAGE_VENDOR "ngscopeclient.org project")
set(CPACK_PACKAGE_VERSION_PATCH "0+${NGSCOPECLIENT_VERSION}")
set(CPACK_PACKAGE_DESCRIPTION "Cross platform T&M remote control and signal analysis suite")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://www.ngscopeclient.org/")
set(CPACK_THREADS 0)
set(CPACK_STRIP_FILES TRUE)
# Figure out what distro version we're on
if(LINUX)
find_program(LSB_RELEASE_EXEC lsb_release REQUIRED)
execute_process(COMMAND ${LSB_RELEASE_EXEC} -is
OUTPUT_VARIABLE DISTRO_NAME
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY)
execute_process(COMMAND ${LSB_RELEASE_EXEC} -rs
OUTPUT_VARIABLE DISTRO_VER
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY)
message(STATUS "Linux distribution target for packaging: name ${DISTRO_NAME}, version ${DISTRO_VER}")
# Debian specific packaging config
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Andrew Zonenberg <andrew.zonenberg@antikernel.net>")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
endif()
if(APPLE)
set(CPACK_BUNDLE "ON")
set(CPACK_BUNDLE_PLIST "${PROJECT_SOURCE_DIR}/src/ngscopeclient/macos/Info.plist")
# Must be generated with:
# iconutil -c icns ngscopeclient.iconset
set(CPACK_BUNDLE_ICON "${PROJECT_SOURCE_DIR}/src/ngscopeclient/icons/macos/ngscopeclient.icns")
set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/src/ngscopeclient/icons/macos/ngscopeclient.icns")
set(CPACK_BUNDLE_NAME "ngscopeclient")
set(CPACK_BUNDLE_STARTUP_COMMAND "${PROJECT_SOURCE_DIR}/src/ngscopeclient/macos/ngscopeclient.sh")
set_target_properties(ngscopeclient PROPERTIES
INSTALL_RPATH "@executable_path/../lib;/usr/local/lib;/opt/homebrew/lib")
endif()
# this must be at the very end *after* we've done all the config
include(CPack)