1# 2# Copyright (c) 2017, Alliance for Open Media. All rights reserved 3# 4# This source code is subject to the terms of the BSD 2 Clause License and the 5# Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License was 6# not distributed with this source code in the LICENSE file, you can obtain it 7# at www.aomedia.org/license/software. If the Alliance for Open Media Patent 8# License 1.0 was not distributed with this source code in the PATENTS file, you 9# can obtain it at www.aomedia.org/license/patent. 10# 11if(AOM_BUILD_CMAKE_AOM_OPTIMIZATION_CMAKE_) 12 return() 13endif() # AOM_BUILD_CMAKE_AOM_OPTIMIZATION_CMAKE_ 14set(AOM_BUILD_CMAKE_AOM_OPTIMIZATION_CMAKE_ 1) 15 16include("${AOM_ROOT}/build/cmake/util.cmake") 17 18# Translate $flag to one which MSVC understands, and write the new flag to the 19# variable named by $translated_flag (or unset it, when MSVC needs no flag). 20function(get_msvc_intrinsic_flag flag translated_flag) 21 if("${flag}" STREQUAL "-mavx") 22 set(${translated_flag} "/arch:AVX" PARENT_SCOPE) 23 elseif("${flag}" STREQUAL "-mavx2") 24 set(${translated_flag} "/arch:AVX2" PARENT_SCOPE) 25 else() 26 27 # MSVC does not need flags for intrinsics flavors other than AVX/AVX2. 28 unset(${translated_flag} PARENT_SCOPE) 29 endif() 30endfunction() 31 32# Adds an object library target. Terminates generation if $flag is not supported 33# by the current compiler. $flag is the intrinsics flag required by the current 34# compiler, and is added to the compile flags for all sources in $sources. 35# $opt_name is used to name the target. $target_to_update is made dependent upon 36# the created target. 37# 38# Note: this function always updates the aom, and aom_static targets because 39# OBJECT libraries have rules that disallow the direct addition of .o files to 40# them as dependencies. Static and shared libraries do not have this limitation. 41function(add_intrinsics_object_library flag opt_name target_to_update sources) 42 if("${${sources}}" STREQUAL "") 43 return() 44 endif() 45 set(target_name ${target_to_update}_${opt_name}_intrinsics) 46 add_library(${target_name} OBJECT ${${sources}}) 47 set_property(TARGET ${target_name} PROPERTY FOLDER ${AOM_TARGET_CPU}) 48 49 if(MSVC) 50 get_msvc_intrinsic_flag(${flag} "flag") 51 endif() 52 53 if("${flag}" STREQUAL "-mavx2") 54 unset(FLAG_SUPPORTED) 55 check_c_compiler_flag("-mno-avx256-split-unaligned-load" FLAG_SUPPORTED) 56 if(${FLAG_SUPPORTED}) 57 set(flag "${flag} -mno-avx256-split-unaligned-load") 58 endif() 59 60 unset(FLAG_SUPPORTED) 61 check_c_compiler_flag("-mno-avx256-split-unaligned-store" FLAG_SUPPORTED) 62 if(${FLAG_SUPPORTED}) 63 set(flag "${flag} -mno-avx256-split-unaligned-store") 64 endif() 65 endif() 66 67 if(flag) 68 separate_arguments(flag) 69 target_compile_options(${target_name} PUBLIC ${flag}) 70 endif() 71 72 target_sources(aom PRIVATE $<TARGET_OBJECTS:${target_name}>) 73 if(BUILD_SHARED_LIBS) 74 target_sources(aom_static PRIVATE $<TARGET_OBJECTS:${target_name}>) 75 endif() 76 77 # Add the new lib target to the global list of aom library targets. 78 list(APPEND AOM_LIB_TARGETS ${target_name}) 79 set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} PARENT_SCOPE) 80endfunction() 81 82# Adds sources in list named by $sources to $target and adds $flag to the 83# compile flags for each source file. 84function(add_intrinsics_source_to_target flag target sources) 85 target_sources(${target} PRIVATE ${${sources}}) 86 if(MSVC) 87 get_msvc_intrinsic_flag(${flag} "flag") 88 endif() 89 if(flag) 90 foreach(source ${${sources}}) 91 set_property(SOURCE ${source} APPEND PROPERTY COMPILE_FLAGS ${flag}) 92 endforeach() 93 endif() 94endfunction() 95 96# Writes object format for the current target to the var named by $out_format, 97# or terminates the build when the object format for the current target is 98# unknown. 99function(get_asm_obj_format out_format) 100 if("${AOM_TARGET_CPU}" STREQUAL "x86_64") 101 if("${AOM_TARGET_SYSTEM}" STREQUAL "Darwin") 102 set(objformat "macho64") 103 elseif("${AOM_TARGET_SYSTEM}" STREQUAL "MSYS" 104 OR "${AOM_TARGET_SYSTEM}" STREQUAL "CYGWIN" 105 OR "${AOM_TARGET_SYSTEM}" STREQUAL "Windows") 106 set(objformat "win64") 107 else() 108 set(objformat "elf64") 109 endif() 110 elseif("${AOM_TARGET_CPU}" STREQUAL "x86") 111 if("${AOM_TARGET_SYSTEM}" STREQUAL "Darwin") 112 set(objformat "macho32") 113 elseif("${AOM_TARGET_SYSTEM}" STREQUAL "MSYS" 114 OR "${AOM_TARGET_SYSTEM}" STREQUAL "CYGWIN" 115 OR "${AOM_TARGET_SYSTEM}" STREQUAL "Windows") 116 set(objformat "win32") 117 else() 118 set(objformat "elf32") 119 endif() 120 else() 121 message( 122 FATAL_ERROR "Unknown obj format: ${AOM_TARGET_CPU}-${AOM_TARGET_SYSTEM}") 123 endif() 124 125 set(${out_format} ${objformat} PARENT_SCOPE) 126endfunction() 127 128# Adds library target named $lib_name for ASM files in variable named by 129# $asm_sources. Builds an output directory path from $lib_name. Links $lib_name 130# into the aom library target(s). Generates a dummy C file with a dummy function 131# to ensure that all cmake generators can determine the linker language, and 132# that build tools don't complain that an object exposes no symbols. 133function(add_asm_library lib_name asm_sources) 134 if("${${asm_sources}}" STREQUAL "") 135 return() 136 endif() 137 set(asm_lib_obj_dir "${AOM_CONFIG_DIR}/asm_objects/${lib_name}") 138 if(NOT EXISTS "${asm_lib_obj_dir}") 139 file(MAKE_DIRECTORY "${asm_lib_obj_dir}") 140 endif() 141 142 # TODO(tomfinegan): If cmake ever allows addition of .o files to OBJECT lib 143 # targets, make this OBJECT instead of STATIC to hide the target from 144 # consumers of the AOM cmake build. 145 add_library(${lib_name} STATIC ${${asm_sources}}) 146 set_property(TARGET ${lib_name} PROPERTY FOLDER ${AOM_TARGET_CPU}) 147 148 foreach(asm_source ${${asm_sources}}) 149 get_filename_component(asm_source_name "${asm_source}" NAME) 150 set(asm_object "${asm_lib_obj_dir}/${asm_source_name}.o") 151 add_custom_command(OUTPUT "${asm_object}" 152 COMMAND ${AS_EXECUTABLE} ARGS ${AOM_AS_FLAGS} 153 -I${AOM_ROOT}/ -I${AOM_CONFIG_DIR}/ -o 154 "${asm_object}" "${asm_source}" 155 DEPENDS "${asm_source}" 156 COMMENT "Building ASM object ${asm_object}" 157 WORKING_DIRECTORY "${AOM_CONFIG_DIR}" 158 VERBATIM) 159 target_sources(aom PRIVATE "${asm_object}") 160 if(BUILD_SHARED_LIBS) 161 target_sources(aom_static PRIVATE "${asm_object}") 162 endif() 163 endforeach() 164 165 # The above created a target containing only ASM sources. Cmake needs help 166 # here to determine the linker language. Add a dummy C file to force the 167 # linker language to C. We don't bother with setting the LINKER_LANGUAGE 168 # property on the library target because not all generators obey it (looking 169 # at you, xcode generator). 170 add_dummy_source_file_to_target("${lib_name}" "c") 171 172 # Add the new lib target to the global list of aom library targets. 173 list(APPEND AOM_LIB_TARGETS ${lib_name}) 174 set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} PARENT_SCOPE) 175endfunction() 176 177# Terminates generation if nasm found in PATH does not meet requirements. 178# Currently checks only for presence of required object formats and support for 179# the -Ox argument (multipass optimization). 180function(test_nasm) 181 execute_process(COMMAND ${AS_EXECUTABLE} -hf OUTPUT_VARIABLE nasm_helptext) 182 183 if(NOT "${nasm_helptext}" MATCHES "-Ox") 184 message( 185 FATAL_ERROR "Unsupported nasm: multipass optimization not supported.") 186 endif() 187 188 if("${AOM_TARGET_CPU}" STREQUAL "x86") 189 if("${AOM_TARGET_SYSTEM}" STREQUAL "Darwin") 190 if(NOT "${nasm_helptext}" MATCHES "macho32") 191 message( 192 FATAL_ERROR "Unsupported nasm: macho32 object format not supported.") 193 endif() 194 elseif("${AOM_TARGET_SYSTEM}" STREQUAL "MSYS" 195 OR "${AOM_TARGET_SYSTEM}" STREQUAL "Windows") 196 if(NOT "${nasm_helptext}" MATCHES "win32") 197 message( 198 FATAL_ERROR "Unsupported nasm: win32 object format not supported.") 199 endif() 200 else() 201 if(NOT "${nasm_helptext}" MATCHES "elf32") 202 message( 203 FATAL_ERROR "Unsupported nasm: elf32 object format not supported.") 204 endif() 205 endif() 206 else() 207 if("${AOM_TARGET_SYSTEM}" STREQUAL "Darwin") 208 if(NOT "${nasm_helptext}" MATCHES "macho64") 209 message( 210 FATAL_ERROR "Unsupported nasm: macho64 object format not supported.") 211 endif() 212 elseif("${AOM_TARGET_SYSTEM}" STREQUAL "MSYS" 213 OR "${AOM_TARGET_SYSTEM}" STREQUAL "Windows") 214 if(NOT "${nasm_helptext}" MATCHES "win64") 215 message( 216 FATAL_ERROR "Unsupported nasm: win64 object format not supported.") 217 endif() 218 else() 219 if(NOT "${nasm_helptext}" MATCHES "elf64") 220 message( 221 FATAL_ERROR "Unsupported nasm: elf64 object format not supported.") 222 endif() 223 endif() 224 endif() 225endfunction() 226 227# Adds build command for generation of rtcd C source files using 228# build/cmake/rtcd.pl. $config is the input perl file, $output is the output C 229# include file, $source is the C source file, and $symbol is used for the symbol 230# argument passed to rtcd.pl. 231function(add_rtcd_build_step config output source symbol) 232 add_custom_command( 233 OUTPUT ${output} 234 COMMAND ${PERL_EXECUTABLE} ARGS "${AOM_ROOT}/build/cmake/rtcd.pl" 235 --arch=${AOM_TARGET_CPU} 236 --sym=${symbol} ${AOM_RTCD_FLAGS} 237 --config=${AOM_CONFIG_DIR}/config/aom_config.h ${config} > ${output} 238 DEPENDS ${config} 239 COMMENT "Generating ${output}" 240 WORKING_DIRECTORY ${AOM_CONFIG_DIR} 241 VERBATIM) 242 set_property(SOURCE ${source} PROPERTY OBJECT_DEPENDS ${output}) 243 set_property(SOURCE ${output} PROPERTY GENERATED TRUE) 244endfunction() 245