forked from jeeb/avisynth
-
Notifications
You must be signed in to change notification settings - Fork 88
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
613 lines (531 loc) · 29.6 KB
/
CMakeLists.txt
File metadata and controls
613 lines (531 loc) · 29.6 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
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
# Tested generators:
# Command line makefile generator
# "MinGW Makefiles": MSYS2/Mingw32 GCC 8.3, 10.3 build
# IDE project file generators
# "Visual Studio 15 2017" optional platform generator Win32 and x64
# "Visual Studio 16 2019" optional platform generator Win32 and x64. optional toolset "v141_xp"
# "Visual Studio 17 2022" optional platform generator Win32 and x64. optional toolset "v141_xp" or "clangcl"
# "Visual Studio 18 2026" optional platform generator Win32 and x64. optional toolset "v141_xp" or "clangcl"
# Intel C++ Compilers
# Minimum Cmake version for Intel C++ Compiler 2023: 3.22.3 (Win) 3.20 (Linux)
# Howto: https://www.intel.com/content/www/us/en/developer/articles/technical/using-oneapi-compilers-with-cmake-in-visual-studio.html
# "Intel(R) oneAPI DPC++ Compiler", two flavours. DPCPP is not compatible with Avisynth.
# - Intel® NextGen Compiler (in base kit, LLVM based): TOOLSET = "Intel C++ Compiler 2023", COMPILER EXE NAME = icx.exe
# - Intel® Classic Compiler (in extra HPC kit): TOOLSET = "Intel C++ Compiler 19.2", COMPILER EXE NAME = icl.exe
# CMake support files.
# - Info from: c:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\IntelDPCPP\ReadMe.txt
# - copy c:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\IntelDPCPP\IntelDPCPPConfig.cmake to c:\Program Files\CMake\share\cmake-3.20\Modules\
# CMake GUI:
# - Generator: "Visual Studio 17 2022"
# - Optional toolset to use (-T option):
# For LLVM based icx: Intel C++ Compiler 2023 (or earlier 2022, 2021)
# For classic icl: Intel C++ Compiler 19.2
# - Specify native compilers: browse for the appropriate compiler executable path.
# icx: C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\bin\icx.exe
# icl: C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\bin\intel64\icl.exe
# If you have errors like "xilink: : error : Assertion failed (shared/driver/drvutils.c, line 312" then
# as a workaround you must copy clang.exe (by default it is located in C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\bin)
# to the folder beside xilink (for x64 configuration it is in C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\bin\intel64).
# Successful log looks like:
# The CXX compiler identification is IntelLLVM 2023.0.0 with MSVC-like command-line
# Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2023.0.0/windows/bin/icx.exe - skipped
# or
# The CXX compiler identification is IntelLLVM 2021.4.0 with MSVC-like command-line
# Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2021.4.0/windows/bin/icx.exe
# or
# The CXX compiler identification is Intel 2021.4.0.20210910
# Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2021.4.0/windows/bin/intel64/icl.exe
#
# command line:
# run "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" to configure the environment
# cmake -T "Intel C++ Compiler 2023" -DCMAKE_CXX_COMPILER="icx.exe" ../
# or
# cmake -T "Intel C++ Compiler 19.2" -DCMAKE_CXX_COMPILER="icl.exe" ../
# "Visual Studio 16 2019" + LLVM 8.0 (clang) optional platform generator Win32 and x64
CMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )
# VS2019: 3.14.1
# Intel 2023: 3.22.3 (Win) 3.20 (Linux)
# VS2022: 3.21
# VS2026: 4.2
# Get PROJECT_VERSION property from 'avs_core/core/version.h.in'
file(READ "avs_core/core/version.h.in" versioning)
string(REGEX MATCH "AVS_MAJOR_VER[ \\t]+([0-9]*)" _ ${versioning})
set(version_major ${CMAKE_MATCH_1})
string(REGEX MATCH "AVS_MINOR_VER[ \\t]+([0-9]*)" _ ${versioning})
set(version_minor ${CMAKE_MATCH_1})
string(REGEX MATCH "AVS_BUGFIX_VER[ \\t]+([0-9]*)" _ ${versioning})
set(version_bugfix ${CMAKE_MATCH_1})
# Combine version variables for use in the project command
set(PROJECT_VERSION_STRING "${version_major}.${version_minor}.${version_bugfix}")
# Get AVISYNTH_INTERFACE_VERSION from avs_core/include/avisynth.h
file(READ "avs_core/include/avisynth.h" versioning)
string(REGEX MATCH "AVISYNTH_INTERFACE_VERSION = ([0-9]*)" _ ${versioning})
set(AVISYNTH_INTERFACE_VERSION ${CMAKE_MATCH_1})
option(BUILD_SHARED_LIBS "Build shared libraries instead of static ones." ON)
if(NOT ${BUILD_SHARED_LIBS})
message(WARNING "You must satisfy the conditions of the GPL license when linking against the AviSynth library.")
endif()
option(HEADERS_ONLY "Install only the Headers" ${INSTALL_ONLY_HEADER})
if(${INSTALL_ONLY_HEADER})
set(INSTALL_ONLY_HEADER OFF)
endif()
if(NOT HEADERS_ONLY)
project("AviSynth+" VERSION ${PROJECT_VERSION_STRING} LANGUAGES CXX)
# message("Compiler ID: ${CMAKE_CXX_COMPILER_ID} ")
include(GNUInstallDirs)
# Avoid uselessly linking to unused libraries
set(CMAKE_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
set(CMAKE_C_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
# We require C++17 or higher.
if(CMAKE_VERSION VERSION_GREATER 3.7)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_EXTENSIONS FALSE)
endif()
# Detect Intel processors and turn Intel SIMD on or off automatically.
# Detect AArch64 processors and turn AArch64 NEON SIMD on or off automatically.
# Old logic relied on the host processor: ${CMAKE_SYSTEM_PROCESSOR}
set(INTEL_SIMD "OFF")
set(NEON_SIMD "OFF")
# Use a list of known Intel-compatible/aarch64 architecture names for the default ON state.
set(INTEL_ARCH_NAMES "win32" "x64" "x86" "i386" "amd64" "x86_64" "i686")
set(ARM_ARCH_NAMES "arm64" "aarch64")
# Check the TARGET architecture using the most reliable variables (CMAKE_GENERATOR_PLATFORM and PLATFORMID_LOWER)
string(TOLOWER "${PLATFORMID}" PLATFORMID_LOWER)
string(TOLOWER "${CMAKE_GENERATOR_PLATFORM}" GEN_PLATFORM_LOWER) # Often holds x64, ARM64, etc.
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" HOST_ARCH_LOWER) # ninja with ative aarch64 gcc: probably only this exists
# --- DEBUG OUTPUT START ---
# message(STATUS "--- SIMD Detection Variables ---")
# message(STATUS "CMAKE_SYSTEM_PROCESSOR (Host Arch): ${CMAKE_SYSTEM_PROCESSOR}")
# message(STATUS "Host Arch Lower: ${HOST_ARCH_LOWER}")
# message(STATUS "PLATFORMID_LOWER (VS Target Platform): ${PLATFORMID_LOWER}")
# message(STATUS "CMAKE_GENERATOR_PLATFORM (Generator Target): ${CMAKE_GENERATOR_PLATFORM}")
# message(STATUS "INTEL_ARCH_NAMES: ${INTEL_ARCH_NAMES}")
# message(STATUS "------------------------------------")
# --- DEBUG OUTPUT END ---
# e.g. ARM64 cross-compile on x64 machine:
# CMAKE_SYSTEM_PROCESSOR (Host Arch): AMD64
# Host Arch Lower: amd64
# PLATFORMID_LOWER (VS Target Platform):
# CMAKE_GENERATOR_PLATFORM (Generator Target): ARM64
# check aarch64 variants
list(FIND ARM_ARCH_NAMES "${HOST_ARCH_LOWER}" _found_arm_host) # New check
list(FIND ARM_ARCH_NAMES "${PLATFORMID_LOWER}" _found_arm_platform_id)
list(FIND ARM_ARCH_NAMES "${GEN_PLATFORM_LOWER}" _found_arm_gen)
# check intel variants
list(FIND INTEL_ARCH_NAMES "${HOST_ARCH_LOWER}" _found_arch)
list(FIND INTEL_ARCH_NAMES "${PLATFORMID_LOWER}" _found_target_platform_id)
list(FIND INTEL_ARCH_NAMES "${GEN_PLATFORM_LOWER}" _found_target_gen)
# 1. Check if the target platform is explicitly known non-Intel (ARM64, AARCH64)
if(_found_arm_platform_id GREATER -1 OR _found_arm_gen GREATER -1 OR _found_arm_host GREATER -1)
set(INTEL_SIMD "OFF")
set(NEON_SIMD "ON")
message(STATUS "Target is aarch64, turn NEON_SIMD ON.")
else()
# 2. Inclusion Check: We are NOT targeting ARM64.
# Define a boolean check: Did we find a match in the explicit target variables OR the host architecture?
if(_found_target_gen GREATER -1 OR _found_target_platform_id GREATER -1)
# Found a match in a generator-set variable (e.g., Win32, x64 when explicitly chosen)
set(INTEL_SIMD "ON")
message(STATUS "Target architecture is explicitly set and Intel-compatible, INTEL_SIMD set ON.")
elseif(_found_arch GREATER -1 AND "${GEN_PLATFORM_LOWER}" STREQUAL "")
# FALLBACK: Target platform is NOT set (Default Configuration), but the Host is Intel-compatible.
# The default target platform for a multi-config generator on a bare x64 host is x64.
set(INTEL_SIMD "ON")
message(STATUS "Target platform not specified; defaulting to Host (${CMAKE_SYSTEM_PROCESSOR}), INTEL_SIMD set ON.")
endif()
endif()
# message(STATUS "Final INTEL_SIMD initial assumption: ${INTEL_SIMD}")
option(ENABLE_INTEL_SIMD "Enable SIMD intrinsics for Intel processors" "${INTEL_SIMD}")
option(ENABLE_NEON_SIMD "Enable SIMD intrinsics for AArch64 processors" "${NEON_SIMD}")
option(ENABLE_PLUGINS "Build set of default external plugins" ON)
set(USER_AVS_PLUGINDIR_LOCATION ".local/lib/avisynth" CACHE STRING "Override path for user-local plugins, with $HOME omitted (default: .local/lib/avisynth)")
option(ENABLE_CUDA "Enable CUDA support" OFF)
set(CORE_PLUGIN_INSTALL_PATH "${CMAKE_INSTALL_FULL_LIBDIR}" CACHE STRING "Set system plugin install parent directory (default: value of CMAKE_INSTALL_FULL_LIBDIR)")
if(CMAKE_VERSION VERSION_GREATER 3.9)
get_cmake_property(MULTI_CONFIG GENERATOR_IS_MULTI_CONFIG)
if(MULTI_CONFIG)
if(CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES Debug Release RelWithDebInfo)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "Reset the configurations to what we need" FORCE)
endif()
message("-- Build type: Multi-configuration (${CMAKE_CONFIGURATION_TYPES})")
else()
# When CMAKE_BUILD_TYPE is not defined, CMake defaults to a simple -O0 configuration, no compiler optimizations
# and no debug symbols. For single-configuration generators (Makefiles, Ninja, etc.) we can make Release the
# assumed default if it isn't explicitly set by the user. Multi-config generators like Visual Studio ignore
# CMAKE_BUILD_TYPE.
# Unfortunately, this is not visible in CMakeCache, but it can be seen to take effect in build.ninja or running
# make with VERBOSE=1 adding the appropriate Release flags.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
message("-- Build type: ${CMAKE_BUILD_TYPE}")
endif()
endif()
# Use this one to be safe:
# Check for the Visual Studio generator OR the MSVC compiler/toolchain on Windows
# (which includes Ninja with cl.exe).
# We use the MSVC variable to ensure the configuration block runs when cl.exe is detected.
if( CMAKE_GENERATOR MATCHES "Visual Studio" OR (MSVC AND WIN32) )
## IF( MSVC ) # Check for Visual Studio
#1910-1919 = VS 15.0 (v141 toolset) Visual Studio 2017
#1920-1929 = VS 16.0 (v142 toolset) Visual Studio 2019
#1930-1949 = VS 17.x (v143 toolset) Visual Studio 2022
# ( 1940-1949 = VS v17.10+: Toolset v143 (Still!) | Compiler 19.4x)
#1950-1959 = VS 18.0 (v145 toolset) Visual Studio 2026
# --- Determine MSVC target platform, Ninja makes a bit more work for us
# Since CMAKE_VS_PLATFORM_NAME is empty, only valid for Visual Studio generators.
# Detect the target platform based on the most reliable variables for MSVC/Ninja:
# 1. start with the VS Generator's specific variable. If it's not set, it will be empty.
set(TARGET_PLATFORM_TO_CHECK "${CMAKE_VS_PLATFORM_NAME}")
# message(STATUS "DEBUG: CMAKE_VS_PLATFORM_NAME = '${CMAKE_VS_PLATFORM_NAME}'")
# message(STATUS "DEBUG: CMAKE_GENERATOR_PLATFORM = '${CMAKE_GENERATOR_PLATFORM}'")
# message(STATUS "DEBUG: CMAKE_SIZEOF_VOID_P = '${CMAKE_SIZEOF_VOID_P}'")
# 2. If CMAKE_VS_PLATFORM_NAME is empty (e.g., Ninja generator), try to infer from pointer size.
if(NOT TARGET_PLATFORM_TO_CHECK)
# 3. Check the pointer size (most reliable indicator for x64/Win32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
# 64-bit target
set(TARGET_PLATFORM_TO_CHECK "x64")
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
# 32-bit target
set(TARGET_PLATFORM_TO_CHECK "Win32")
endif()
endif()
# 4. final attempt: If CMAKE_GENERATOR_PLATFORM has a value and TARGET_PLATFORM_TO_CHECK is still empty
if(NOT TARGET_PLATFORM_TO_CHECK AND CMAKE_GENERATOR_PLATFORM)
set(TARGET_PLATFORM_TO_CHECK "${CMAKE_GENERATOR_PLATFORM}")
endif()
# detect if the target is for x86
# PLATFORMID_LOWER is just a lowercase copy of CMAKE_VS_PLATFORM_NAME
string(TOLOWER "${TARGET_PLATFORM_TO_CHECK}" PLATFORMID_LOWER)
# message("-- PLATFORMID_LOWER: ${PLATFORMID_LOWER}")
if(("${PLATFORMID_LOWER}" STREQUAL "win32") OR
("${PLATFORMID_LOWER}" STREQUAL "x64") OR
("${PLATFORMID_LOWER}" STREQUAL "arm64")) # allow arm64 targets
set(SUPPORTED_MSVC_PLATFORM "ON")
else()
set(SUPPORTED_MSVC_PLATFORM "OFF")
endif()
if(SUPPORTED_MSVC_PLATFORM STREQUAL "OFF")
message(FATAL_ERROR "MSVC/ClangCL only supported on Win32, x64, or ARM64 targets. Use MinGW (llvm-mingw or gcc). Unsupported target: ${CMAKE_VS_PLATFORM_NAME}.")
endif()
#[[
# check to disable ARM64 by default
# PF: re-allowed; VS2026 can build ARM64 even with LLVM
if(("${PLATFORMID_LOWER}" STREQUAL "arm64") AND (NOT DEFINED ENABLE_ARM64_WITH_MSVC_TESTING))
# This FATAL_ERROR can be commented out or protected by the ENABLE_ARM64_TESTING cache variable.
# To enable the build, define -DENABLE_ARM64_TESTING=ON when running cmake.
message(FATAL_ERROR "MSVC ARM64 platform is currently disabled by default. Define ENABLE_ARM64_WITH_MSVC_TESTING=ON to proceed or use MinGW (llvm-mingw or gcc).")
endif()
#]]
IF( MSVC_VERSION VERSION_LESS 1910 )
MESSAGE(FATAL_ERROR "Visual C++ 2017 or newer required.")
ENDIF()
# Milestones
# C++17 COMPLETENESS: Compiler versions 19.10-19.19 (VS 2017) had incomplete C++17 support.
# Full C++17 support: starting with compiler version 19.20 (VS 2019 RTM).
# C++20 COMPLETENESS: Compiler version 19.29 (VS 2019 v16.10+): full C++20 standard library support.
# VS 2022 (v19.30+) is generally recommended for best C++20 stability and language feature compliance.
# Damn XP support prevents defining a minimum.
# When v141_xp toolset is used, MSVC_VERSION is 1916
# So we temporarily inactivate the minimum version check:
IF(FALSE)
IF( MSVC_VERSION VERSION_LESS 1929 )
message("--MSVC_VERSION is (${MSVC_VERSION})")
MESSAGE(FATAL_ERROR "Visual C++ 2019 (v16.10+) or newer is required for C++20 support. Recommended: Visual Studio 2022.")
ENDIF()
ENDIF()
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/Output/plugins")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/Output/system")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/Output/c_api")
IF(MSVC_IDE)
message("MSVC_IDE support found, reported CMAKE_GENERATOR_TOOLSET is: ${CMAKE_GENERATOR_TOOLSET}")
string( TOLOWER "${CMAKE_GENERATOR_TOOLSET}" cmake_gentoolset_lower)
IF(cmake_gentoolset_lower STREQUAL "intel c++ compiler 2021" OR
cmake_gentoolset_lower STREQUAL "intel c++ compiler 2022" OR
cmake_gentoolset_lower STREQUAL "intel c++ compiler 2023" OR
cmake_gentoolset_lower STREQUAL "intel c++ compiler 2024" OR
cmake_gentoolset_lower STREQUAL "intel c++ compiler 2025" OR
cmake_gentoolset_lower STREQUAL "intel c++ compiler 2026"
)
# IntelLLVM
set(IntelLLVM_IN_VS "1")
ELSEIF(cmake_gentoolset_lower STREQUAL "intel c++ compiler 19.2")
# Intel Classic
set(IntelClassic_IN_VS "1")
ELSEIF(cmake_gentoolset_lower MATCHES "intel")
MESSAGE(FATAL_ERROR "Possibly unknown or unsupported Intel compiler") # version update needed in the above lines
ELSEIF(cmake_gentoolset_lower STREQUAL "llvm" OR cmake_gentoolset_lower STREQUAL "clangcl")
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") # hope: always
message("LLVM toolset was specified via -T. Compiler ID is: ${CMAKE_CXX_COMPILER_ID}; CMAKE_CXX_COMPILER_VERSION is: ${CMAKE_CXX_COMPILER_VERSION}")
# Clang; 9.0.0
# These are probably not supported when clang is downloaded as a ready-made binary: CLANG_VERSION_MAJOR CLANG_VERSION_MINOR CLANG_VERSION_STRING
# string (REGEX REPLACE ".*clang version ([0-9]+\\.[0-9]+).*" "\\1" CLANG_VERSION_STRING ${clang_full_version_string})
if( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.1 )
MESSAGE(FATAL_ERROR "Clang 7.0.1 or newer required") # as of November 2021 actually we are using 12.0
endif()
endif()
set(CLANG_IN_VS "1")
ELSEIF(cmake_gentoolset_lower STREQUAL "v141_clang_c2")
#1900 is reported
message("v141_clang_c2 toolset was specified via -T. Reported MSVC_VERSION is: ${MSVC_VERSION}")
message("May not work, try clangcl or LLVM")
set(CLANG_IN_VS "1")
# For LLVM Clang installed separately, specify llvm
# Since Visual Studio 2019 v16.4, LLVM 9.0 or newer is integrated, for this use Toolset: clangcl
ENDIF()
option(WINXP_SUPPORT "Make binaries compatible with Windows XP and Vista" OFF)
if(WINXP_SUPPORT)
# We want our project to also run on Windows XP
# Not for LLVM: Clang stopped XP support in 2016
IF(NOT CLANG_IN_VS STREQUAL "1")
# Setting CMAKE_GENERATOR_TOOLSET here has no effect, only when passed (-T option) or set directly, so we just check it
IF(CMAKE_GENERATOR_TOOLSET STREQUAL "v141_xp")
# v141_xp is still available in Visual Studio 2022 and 2026.
message("CMAKE_GENERATOR_TOOLSET is XP compatible: ${CMAKE_GENERATOR_TOOLSET}, extra XP options added")
# https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics
# later done: add_definitions("/Zc:threadSafeInit-")
ELSE()
message(FATAL_ERROR "For XP you must specify v141_xp toolset with -T option (or 'Optional toolset to use' in CMake GUI)!")
ENDIF()
ENDIF()
endif()
ENDIF()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
set(CLANG_IN_VS "1")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
set(IntelLLVM_IN_VS "1")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
set(IntelClassic_IN_VS "1")
endif()
IF(IntelClassic_IN_VS STREQUAL "1")
# Intel C++ Compiler 19.2
message("Intel Classic chosen, setting additional flags")
set(DELETE_THIS "/std:c++17") # if it would co-exist with /Qstd=c++17
STRING( REPLACE "${DELETE_THIS}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
STRING( REPLACE "${DELETE_THIS}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
# Workaround as of 19.2:
# Statically link with /MT instead of /MD against linker error message
# "unresolved external symbol wmemcmp referenced in function std::filesystem ... lexically_normal"
# Linker bug?
set(CompilerFlags
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELWITHDEBINFO
)
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
set(${CompilerFlag} "${${CompilerFlag}}" CACHE STRING "msvc compiler flags" FORCE)
message("MSVC flags: ${CompilerFlag}:${${CompilerFlag}}")
endforeach()
ELSE()
# Plain MSVC branch continues; per-target options are applied later
ENDIF()
# CPU_ARCH can be overridden with the corresponding values when using MSVC:
# IA32 (disabled),
# SSE (Pentium III and higher, 1999),
# SSE2 (Pentium 4 and higher, 2000/2001),
# AVX (Sandy Bridge and higher, 2011),
# AVX2 (Haswell and higher, 2013)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(MSVC_CPU_ARCH "SSE2" CACHE STRING "Set MSVC architecture optimization level (default: SSE2)")
# /arch: applied later per-target
endif()
ELSE()
# not MS Visual Studio IDE
if(WIN32)
SET( CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-stdcall-fixup" )
# __CRT__NO_INLINE: moved to per-target definitions
elseif(APPLE)
# macOS uses Clang's linker, doesn't like --no-undefined
SET( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error" )
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# make sure there are no undefined symbols
SET( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" )
endif()
ENDIF()
add_subdirectory("avs_core")
# Start tracking targets before the plugins subdirectory is processed
get_property(_targets_before_plugins GLOBAL PROPERTY BUILT_TARGETS)
if(ENABLE_PLUGINS)
add_subdirectory("plugins")
endif()
# End tracking targets and apply fixes here
get_property(_targets_after_plugins GLOBAL PROPERTY BUILT_TARGETS)
# Calculate targets added in the plugins subdirectory
list(REMOVE_ITEM _targets_after_plugins ${_targets_before_plugins})
set(NEW_PLUGIN_TARGETS ${_targets_after_plugins})
# Combine AvsCore and the newly discovered plugins into one list for fixing
set(ALL_AFFECTED_TARGETS)
if(TARGET AvsCore)
list(APPEND ALL_AFFECTED_TARGETS AvsCore)
endif()
list(APPEND ALL_AFFECTED_TARGETS ${NEW_PLUGIN_TARGETS})
# -----------------------------------------------------------------------
# Per-target, modern & safe application of options/defines (CORE and PLUGINS)
# -----------------------------------------------------------------------
foreach(AFFECTED_TARGET ${ALL_AFFECTED_TARGETS})
if(TARGET ${AFFECTED_TARGET})
message(STATUS "Applying compiler fixes to target: ${AFFECTED_TARGET}")
# Check if the target is a library or executable (exclude INTERFACE targets)
get_target_property(_target_type ${AFFECTED_TARGET} TYPE)
if(NOT (
${_target_type} STREQUAL "SHARED_LIBRARY" OR
${_target_type} STREQUAL "STATIC_LIBRARY" OR
${_target_type} STREQUAL "MODULE_LIBRARY"
))
# Skip if it's not a compileable target (e.g., if it was an interface target)
continue()
endif()
# Use a compound check: If the generator is Visual Studio, or the compiler ID
# is MSVC AND we are on Windows, run the MSVC-specific logic.
if( CMAKE_GENERATOR MATCHES "Visual Studio" OR (MSVC AND WIN32) )
# Using only if(MSVC) will fail with MinGW if the compiler ID is MSVC but the generator is not VS.
# This robust check ensures that the MSVC block only runs in an MSVC environment.
# Handle ARM64 soft intrinsics if requested (for AvsCore logic)
# Was experimental, never true
if("${PLATFORMID}" STREQUAL "ARM64" AND ENABLE_INTEL_SIMD)
target_compile_definitions(${AFFECTED_TARGET} PRIVATE USE_SOFT_INTRINSICS)
endif()
# Needed to properly handle __has_include(<filesystem>) in avs_core/filesystem.h
# See note in filesystem/README.md
target_compile_options(${AFFECTED_TARGET} PRIVATE /Zc:__cplusplus)
# Prevent VC++ secure CRT warnings, and add __SSE2__ flag. (Why?)
target_compile_definitions(${AFFECTED_TARGET} PRIVATE
_CRT_SECURE_NO_WARNINGS
_SECURE_SCL=0
_CRTDBG_MAP_ALLOC
__SSE2__
)
# INTEL intrinsics master switch (if enabled)
if(ENABLE_INTEL_SIMD)
target_compile_definitions(${AFFECTED_TARGET} PRIVATE INTEL_INTRINSICS)
endif()
# NEON intrinsics master switch (if enabled)
if(ENABLE_NEON_SIMD)
target_compile_definitions(${AFFECTED_TARGET} PRIVATE NEON_INTRINSICS)
endif()
# FIXME: With Ninja, we can see cl : Command line warning D9025 : overriding '/EHs' with '/EHa'
# Compiler-specific options for IntelLLVM / Clang
if(CLANG_IN_VS STREQUAL "1")
target_compile_options(${AFFECTED_TARGET} PRIVATE /EHa -Wno-inconsistent-missing-override)
target_compile_options(${AFFECTED_TARGET} PRIVATE -Wno-unused-function -Wno-reorder -Wno-unused-value -Wno-gcc-compat)
elseif(IntelLLVM_IN_VS STREQUAL "1")
target_compile_options(${AFFECTED_TARGET} PRIVATE -Wno-inconsistent-missing-override /EHa /fp:precise)
target_compile_options(${AFFECTED_TARGET} PRIVATE -Wno-unused-function -Wno-reorder -Wno-unused-value -Wno-gcc-compat)
elseif(IntelClassic_IN_VS STREQUAL "1")
target_compile_options(${AFFECTED_TARGET} PRIVATE /EHa)
else()
# Plain MSVC
target_compile_options(${AFFECTED_TARGET} PRIVATE /EHa)
if (NOT (MSVC_VERSION LESS 1930)) # VS2022+
target_compile_options(${AFFECTED_TARGET} PRIVATE /fp:contract)
endif()
endif()
# Enable standards-conformance mode for MSVC compilers that support this
# flag (Visual C++ 2017 and later). Default. DirectShowSource will remove if needed.
# The headers in the XP-side SDK also have errors if built in conformance mode,
# so if we're building for XP, don't turn that on.
# Plus check: Skip /permissive- if the target (e.g. DirectShowSource) requests it.
# Filled in plugin's CMakeLists.txt
get_target_property(_skip_permissive ${AFFECTED_TARGET} SKIP_PERMISSIVE_FLAG)
if(NOT _skip_permissive) # old DirectShowSource
if (NOT WINXP_SUPPORT)
if (NOT (MSVC_VERSION LESS 1910))
target_compile_options(${AFFECTED_TARGET} PRIVATE /permissive-)
endif()
endif()
endif()
# Check if XP support is enabled AND if the XP toolset is used (v141_xp)
if (WINXP_SUPPORT)
if (CMAKE_GENERATOR_TOOLSET STREQUAL "v141_xp")
# C++11 static initialization fix for XP/Server 2003
target_compile_options(${AFFECTED_TARGET} PRIVATE "/Zc:threadSafeInit-")
endif()
endif()
# 32-bit arch tuning
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
target_compile_options(${AFFECTED_TARGET} PRIVATE /arch:${MSVC_CPU_ARCH})
endif()
else()
# CMAKE_CXX_STANDARD doesn't cover the use-case of pre-final C++17 support,
# but I'd assume most setups with a new enough version of CMake to use
# CMAKE_CXX_STANDARD 17 would also be running a version of GCC/Clang new enough
# to not need this. So this will most likely only ever be used by setups running
# older versions of CMake; regardless, it shouldn't be necessary to force a
# CMAKE_VERSION check on this part unless the mere presence of CMAKE_CXX_STANDARD 17
# ends up causing problems for the older compilers here.
# Legacy C++17 support for older GCC/Clang
if( ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8)) OR
((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5)) )
target_compile_options(${AFFECTED_TARGET} PRIVATE -std=c++1z)
endif()
if(ENABLE_INTEL_SIMD)
target_compile_options(${AFFECTED_TARGET} PRIVATE -msse2)
target_compile_definitions(${AFFECTED_TARGET} PRIVATE INTEL_INTRINSICS)
endif()
if(ENABLE_NEON_SIMD)
target_compile_definitions(${AFFECTED_TARGET} PRIVATE NEON_INTRINSICS)
endif()
if(WIN32)
target_compile_definitions(${AFFECTED_TARGET} PRIVATE __CRT__NO_INLINE=1)
endif()
endif()
endif()
endforeach()
else()
# HEADERS_ONLY is ON
project(AviSynth-Headers VERSION ${PROJECT_VERSION_STRING} LANGUAGES CXX)
message(STATUS "Install Only Headers: ON")
add_library(${PROJECT_NAME} INTERFACE)
target_include_directories(${PROJECT_NAME} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/avs_core/include")
add_library(AviSynth::Headers ALIAS ${PROJECT_NAME})
# Determine target architecture
include("${CMAKE_CURRENT_LIST_DIR}/avs_core/TargetArch.cmake")
target_architecture(AVS_ARCH)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/avs_core/core/arch.h.in ${CMAKE_CURRENT_BINARY_DIR}/arch.h @ONLY)
# Dynamically generate the sequential version info from Git
# Based on the example here: http://www.cmake.org/pipermail/cmake/2010-July/038015.html
FIND_PACKAGE(Git)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
ADD_CUSTOM_TARGET(
VersionGen ALL
${CMAKE_COMMAND} -D SRC=${CMAKE_CURRENT_SOURCE_DIR}/avs_core/core/version.h.in
-D DST=${CMAKE_CURRENT_BINARY_DIR}/version.h
-D GIT=${GIT_EXECUTABLE}
-D REPO=${CMAKE_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/avs_core/Version.cmake
)
include(GNUInstallDirs)
install(
FILES ${CMAKE_CURRENT_SOURCE_DIR}/avs_core/include/avisynth.h
${CMAKE_CURRENT_SOURCE_DIR}/avs_core/include/avisynth_c.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/avisynth
)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/avs_core/include/avs
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/avisynth
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/version.h"
"${CMAKE_CURRENT_BINARY_DIR}/arch.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/avisynth/avs"
)
endif()
# uninstall target
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)