1# SPDX-License-Identifier: Apache-2.0 2# ---------------------------------------------------------------------------- 3# Copyright 2020-2023 Arm Limited 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may not 6# use this file except in compliance with the License. You may obtain a copy 7# of the License at: 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations 15# under the License. 16# ---------------------------------------------------------------------------- 17 18set(ASTCENC_TARGET astc${ASTCENC_CODEC}-${ASTCENC_ISA_SIMD}) 19 20project(${ASTCENC_TARGET}) 21 22# On CMake 3.25 or older CXX_COMPILER_FRONTEND_VARIANT is not always set 23if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "") 24 set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "${CMAKE_CXX_COMPILER_ID}") 25endif() 26 27# Compiler accepts MSVC-style command line options 28set(is_msvc_fe "$<STREQUAL:${CMAKE_CXX_COMPILER_FRONTEND_VARIANT},MSVC>") 29# Compiler accepts GNU-style command line options 30set(is_gnu_fe1 "$<STREQUAL:${CMAKE_CXX_COMPILER_FRONTEND_VARIANT},GNU>") 31# Compiler accepts AppleClang-style command line options, which is also GNU-style 32set(is_gnu_fe2 "$<STREQUAL:${CMAKE_CXX_COMPILER_FRONTEND_VARIANT},AppleClang>") 33# Compiler accepts GNU-style command line options 34set(is_gnu_fe "$<OR:${is_gnu_fe1},${is_gnu_fe2}>") 35 36# Compiler is Visual Studio cl.exe 37set(is_msvccl "$<AND:${is_msvc_fe},$<CXX_COMPILER_ID:MSVC>>") 38# Compiler is Visual Studio clangcl.exe 39set(is_clangcl "$<AND:${is_msvc_fe},$<CXX_COMPILER_ID:Clang>>") 40# Compiler is upstream clang with the standard frontend 41set(is_clang "$<AND:${is_gnu_fe},$<CXX_COMPILER_ID:Clang,AppleClang>>") 42 43add_library(${ASTCENC_TARGET}-static 44 STATIC 45 astcenc_averages_and_directions.cpp 46 astcenc_block_sizes.cpp 47 astcenc_color_quantize.cpp 48 astcenc_color_unquantize.cpp 49 astcenc_compress_symbolic.cpp 50 astcenc_compute_variance.cpp 51 astcenc_decompress_symbolic.cpp 52 astcenc_diagnostic_trace.cpp 53 astcenc_entry.cpp 54 astcenc_find_best_partitioning.cpp 55 astcenc_ideal_endpoints_and_weights.cpp 56 astcenc_image.cpp 57 astcenc_integer_sequence.cpp 58 astcenc_mathlib.cpp 59 astcenc_mathlib_softfloat.cpp 60 astcenc_partition_tables.cpp 61 astcenc_percentile_tables.cpp 62 astcenc_pick_best_endpoint_format.cpp 63 astcenc_quantization.cpp 64 astcenc_symbolic_physical.cpp 65 astcenc_weight_align.cpp 66 astcenc_weight_quant_xfer_tables.cpp) 67 68target_include_directories(${ASTCENC_TARGET}-static 69 PUBLIC 70 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> 71 $<INSTALL_INTERFACE:.>) 72 73if(${ASTCENC_SHAREDLIB}) 74 add_library(${ASTCENC_TARGET}-shared 75 SHARED 76 astcenc_averages_and_directions.cpp 77 astcenc_block_sizes.cpp 78 astcenc_color_quantize.cpp 79 astcenc_color_unquantize.cpp 80 astcenc_compress_symbolic.cpp 81 astcenc_compute_variance.cpp 82 astcenc_decompress_symbolic.cpp 83 astcenc_diagnostic_trace.cpp 84 astcenc_entry.cpp 85 astcenc_find_best_partitioning.cpp 86 astcenc_ideal_endpoints_and_weights.cpp 87 astcenc_image.cpp 88 astcenc_integer_sequence.cpp 89 astcenc_mathlib.cpp 90 astcenc_mathlib_softfloat.cpp 91 astcenc_partition_tables.cpp 92 astcenc_percentile_tables.cpp 93 astcenc_pick_best_endpoint_format.cpp 94 astcenc_quantization.cpp 95 astcenc_symbolic_physical.cpp 96 astcenc_weight_align.cpp 97 astcenc_weight_quant_xfer_tables.cpp) 98 99 target_include_directories(${ASTCENC_TARGET}-shared 100 PUBLIC 101 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> 102 $<INSTALL_INTERFACE:.>) 103endif() 104 105if(${ASTCENC_CLI}) 106 # Veneer is compiled without any extended ISA so we can safely do 107 # ISA compatability checks without triggering a SIGILL 108 add_library(${ASTCENC_TARGET}-veneer 109 astcenccli_entry.cpp) 110 111 add_executable(${ASTCENC_TARGET} 112 astcenccli_error_metrics.cpp 113 astcenccli_image.cpp 114 astcenccli_image_external.cpp 115 astcenccli_image_load_store.cpp 116 astcenccli_platform_dependents.cpp 117 astcenccli_toplevel.cpp 118 astcenccli_toplevel_help.cpp) 119 120 target_link_libraries(${ASTCENC_TARGET} 121 PRIVATE 122 ${ASTCENC_TARGET}-veneer 123 ${ASTCENC_TARGET}-static) 124endif() 125 126macro(astcenc_set_properties ASTCENC_TARGET_NAME ASTCENC_IS_VENEER) 127 128 target_compile_features(${ASTCENC_TARGET_NAME} 129 PRIVATE 130 cxx_std_14) 131 132 target_compile_definitions(${ASTCENC_TARGET_NAME} 133 PRIVATE 134 $<${is_msvc_fe}:_CRT_SECURE_NO_WARNINGS>) 135 136 if(${ASTCENC_DECOMPRESSOR}) 137 target_compile_definitions(${ASTCENC_TARGET_NAME} 138 PRIVATE 139 ASTCENC_DECOMPRESS_ONLY) 140 endif() 141 142 if(${ASTCENC_BLOCK_MAX_TEXELS}) 143 target_compile_definitions(${ASTCENC_TARGET_NAME} 144 PRIVATE 145 ASTCENC_BLOCK_MAX_TEXELS=${ASTCENC_BLOCK_MAX_TEXELS}) 146 endif() 147 148 if(${ASTCENC_DIAGNOSTICS}) 149 target_compile_definitions(${ASTCENC_TARGET_NAME} 150 PUBLIC 151 ASTCENC_DIAGNOSTICS) 152 endif() 153 154 target_compile_options(${ASTCENC_TARGET_NAME} 155 PRIVATE 156 # Use pthreads on Linux/macOS 157 $<$<PLATFORM_ID:Linux,Darwin>:-pthread> 158 159 # MSVC compiler defines 160 $<${is_msvc_fe}:/EHsc> 161 $<${is_msvccl}:/wd4324> 162 163 # G++ and Clang++ compiler defines 164 $<${is_gnu_fe}:-Wall> 165 $<${is_gnu_fe}:-Wextra> 166 $<${is_gnu_fe}:-Wpedantic> 167 $<${is_gnu_fe}:-Werror> 168 $<${is_gnu_fe}:-Wshadow> 169 $<${is_gnu_fe}:-Wdouble-promotion> 170 $<${is_clang}:-Wdocumentation> 171 172 # Hide noise thrown up by Clang 10 and clang-cl 173 $<${is_gnu_fe}:-Wno-unknown-warning-option> 174 $<${is_gnu_fe}:-Wno-c++98-compat-pedantic> 175 $<${is_gnu_fe}:-Wno-c++98-c++11-compat-pedantic> 176 $<${is_gnu_fe}:-Wno-float-equal> 177 $<${is_gnu_fe}:-Wno-deprecated-declarations> 178 $<${is_gnu_fe}:-Wno-atomic-implicit-seq-cst> 179 180 # Clang 10 also throws up warnings we need to investigate (ours) 181 $<${is_gnu_fe}:-Wno-cast-align> 182 $<${is_gnu_fe}:-Wno-sign-conversion> 183 $<${is_gnu_fe}:-Wno-implicit-int-conversion> 184 $<${is_gnu_fe}:-Wno-shift-sign-overflow> 185 $<${is_gnu_fe}:-Wno-format-nonliteral> 186 $<${is_gnu_fe}:-Wno-reserved-identifier> 187 $<${is_gnu_fe}:-Wno-cast-function-type> 188 189 # Force DWARF4 for Valgrind profiling 190 $<$<AND:$<PLATFORM_ID:Linux,Darwin>,${is_clang}>:-gdwarf-4> 191 192 # Disable non-portable Windows.h warning (fixing it fails builds on MinGW) 193 $<$<AND:$<PLATFORM_ID:Windows>,${is_clang}>:-Wno-nonportable-system-include-path>) 194 195 target_link_options(${ASTCENC_TARGET_NAME} 196 PRIVATE 197 # Use pthreads on Linux/macOS 198 $<$<PLATFORM_ID:Linux,Darwin>:-pthread>) 199 200 if(${ASTCENC_ASAN}) 201 target_compile_options(${ASTCENC_TARGET_NAME} 202 PRIVATE 203 $<${is_clang}:-fsanitize=address>) 204 205 target_link_options(${ASTCENC_TARGET_NAME} 206 PRIVATE 207 $<${is_clang}:-fsanitize=address>) 208 endif() 209 210 if(NOT ${ASTCENC_INVARIANCE}) 211 target_compile_definitions(${ASTCENC_TARGET_NAME} 212 PRIVATE 213 ASTCENC_NO_INVARIANCE=1) 214 215 # For Visual Studio prior to 2022 (compiler < 19.30) /fp:precise 216 # For Visual Studio 2022 (compiler >= 19.30) /fp:precise and /fp:contract 217 218 # For Visual Studio 2022 ClangCL seems to have accidentally enabled contraction by default, 219 # so behaves differently to CL.exe. Use the -Xclang argument to workaround and allow access 220 # GNU-style switch to control contraction on the assumption this gets fixed and disabled. 221 # Note ClangCL does not accept /fp:contract as an argument as of v15.0.7. 222 target_compile_options(${ASTCENC_TARGET_NAME} 223 PRIVATE 224 $<${is_msvccl}:/fp:precise> 225 $<${is_clangcl}:/fp:precise> 226 $<$<AND:${is_msvccl},$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,19.30>>:/fp:contract> 227 $<$<AND:${is_clangcl},$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,14.0.0>>:-Xclang -ffp-contract=fast> 228 $<$<AND:${is_clang},$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,10.0.0>>:-ffp-model=precise> 229 $<${is_gnu_fe}:-ffp-contract=fast>) 230 else() 231 # For Visual Studio prior to 2022 (compiler < 19.30) /fp:strict 232 # For Visual Studio 2022 (compiler >= 19.30) /fp:precise 233 234 # For Visual Studio 2022 ClangCL seems to have accidentally enabled contraction by default, 235 # so behaves differently to CL.exe. Use the -Xclang argument to workaround and allow access 236 # GNU-style switch to control contraction and force disable. 237 target_compile_options(${ASTCENC_TARGET_NAME} 238 PRIVATE 239 $<$<AND:${is_msvccl},$<VERSION_LESS:$<CXX_COMPILER_VERSION>,19.30>>:/fp:strict> 240 $<$<AND:${is_msvccl},$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,19.30>>:/fp:precise> 241 $<${is_clangcl}:/fp:precise> 242 $<$<AND:${is_clangcl},$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,14.0.0>>:-Xclang -ffp-contract=off> 243 $<$<AND:${is_clang},$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,10.0.0>>:-ffp-model=precise> 244 $<${is_gnu_fe}:-ffp-contract=off>) 245 endif() 246 247 if(${ASTCENC_CLI}) 248 # Enable LTO on release builds 249 set_property(TARGET ${ASTCENC_TARGET_NAME} 250 PROPERTY 251 INTERPROCEDURAL_OPTIMIZATION_RELEASE True) 252 253 # Use a static runtime on MSVC builds (ignored on non-MSVC compilers) 254 set_property(TARGET ${ASTCENC_TARGET_NAME} 255 PROPERTY 256 MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") 257 endif() 258 259 # Set up configuration for SIMD ISA builds 260 if(${ASTCENC_ISA_SIMD} MATCHES "none") 261 target_compile_definitions(${ASTCENC_TARGET_NAME} 262 PRIVATE 263 ASTCENC_NEON=0 264 ASTCENC_SSE=0 265 ASTCENC_AVX=0 266 ASTCENC_POPCNT=0 267 ASTCENC_F16C=0) 268 269 elseif(${ASTCENC_ISA_SIMD} MATCHES "neon") 270 target_compile_definitions(${ASTCENC_TARGET_NAME} 271 PRIVATE 272 ASTCENC_NEON=1 273 ASTCENC_SSE=0 274 ASTCENC_AVX=0 275 ASTCENC_POPCNT=0 276 ASTCENC_F16C=0) 277 278 # Workaround MSVC codegen bug for NEON builds on VS 2022 17.2 or older 279 # https://developercommunity.visualstudio.com/t/inlining-turns-constant-into-register-operand-for/1394798 280 if((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND (MSVC_VERSION LESS 1933)) 281 target_compile_options(${ASTCENC_TARGET_NAME} 282 PRIVATE 283 $<${is_msvccl}:/d2ssa-cfg-sink->) 284 endif() 285 286 elseif(${ASTCENC_ISA_SIMD} MATCHES "sse2") 287 target_compile_definitions(${ASTCENC_TARGET_NAME} 288 PRIVATE 289 ASTCENC_NEON=0 290 ASTCENC_SSE=20 291 ASTCENC_AVX=0 292 ASTCENC_POPCNT=0 293 ASTCENC_F16C=0) 294 295 # Force SSE2 on AppleClang (normally SSE4.1 is the default) 296 target_compile_options(${ASTCENC_TARGET_NAME} 297 PRIVATE 298 $<${is_clangcl}:-msse2> 299 $<${is_gnu_fe}:-msse2> 300 $<${is_gnu_fe}:-mno-sse4.1> 301 $<${is_gnu_fe}:-Wno-unused-command-line-argument>) 302 303 elseif(${ASTCENC_ISA_SIMD} MATCHES "sse4.1") 304 target_compile_definitions(${ASTCENC_TARGET_NAME} 305 PRIVATE 306 ASTCENC_NEON=0 307 ASTCENC_SSE=41 308 ASTCENC_AVX=0 309 ASTCENC_POPCNT=1 310 ASTCENC_F16C=0) 311 312 if (${ASTCENC_IS_VENEER}) 313 # Force SSE2 on AppleClang (normally SSE4.1 is the default) 314 target_compile_options(${ASTCENC_TARGET_NAME} 315 PRIVATE 316 $<${is_gnu_fe}:-msse2> 317 $<${is_gnu_fe}:-mno-sse4.1> 318 $<${is_gnu_fe}:-Wno-unused-command-line-argument>) 319 else() 320 target_compile_options(${ASTCENC_TARGET_NAME} 321 PRIVATE 322 $<${is_clangcl}:-msse4.1 -mpopcnt> 323 $<${is_gnu_fe}:-msse4.1 -mpopcnt> 324 $<${is_gnu_fe}:-Wno-unused-command-line-argument>) 325 endif() 326 327 elseif(${ASTCENC_ISA_SIMD} MATCHES "avx2") 328 target_compile_definitions(${ASTCENC_TARGET_NAME} 329 PRIVATE 330 ASTCENC_NEON=0 331 ASTCENC_SSE=41 332 ASTCENC_AVX=2 333 ASTCENC_POPCNT=1 334 ASTCENC_F16C=1) 335 336 if (${ASTCENC_IS_VENEER}) 337 # Force SSE2 on AppleClang (normally SSE4.1 is the default) 338 target_compile_options(${ASTCENC_TARGET_NAME} 339 PRIVATE 340 $<${is_gnu_fe}:-msse2> 341 $<${is_gnu_fe}:-mno-sse4.1> 342 $<${is_gnu_fe}:-Wno-unused-command-line-argument>) 343 else() 344 target_compile_options(${ASTCENC_TARGET_NAME} 345 PRIVATE 346 $<${is_msvc_fe}:/arch:AVX2> 347 $<${is_clangcl}:-mavx2 -mpopcnt -mf16c> 348 $<${is_gnu_fe}:-mavx2 -mpopcnt -mf16c> 349 $<${is_gnu_fe}:-Wno-unused-command-line-argument>) 350 endif() 351 352 # Non-invariant builds enable us to loosen the compiler constraints on 353 # floating point, but this is only worth doing on CPUs with AVX2 because 354 # this implies we can also enable the FMA instruction set extensions 355 # which significantly improve performance. Note that this DOES reduce 356 # image quality by up to 0.2 dB (normally much less), but buys an 357 # average of 10-15% performance improvement ... 358 if((NOT ${ASTCENC_INVARIANCE}) AND (NOT ${ASTCENC_IS_VENEER})) 359 target_compile_options(${ASTCENC_TARGET_NAME} 360 PRIVATE 361 $<${is_gnu_fe}:-mfma>) 362 endif() 363 364 endif() 365 366endmacro() 367 368string(CONCAT EXTERNAL_CXX_FLAGS 369 " $<${is_gnu_fe}: -fno-strict-aliasing>" 370 " $<${is_gnu_fe}: -Wno-unused-parameter>" 371 " $<${is_gnu_fe}: -Wno-old-style-cast>" 372 " $<${is_gnu_fe}: -Wno-double-promotion>" 373 " $<${is_gnu_fe}: -Wno-zero-as-null-pointer-constant>" 374 " $<${is_gnu_fe}: -Wno-disabled-macro-expansion>" 375 " $<${is_gnu_fe}: -Wno-reserved-id-macro>" 376 " $<${is_gnu_fe}: -Wno-extra-semi-stmt>" 377 " $<${is_gnu_fe}: -Wno-implicit-fallthrough>" 378 " $<${is_gnu_fe}: -Wno-tautological-type-limit-compare>" 379 " $<${is_gnu_fe}: -Wno-cast-qual>" 380 " $<${is_gnu_fe}: -Wno-reserved-identifier>" 381 " $<${is_clang}: -Wno-missing-prototypes>" 382 " $<${is_gnu_fe}: -Wno-missing-field-initializers>" 383 " $<${is_gnu_fe}: -Wno-suggest-override>" 384 " $<${is_gnu_fe}: -Wno-used-but-marked-unused>" 385 " $<${is_gnu_fe}: -Wno-noexcept-type>" 386 " $<${is_gnu_fe}: -Wno-comma>" 387 " $<${is_gnu_fe}: -Wno-c99-extensions>") 388 389set_source_files_properties(astcenccli_image_external.cpp 390 PROPERTIES 391 COMPILE_FLAGS ${EXTERNAL_CXX_FLAGS}) 392 393astcenc_set_properties(${ASTCENC_TARGET}-static OFF) 394 395target_compile_options(${ASTCENC_TARGET}-static 396 PRIVATE 397 $<${is_msvc_fe}:/W4>) 398 399if(${ASTCENC_SHAREDLIB}) 400 astcenc_set_properties(${ASTCENC_TARGET}-shared OFF) 401 402 target_compile_definitions(${ASTCENC_TARGET}-shared 403 PRIVATE 404 ASTCENC_DYNAMIC_LIBRARY=1) 405 406 target_compile_options(${ASTCENC_TARGET}-shared 407 PRIVATE 408 $<${is_gnu_fe}:-fvisibility=hidden> 409 $<${is_msvc_fe}:/W4>) 410 411 if(NOT ${ASTCENC_UNIVERSAL_BUILD}) 412 install(TARGETS ${ASTCENC_TARGET}-shared) 413 endif() 414endif() 415 416if(${ASTCENC_CLI}) 417 astcenc_set_properties(${ASTCENC_TARGET}-veneer ON) 418 astcenc_set_properties(${ASTCENC_TARGET} OFF) 419 420 target_compile_options(${ASTCENC_TARGET} 421 PRIVATE 422 $<${is_msvc_fe}:/W3>) 423 424 target_compile_options(${ASTCENC_TARGET}-veneer 425 PRIVATE 426 $<${is_msvc_fe}:/W3>) 427 428 string(TIMESTAMP astcencoder_YEAR "%Y") 429 430 configure_file( 431 astcenccli_version.h.in 432 astcenccli_version.h 433 ESCAPE_QUOTES @ONLY) 434 435 target_include_directories(${ASTCENC_TARGET} 436 PRIVATE 437 ${CMAKE_CURRENT_BINARY_DIR}) 438 439 if(NOT ${ASTCENC_UNIVERSAL_BUILD}) 440 install(TARGETS ${ASTCENC_TARGET}) 441 endif() 442endif() 443