• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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