blob: e2b0ba07e3c87c707fde037f19c789cc455fac08 [file] [log] [blame]
Tom Finegan50c5a7e2017-01-31 21:36:56 -08001##
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
5## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6## was not distributed with this source code in the LICENSE file, you can
7## obtain it at www.aomedia.org/license/software. If the Alliance for Open
8## Media Patent License 1.0 was not distributed with this source code in the
9## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10##
Tom Finegan285dedb2017-03-13 14:05:03 -070011if (NOT AOM_BUILD_CMAKE_AOM_OPTIMIZATION_CMAKE_)
12set(AOM_BUILD_CMAKE_AOM_OPTIMIZATION_CMAKE_ 1)
Tom Finegan50c5a7e2017-01-31 21:36:56 -080013
Tom Finegan87fdc282017-02-10 10:30:28 -080014# Translate $flag to one which MSVC understands, and write the new flag to the
15# variable named by $translated_flag (or unset it, when MSVC needs no flag).
16function (get_msvc_intrinsic_flag flag translated_flag)
Tom Finegan0b3c9052017-02-14 11:04:56 -080017 if ("${flag}" STREQUAL "-mavx")
18 set(${translated_flag} "/arch:AVX" PARENT_SCOPE)
Tom Finegan87fdc282017-02-10 10:30:28 -080019 elseif ("${flag}" STREQUAL "-mavx2")
20 set(${translated_flag} "/arch:AVX2" PARENT_SCOPE)
21 else ()
Tom Finegan0b3c9052017-02-14 11:04:56 -080022 # MSVC does not need flags for intrinsics flavors other than AVX/AVX2.
23 unset(${translated_flag} PARENT_SCOPE)
Tom Finegan87fdc282017-02-10 10:30:28 -080024 endif ()
25endfunction ()
26
Tom Finegan50c5a7e2017-01-31 21:36:56 -080027# Adds an object library target. Terminates generation if $flag is not supported
28# by the current compiler. $flag is the intrinsics flag required by the current
29# compiler, and is added to the compile flags for all sources in $sources.
30# $opt_name is used to name the target. $target_to_update is made
31# dependent upon the created target.
32#
33# Note: the libaom target is always updated because OBJECT libraries have rules
34# that disallow the direct addition of .o files to them as dependencies. Static
35# libraries do not have this limitation.
36function (add_intrinsics_object_library flag opt_name target_to_update sources)
Tom Finegan50c5a7e2017-01-31 21:36:56 -080037 set(target_name ${target_to_update}_${opt_name}_intrinsics)
38 add_library(${target_name} OBJECT ${${sources}})
Tom Finegan87fdc282017-02-10 10:30:28 -080039
40 if (MSVC)
41 get_msvc_intrinsic_flag(${flag} "flag")
42 endif ()
43
44 if (flag)
45 target_compile_options(${target_name} PUBLIC ${flag})
46 endif ()
47
Tom Finegan50c5a7e2017-01-31 21:36:56 -080048 target_sources(aom PUBLIC $<TARGET_OBJECTS:${target_name}>)
Tom Finegana0c21f02017-02-01 11:11:09 -080049
50 # Add the new lib target to the global list of aom library targets.
51 list(APPEND AOM_LIB_TARGETS ${target_name})
52 set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} PARENT_SCOPE)
Tom Finegan50c5a7e2017-01-31 21:36:56 -080053endfunction ()
54
Tom Finegane0578d12017-02-02 14:39:47 -080055# Adds sources in list named by $sources to $target and adds $flag to the
56# compile flags for each source file.
57function (add_intrinsics_source_to_target flag target sources)
Tom Finegane0578d12017-02-02 14:39:47 -080058 target_sources(${target} PUBLIC ${${sources}})
Tom Finegan87fdc282017-02-10 10:30:28 -080059 if (MSVC)
60 get_msvc_intrinsic_flag(${flag} "flag")
61 endif ()
62 if (flag)
63 foreach (source ${${sources}})
64 set_property(SOURCE ${source} APPEND PROPERTY COMPILE_FLAGS ${flag})
65 endforeach ()
66 endif ()
Tom Finegane0578d12017-02-02 14:39:47 -080067endfunction ()
68
Tom Finegan87fdc282017-02-10 10:30:28 -080069# Writes object format for the current target to the var named by $out_format,
70# or terminates the build when the object format for the current target is
71# unknown.
72function (get_asm_obj_format out_format)
73 if ("${AOM_TARGET_CPU}" STREQUAL "x86_64")
74 if ("${AOM_TARGET_SYSTEM}" STREQUAL "Darwin")
75 set(objformat "macho64")
76 elseif ("${AOM_TARGET_SYSTEM}" STREQUAL "Linux")
77 set(objformat "elf64")
78 elseif ("${AOM_TARGET_SYSTEM}" STREQUAL "Windows")
79 set(objformat "win64")
80 else ()
81 message(FATAL_ERROR "Unknown obj format: ${AOM_TARGET_SYSTEM}")
82 endif ()
Tom Finegan1ba9bd82017-02-14 11:08:38 -080083 elseif ("${AOM_TARGET_CPU}" STREQUAL "x86")
Tom Fineganf769c4e2017-02-15 14:37:29 -080084 if ("${AOM_TARGET_SYSTEM}" STREQUAL "Darwin")
85 set(objformat "macho32")
Tom Finegan1264fde2017-02-15 15:40:00 -080086 elseif ("${AOM_TARGET_SYSTEM}" STREQUAL "Linux")
87 set(objformat "elf32")
Tom Fineganf769c4e2017-02-15 14:37:29 -080088 elseif ("${AOM_TARGET_SYSTEM}" STREQUAL "Windows")
Tom Finegan1ba9bd82017-02-14 11:08:38 -080089 set(objformat "win32")
90 else ()
91 message(FATAL_ERROR "Unknown obj format: ${AOM_TARGET_SYSTEM}")
92 endif ()
Tom Finegan50c5a7e2017-01-31 21:36:56 -080093 else ()
94 message(FATAL_ERROR
95 "Unknown obj format: ${AOM_TARGET_CPU}-${AOM_TARGET_SYSTEM}")
96 endif ()
97
Tom Finegan87fdc282017-02-10 10:30:28 -080098 set(${out_format} ${objformat} PARENT_SCOPE)
99endfunction ()
100
101# Adds library target named $lib_name for ASM files in variable named by
102# $asm_sources. Builds an output directory path from $lib_name. Links $lib_name
103# into $dependent_target. Generates a dummy C file with a dummy function to
104# ensure that all cmake generators can determine the linker language, and that
105# build tools don't complain that an object exposes no symbols.
106function (add_asm_library lib_name asm_sources dependent_target)
107 set(asm_lib_obj_dir "${AOM_CONFIG_DIR}/asm_objects/${lib_name}")
108 if (NOT EXISTS "${asm_lib_obj_dir}")
109 file(MAKE_DIRECTORY "${asm_lib_obj_dir}")
110 endif ()
111
112 # TODO(tomfinegan): If cmake ever allows addition of .o files to OBJECT lib
113 # targets, make this OBJECT instead of STATIC to hide the target from
114 # consumers of the AOM cmake build.
115 add_library(${lib_name} STATIC ${${asm_sources}})
116
Tom Finegan87fdc282017-02-10 10:30:28 -0800117 foreach (asm_source ${${asm_sources}})
Tom Finegan50c5a7e2017-01-31 21:36:56 -0800118 get_filename_component(asm_source_name "${asm_source}" NAME)
Tom Finegan87fdc282017-02-10 10:30:28 -0800119 set(asm_object "${asm_lib_obj_dir}/${asm_source_name}.o")
Tom Finegan50c5a7e2017-01-31 21:36:56 -0800120 add_custom_command(OUTPUT "${asm_object}"
Tom Finegan285dedb2017-03-13 14:05:03 -0700121 COMMAND ${AS_EXECUTABLE}
Tom Finegan85ef2342017-02-22 15:11:38 -0800122 ARGS ${AOM_AS_FLAGS}
Tom Finegan50c5a7e2017-01-31 21:36:56 -0800123 -I${AOM_ROOT} -I${AOM_CONFIG_DIR}
124 -o "${asm_object}" "${asm_source}"
125 DEPENDS "${asm_source}"
126 COMMENT "Building ASM object ${asm_object}"
127 WORKING_DIRECTORY "${AOM_CONFIG_DIR}"
128 VERBATIM)
Tom Finegan87fdc282017-02-10 10:30:28 -0800129 target_sources(${lib_name} PRIVATE "${asm_object}")
Tom Finegan50c5a7e2017-01-31 21:36:56 -0800130 endforeach ()
Tom Finegan87fdc282017-02-10 10:30:28 -0800131
132 # The above created a target containing only ASM sources. Cmake needs help
133 # here to determine the linker language. Add a dummy C file to force the
134 # linker language to C. We don't bother with setting the LINKER_LANGUAGE
135 # property on the library target because not all generators obey it (looking
136 # at you, xcode generator).
137 set(dummy_c_file "${AOM_CONFIG_DIR}/${lib_name}_dummy.c")
138 file(WRITE "${dummy_c_file}"
139 "// Generated file. DO NOT EDIT!\n"
140 "// ${lib_name} needs C file to force link language, ignore me.\n"
141 "void ${lib_name}_dummy_function(void) {}\n")
142 target_sources(${lib_name} PUBLIC ${dummy_c_file})
143
144 target_link_libraries(${dependent_target} PRIVATE ${lib_name})
Tom Finegan1ba9bd82017-02-14 11:08:38 -0800145
146 # Add the new lib target to the global list of aom library targets.
147 list(APPEND AOM_LIB_TARGETS ${lib_name})
148 set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} PARENT_SCOPE)
Tom Finegan50c5a7e2017-01-31 21:36:56 -0800149endfunction ()
Tom Finegan285dedb2017-03-13 14:05:03 -0700150
Tom Finegan97d29ea2017-03-16 18:34:17 -0700151# Converts asm sources in $asm_sources using $AOM_ADS2GAS and calls
152# add_asm_library() to create a library from the converted sources. At
153# generation time the converted sources are created, and a custom rule is added
154# to ensure the sources are reconverted when the original asm source is updated.
155# See add_asm_library() for more information.
156function (add_gas_asm_library lib_name asm_sources dependent_target)
157 set(asm_converted_source_dir "${AOM_CONFIG_DIR}/asm_gas/${lib_name}")
158 if (NOT EXISTS "${asm_converted_source_dir}")
159 file(MAKE_DIRECTORY "${asm_converted_source_dir}")
160 endif ()
161
162 # Create the converted version of each assembly source at generation time.
163 unset(gas_target_sources)
164 foreach (neon_asm_source ${${asm_sources}})
165 get_filename_component(output_asm_source "${neon_asm_source}" NAME)
166 set(output_asm_source "${asm_converted_source_dir}/${output_asm_source}")
167 set(output_asm_source "${output_asm_source}.${AOM_GAS_EXT}")
168 execute_process(COMMAND "${PERL_EXECUTABLE}" "${AOM_ADS2GAS}"
169 INPUT_FILE "${neon_asm_source}"
170 OUTPUT_FILE "${output_asm_source}")
171 list(APPEND gas_target_sources "${output_asm_source}")
172 endforeach ()
173
174 add_asm_library("${lib_name}" "gas_target_sources" "${dependent_target}")
175
176 # For each of the converted sources, create a custom rule that will regenerate
177 # the converted source when its input is touched.
178 list(LENGTH gas_target_sources num_asm_files)
179 math(EXPR num_asm_files "${num_asm_files} - 1")
180 foreach(NUM RANGE ${num_asm_files})
181 list(GET ${asm_sources} ${NUM} neon_asm_source)
182 list(GET gas_target_sources ${NUM} gas_asm_source)
183
184 # Grab only the filename for the custom command output to keep build output
185 # reasonably sane.
186 get_filename_component(neon_name "${neon_asm_source}" NAME)
187 get_filename_component(gas_name "${gas_asm_source}" NAME)
188
189 add_custom_command(
190 OUTPUT "${gas_asm_source}"
191 COMMAND ${PERL_EXECUTABLE}
192 ARGS "${AOM_ADS2GAS}" < "${neon_asm_source}" > "${gas_asm_source}"
193 DEPENDS "${neon_asm_source}"
194 COMMENT "ads2gas conversion ${neon_name} -> ${gas_name}"
195 WORKING_DIRECTORY "${AOM_CONFIG_DIR}"
196 VERBATIM)
197 endforeach ()
198
199 # Update the sources list passed in to include the converted asm source files.
200 list(APPEND asm_sources ${gas_target_sources})
201 set(${asm_sources} ${${asm_sources}} PARENT_SCOPE)
202endfunction ()
203
Tom Finegan285dedb2017-03-13 14:05:03 -0700204endif () # AOM_BUILD_CMAKE_AOM_OPTIMIZATION_CMAKE_