1#  SPDX-License-Identifier: Apache-2.0
2#  ----------------------------------------------------------------------------
3#  Copyright 2020-2022 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
18# CMake configuration
19cmake_minimum_required(VERSION 3.15)
20cmake_policy(SET CMP0069 NEW)  # LTO support
21cmake_policy(SET CMP0091 NEW)  # MSVC runtime support
22
23if(MSVC)
24    add_compile_options("/wd4324") # Disable structure was padded due to alignment specifier
25endif()
26
27project(astcencoder VERSION 4.2.0)
28
29set(CMAKE_CXX_STANDARD 14)
30set(CMAKE_CXX_STANDARD_REQUIRED ON)
31set(CMAKE_CXX_EXTENSIONS OFF)
32set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
33
34include(CTest)
35
36option(ISA_AVX2 "Enable builds for AVX2 SIMD")
37option(ISA_SSE41 "Enable builds for SSE4.1 SIMD")
38option(ISA_SSE2 "Enable builds for SSE2 SIMD")
39option(ISA_NEON "Enable builds for NEON SIMD")
40option(ISA_NONE "Enable builds for no SIMD")
41option(ISA_NATIVE "Enable builds for native SIMD")
42option(DECOMPRESSOR "Enable builds for decompression only")
43option(DIAGNOSTICS "Enable builds for diagnostic trace")
44option(ASAN "Enable builds width address sanitizer")
45option(UNITTEST "Enable builds for unit tests")
46option(NO_INVARIANCE "Enable builds without invariance")
47option(CLI "Enable build of CLI" ON)
48
49set(UNIVERSAL_BUILD OFF)
50set(MACOS_BUILD OFF)
51set(MACOS_ARCH_LEN 0)
52
53# Preflight for some macOS-specific build options
54if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
55    set(MACOS_BUILD ON)
56    list(LENGTH CMAKE_OSX_ARCHITECTURES MACOS_ARCH_LEN)
57endif()
58
59# Count options which MUST be x64
60set(X64_ISA_COUNT 0)
61set(CONFIGS ${ISA_AVX2} ${ISA_SSE41} ${ISA_SSE2})
62foreach(CONFIG ${CONFIGS})
63    if(${CONFIG})
64        math(EXPR X64_ISA_COUNT "${X64_ISA_COUNT} + 1")
65    endif()
66endforeach()
67
68# Count options which MUST be arm64
69set(ARM64_ISA_COUNT 0)
70set(CONFIGS ${ISA_NEON})
71foreach(CONFIG ${CONFIGS})
72    if(${CONFIG})
73        math(EXPR ARM64_ISA_COUNT "${ARM64_ISA_COUNT} + 1")
74    endif()
75endforeach()
76
77# macOS builds
78if("${MACOS_BUILD}")
79    list(FIND CMAKE_OSX_ARCHITECTURES "x86_64" IS_X64)
80    list(FIND CMAKE_OSX_ARCHITECTURES "arm64" IS_ARM64)
81    list(FIND CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD)" IS_AUTO)
82
83    # Turn list index into boolean
84    if(${IS_X64} EQUAL -1)
85        set(IS_X64 OFF)
86    else()
87        set(IS_X64 ON)
88    endif()
89
90    if(${IS_ARM64} EQUAL -1)
91        set(IS_ARM64 OFF)
92    else()
93        set(IS_ARM64 ON)
94    endif()
95
96    if(${IS_AUTO} EQUAL -1)
97        set(IS_AUTO OFF)
98    else()
99        set(IS_AUTO ON)
100    endif()
101
102    # Set up defaults if no more specific ISA set - use XCode's own defaults
103    if((IS_ARM64 OR IS_AUTO) AND ("${ARM64_ISA_COUNT}" EQUAL 0) AND (NOT "${ISA_NONE}"))
104        set(ARM64_ISA_COUNT 1)
105        set(ISA_NEON ON)
106    endif()
107
108    if((IS_X64 OR IS_AUTO) AND ("${X64_ISA_COUNT}" EQUAL 0) AND (NOT "${ISA_NONE}"))
109        set(X64_ISA_COUNT 1)
110        set(ISA_SSE41 ON)
111    endif()
112
113    # User might be doing multi-architecture - XCode sets this at runtime
114    if("${IS_AUTO}")
115        if(("${ARM64_ISA_COUNT}" GREATER 1) OR ("${X64_ISA_COUNT}" GREATER 1))
116            message(FATAL_ERROR "For macOS universal binaries only one backend per architecture is allowed.")
117        endif()
118
119        set(UNIVERSAL_BUILD ON)
120
121    # User requested explicit multi-architecture universal build
122    elseif("${MACOS_ARCH_LEN}" GREATER 2)
123        message(FATAL_ERROR "For macOS universal binaries only x86_64 and arm64 builds are allowed.")
124
125    elseif("${MACOS_ARCH_LEN}" EQUAL 2)
126        if(NOT (${IS_X64} AND ${IS_ARM64}))
127            message(FATAL_ERROR "For macOS universal binaries only x86_64 and arm64 builds are allowed.")
128        endif()
129
130        if(("${ARM64_ISA_COUNT}" GREATER 1) OR ("${X64_ISA_COUNT}" GREATER 1))
131            message(FATAL_ERROR "For macOS universal binaries only one backend per architecture is allowed.")
132        endif()
133
134        set(UNIVERSAL_BUILD ON)
135
136    # User requested explicit single architecture build
137    elseif("${MACOS_ARCH_LEN}" EQUAL 1)
138        if("${IS_X64}" AND "${ARM64_ISA_COUNT}")
139            message(FATAL_ERROR "For macOS x86_64 builds an arm64 backend cannot be specified.")
140        endif()
141
142        if("${IS_ARM64}" AND "${X64_ISA_COUNT}")
143            message(FATAL_ERROR "For macOS arm64 builds an x86_64 backend cannot be specified.")
144        endif()
145
146    # Else is this a implicit multi-architecture universal build?
147    elseif(("${ARM64_ISA_COUNT}" EQUAL 1) AND ("${X64_ISA_COUNT}" GREATER 1))
148        string(CONCAT MSG "For macOS setting multiple architecture backends builds a universal binary. "
149                          "For universal binaries only one backend per architecture is allowed.")
150        message(FATAL_ERROR "${MSG}")
151
152    elseif(("${X64_ISA_COUNT}" EQUAL 1) AND ("${ARM64_ISA_COUNT}" GREATER 1))
153        string(CONCAT MSG "For macOS setting multiple architecture backends builds a universal binary. "
154                          "For universal binaries only one backend per architecture is allowed.")
155        message(FATAL_ERROR "${MSG}")
156
157    elseif(("${ARM64_ISA_COUNT}" EQUAL 1) AND ("${X64_ISA_COUNT}" EQUAL 1))
158        set(UNIVERSAL_BUILD ON)
159        set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
160
161    # Else is this an implicit single architecture build?
162    elseif("${ARM64_ISA_COUNT}" EQUAL 1)
163        set(CMAKE_OSX_ARCHITECTURES "arm64")
164
165    elseif("${X64_ISA_COUNT}" EQUAL 1)
166        set(CMAKE_OSX_ARCHITECTURES "x86_64")
167
168    else()
169        # Do nothing here - assume it defaults to host?
170
171    endif()
172
173# Non-macOS builds
174else()
175    if(("${ARM64_ISA_COUNT}" GREATER 0) AND ("${X64_ISA_COUNT}" GREATER 0))
176        message(FATAL_ERROR "Builds can only support a single architecture per configure.")
177    endif()
178endif()
179
180# If nothing more specific is set then fall back on the compiler's defaults
181if(("${ARM64_ISA_COUNT}" EQUAL 0) AND ("${X64_ISA_COUNT}" EQUAL 0) AND (NOT "${ISA_NONE}"))
182    set(ISA_NATIVE ON)
183endif()
184
185function(printopt optName optVal)
186    if(${optVal})
187        message(STATUS "  ${optName}  - ON")
188    else()
189        message(STATUS "  ${optName}  - OFF")
190    endif()
191endfunction()
192
193if("${BLOCK_MAX_TEXELS}")
194     message(STATUS "  Max block texels - ${BLOCK_MAX_TEXELS}")
195endif()
196printopt("AVX2 backend   " ${ISA_AVX2})
197printopt("SSE4.1 backend " ${ISA_SSE41})
198printopt("SSE2 backend   " ${ISA_SSE2})
199printopt("NEON backend   " ${ISA_NEON})
200printopt("NONE backend   " ${ISA_NONE})
201printopt("NATIVE backend " ${ISA_NATIVE})
202if("${MACOS_BUILD}")
203    printopt("Universal bin  " ${UNIVERSAL_BUILD})
204endif()
205printopt("Decompressor   " ${DECOMPRESSOR})
206printopt("No invariance  " ${NO_INVARIANCE})
207printopt("Diagnostics    " ${DIAGNOSTICS})
208printopt("ASAN           " ${ASAN})
209printopt("Unit tests     " ${UNITTEST})
210
211# Subcomponents
212add_subdirectory(Source)
213
214# Configure package archive
215if(PACKAGE)
216    if("${MACOS_BUILD}")
217        string(TOLOWER "macOS" PKG_OS)
218    else()
219        string(TOLOWER ${CMAKE_SYSTEM_NAME} PKG_OS)
220    endif()
221
222    set(CPACK_PACKAGE_FILE_NAME "astcenc-${CMAKE_PROJECT_VERSION}-${PKG_OS}-${PACKAGE}")
223    set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY FALSE)
224    set(CPACK_PACKAGE_CHECKSUM SHA256)
225    set(CPACK_GENERATOR ZIP)
226
227    include(CPack) # Must be included after CPack configuration.
228endif()
229