• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
133#
134# In shared library configs every step described above happens twice, and
135# directory/target/object names are updated to include _shared and _static
136# suffixes.
137function(add_asm_library lib_name asm_sources)
138  if("${${asm_sources}}" STREQUAL "")
139    return()
140  endif()
141
142  list(APPEND asm_configs "static")
143  if(BUILD_SHARED_LIBS)
144    list(APPEND asm_configs "shared")
145  endif()
146
147  foreach(asm_config ${asm_configs})
148    set(asm_lib_name ${lib_name}_${asm_config})
149    set(asm_lib_obj_dir "${AOM_CONFIG_DIR}/asm_objects/${asm_lib_name}")
150    if(NOT EXISTS "${asm_lib_obj_dir}")
151      file(MAKE_DIRECTORY "${asm_lib_obj_dir}")
152    endif()
153
154    add_library(${asm_lib_name} STATIC ${${asm_sources}})
155    set_property(TARGET ${asm_lib_name} PROPERTY FOLDER ${AOM_TARGET_CPU})
156
157    foreach(asm_source ${${asm_sources}})
158      get_filename_component(asm_source_name "${asm_source}" NAME)
159      set(asm_object "${asm_lib_obj_dir}/${asm_source_name}.o")
160      add_custom_command(OUTPUT "${asm_object}"
161                         COMMAND ${AS_EXECUTABLE} ARGS ${AOM_AS_FLAGS}
162                                 -I${AOM_ROOT}/ -I${AOM_CONFIG_DIR}/ -o
163                                 "${asm_object}" "${asm_source}"
164                         DEPENDS "${asm_source}"
165                         COMMENT "Building ASM object ${asm_object}"
166                         WORKING_DIRECTORY "${AOM_CONFIG_DIR}"
167                         VERBATIM)
168      if(BUILD_SHARED_LIBS AND "${asm_config}" STREQUAL "static")
169        target_sources(aom_static PRIVATE "${asm_object}")
170      else()
171        target_sources(aom PRIVATE "${asm_object}")
172      endif()
173    endforeach()
174
175    # The above created a target containing only ASM sources. CMake needs help
176    # here to determine the linker language. Add a dummy C file to force the
177    # linker language to C. We don't bother with setting the LINKER_LANGUAGE
178    # property on the library target because not all generators obey it (looking
179    # at you, Xcode generator).
180    add_dummy_source_file_to_target("${asm_lib_name}" "c")
181
182    # Add the new lib target to the global list of aom library targets.
183    list(APPEND AOM_LIB_TARGETS ${asm_lib_name})
184  endforeach()
185
186  set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} PARENT_SCOPE)
187endfunction()
188
189# Terminates generation if nasm found in PATH does not meet requirements.
190# Currently checks only for presence of required object formats and support for
191# the -Ox argument (multipass optimization).
192function(test_nasm)
193  execute_process(COMMAND ${AS_EXECUTABLE} -hf OUTPUT_VARIABLE nasm_helptext)
194
195  if(NOT "${nasm_helptext}" MATCHES "-Ox")
196    message(
197      FATAL_ERROR "Unsupported nasm: multipass optimization not supported.")
198  endif()
199
200  if("${AOM_TARGET_CPU}" STREQUAL "x86")
201    if("${AOM_TARGET_SYSTEM}" STREQUAL "Darwin")
202      if(NOT "${nasm_helptext}" MATCHES "macho32")
203        message(
204          FATAL_ERROR "Unsupported nasm: macho32 object format not supported.")
205      endif()
206    elseif("${AOM_TARGET_SYSTEM}" STREQUAL "MSYS"
207           OR "${AOM_TARGET_SYSTEM}" STREQUAL "Windows")
208      if(NOT "${nasm_helptext}" MATCHES "win32")
209        message(
210          FATAL_ERROR "Unsupported nasm: win32 object format not supported.")
211      endif()
212    else()
213      if(NOT "${nasm_helptext}" MATCHES "elf32")
214        message(
215          FATAL_ERROR "Unsupported nasm: elf32 object format not supported.")
216      endif()
217    endif()
218  else()
219    if("${AOM_TARGET_SYSTEM}" STREQUAL "Darwin")
220      if(NOT "${nasm_helptext}" MATCHES "macho64")
221        message(
222          FATAL_ERROR "Unsupported nasm: macho64 object format not supported.")
223      endif()
224    elseif("${AOM_TARGET_SYSTEM}" STREQUAL "MSYS"
225           OR "${AOM_TARGET_SYSTEM}" STREQUAL "Windows")
226      if(NOT "${nasm_helptext}" MATCHES "win64")
227        message(
228          FATAL_ERROR "Unsupported nasm: win64 object format not supported.")
229      endif()
230    else()
231      if(NOT "${nasm_helptext}" MATCHES "elf64")
232        message(
233          FATAL_ERROR "Unsupported nasm: elf64 object format not supported.")
234      endif()
235    endif()
236  endif()
237endfunction()
238
239# Adds build command for generation of rtcd C source files using
240# build/cmake/rtcd.pl. $config is the input perl file, $output is the output C
241# include file, $source is the C source file, and $symbol is used for the symbol
242# argument passed to rtcd.pl.
243function(add_rtcd_build_step config output source symbol)
244  add_custom_command(
245    OUTPUT ${output}
246    COMMAND ${PERL_EXECUTABLE} ARGS "${AOM_ROOT}/build/cmake/rtcd.pl"
247            --arch=${AOM_TARGET_CPU}
248            --sym=${symbol} ${AOM_RTCD_FLAGS}
249            --config=${AOM_CONFIG_DIR}/config/aom_config.h ${config} > ${output}
250    DEPENDS ${config}
251    COMMENT "Generating ${output}"
252    WORKING_DIRECTORY ${AOM_CONFIG_DIR}
253    VERBATIM)
254  set_property(SOURCE ${source} PROPERTY OBJECT_DEPENDS ${output})
255  set_property(SOURCE ${output} PROPERTY GENERATED TRUE)
256endfunction()
257