Skip to content

Commit d721d69

Browse files
larryliu0820facebook-github-bot
authored andcommitted
Decentralize portable lib cmake build file
Summary: Split out `portable_kernels_bindings` library build code from root `CMakeLists.txt` to `kernels/portable/CMakeLists.txt`. This makes the root `CMakeLists.txt` a bit simpler. Also making the linker options a bit more portable. Differential Revision: D48712541 fbshipit-source-id: a25fdca729d870437e3e211a0a0daf241a72188f
1 parent 7299bf3 commit d721d69

File tree

6 files changed

+148
-144
lines changed

6 files changed

+148
-144
lines changed

CMakeLists.txt

Lines changed: 4 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -174,102 +174,14 @@ target_include_directories(executorch PUBLIC ${_common_include_directories})
174174
target_compile_options(executorch PUBLIC ${_common_compile_options})
175175

176176
#
177-
# portable_kernels: Pure-C++ kernel library for ATen ops
178-
#
179-
# Focused on portability and understandability rather than speed.
180-
#
181-
182-
add_library(portable_kernels ${_portable_kernels__srcs})
183-
target_link_libraries(portable_kernels PRIVATE executorch)
184-
target_compile_options(portable_kernels PUBLIC ${_common_compile_options})
185-
186-
#
187-
# portable_kernels_bindings: Bindings and registration for all ops defined in
188-
# kernels/portable/functions.yaml
177+
# portable_ops_lib: A library to register core ATen ops using portable kernels,
178+
# see kernels/portable/CMakeLists.txt.
189179
#
190180
# Real integrations should supply their own YAML file that only lists the
191181
# operators necessary for the models that will run.
192182
#
193-
# TODO(dbort): Make it possible to provide a custom YAML file. It will be easier
194-
# once we stop using buck2 for this step.
195-
#
196-
197-
set(_portable_kernels_bindings__generated_files
198-
# Although the codegen tool generates more files, these are the only ones we
199-
# need for non-custom kernels.
200-
NativeFunctions.h RegisterCodegenUnboxedKernelsEverything.cpp)
201-
202-
set(_portable_kernels_bindings__output_dir
203-
"${CMAKE_CURRENT_BINARY_DIR}/portable_kernels_bindings")
204-
205-
# Paths to files generated by the codegen step.
206-
set(_portable_kernels_bindings__outputs)
207-
foreach(gen ${_portable_kernels_bindings__generated_files})
208-
list(APPEND _portable_kernels_bindings__outputs
209-
"${_portable_kernels_bindings__output_dir}/${gen}")
210-
endforeach()
211-
212-
set(_portable_kernels_bindings__cpp_files
213-
${_portable_kernels_bindings__outputs})
214-
list(FILTER _portable_kernels_bindings__cpp_files INCLUDE REGEX "[.]cpp$")
215-
216-
# Build the generated files.
217-
#
218-
# NOTE: This will only happen once during cmake setup, so it will not re-run if
219-
# the functions.yaml file changes. TODO(dbort): Stop using buck2 to do this. Use
220-
# add_custom_command() to run the codegen tool directly.
221-
message(STATUS "portable_kernels_bindings: Generating bindings")
222-
execute_process(
223-
COMMAND ${BUCK2} build //kernels/portable:generated_lib_combined --show-output
224-
OUTPUT_VARIABLE buck_output
225-
ERROR_VARIABLE buck_error
226-
RESULT_VARIABLE buck_exit_code
227-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
228-
if(buck_exit_code EQUAL 0)
229-
# The output will look like
230-
# ~~~
231-
# root//kernels/portable:generated_lib_combined buck-out/<path-we-want>
232-
# ~~~
233-
# Extract the second field while avoiding trailing whitespace.
234-
string(REGEX MATCH "buck-out/[^ \t\r\n]*" srcdir ${buck_output})
235-
236-
# Assemble the list of source files, which live under the buck output dir.
237-
set(_srcfiles)
238-
foreach(gen ${_portable_kernels_bindings__generated_files})
239-
list(APPEND _srcfiles "${CMAKE_CURRENT_SOURCE_DIR}/${srcdir}/${gen}")
240-
endforeach()
241-
242-
file(MAKE_DIRECTORY ${_portable_kernels_bindings__output_dir})
243-
file(COPY ${_srcfiles} DESTINATION ${_portable_kernels_bindings__output_dir})
244-
message(STATUS "portable_kernels_bindings: "
245-
"Copied files to ${_portable_kernels_bindings__output_dir}")
246-
else()
247-
message(
248-
"Error occurred while executing buck2 command. Exit code: ${buck_exit_code}"
249-
)
250-
message("Buck2 Output:\n${buck_output}")
251-
message("Buck2 Error:\n${buck_error}")
252-
message(FATAL_ERROR "portable_kernels_bindings: codegen failed")
253-
endif()
254-
255-
add_library(portable_kernels_bindings)
256-
target_sources(portable_kernels_bindings
257-
PRIVATE ${_portable_kernels_bindings__cpp_files})
258-
target_link_libraries(portable_kernels_bindings PRIVATE executorch)
259-
target_link_libraries(portable_kernels_bindings INTERFACE portable_kernels)
260-
261-
# Ensure that the load-time constructor functions run. By default, the linker
262-
# would remove them since there are no other references to them.
263-
if(APPLE)
264-
macos_kernel_link_options(portable_kernels_bindings)
265-
else()
266-
kernel_link_options(portable_kernels_bindings)
267-
endif()
268-
269-
#
270-
# executor_runner: A simple commandline tool that loads and runs a program file.
271-
#
272-
set(_libs executorch portable_kernels_bindings gflags)
183+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/kernels/portable)
184+
set(_libs executorch portable_ops_lib gflags)
273185

274186
# Generate custom_ops_lib based on REGISTER_EXAMPLE_CUSTOM_OP
275187
if(REGISTER_EXAMPLE_CUSTOM_OP EQUAL 1 OR REGISTER_EXAMPLE_CUSTOM_OP EQUAL 2)

build/Codegen.cmake

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -101,31 +101,20 @@ function(gen_custom_ops_aot_lib lib_name kernel_sources)
101101

102102
include(${EXECUTORCH_ROOT}/build/Utils.cmake)
103103

104-
# Ensure that the load-time constructor functions run. By default, the linker
105-
# would remove them since there are no other references to them.
106-
if(APPLE)
107-
macos_kernel_link_options(${lib_name})
108-
else()
109-
kernel_link_options(${lib_name})
110-
endif()
104+
target_link_options_shared_lib(${lib_name})
111105
endfunction()
112106

113107
# Generate a runtime lib for registering operators in Executorch
114-
function(gen_operators_lib lib_name kernel_sources)
115-
add_library(
116-
${lib_name} SHARED
117-
${CMAKE_CURRENT_BINARY_DIR}/RegisterCodegenUnboxedKernelsEverything.cpp
118-
${CMAKE_CURRENT_BINARY_DIR}/Functions.h
119-
${CMAKE_CURRENT_BINARY_DIR}/NativeFunctions.h ${kernel_sources})
120-
target_link_libraries(${lib_name} PRIVATE executorch)
121-
122-
include(${EXECUTORCH_ROOT}/build/Utils.cmake)
108+
function(gen_operators_lib lib_name kernel_lib deps)
109+
add_library(${lib_name})
110+
target_sources(
111+
${lib_name}
112+
PRIVATE
113+
${CMAKE_CURRENT_BINARY_DIR}/RegisterCodegenUnboxedKernelsEverything.cpp
114+
${CMAKE_CURRENT_BINARY_DIR}/Functions.h
115+
${CMAKE_CURRENT_BINARY_DIR}/NativeFunctions.h)
116+
target_link_libraries(${lib_name} PRIVATE ${deps})
117+
target_link_libraries(${lib_name} INTERFACE ${kernel_lib})
123118

124-
# Ensure that the load-time constructor functions run. By default, the linker
125-
# would remove them since there are no other references to them.
126-
if(APPLE)
127-
macos_kernel_link_options(${lib_name})
128-
else()
129-
kernel_link_options(${lib_name})
130-
endif()
119+
target_link_options_shared_lib(${lib_name})
131120
endfunction()

build/Utils.cmake

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,74 @@
44
# This source code is licensed under the BSD-style license found in the
55
# LICENSE file in the root directory of this source tree.
66

7-
# This file is intended to have helper functions to keep the CMakeLists.txt concise. If there are any helper function can be re-used, it's recommented to add them here.
7+
# This file is intended to have helper functions to keep the CMakeLists.txt
8+
# concise. If there are any helper function can be re-used, it's recommented to
9+
# add them here.
810

9-
10-
# Public function to print summary for all configurations. For new variable, it's recommended to add them here.
11+
# Public function to print summary for all configurations. For new variable,
12+
# it's recommended to add them here.
1113
function(executorch_print_configuration_summary)
12-
message(STATUS "")
13-
message(STATUS "******** Summary ********")
14-
message(STATUS " BUCK : ${BUCK2}")
15-
message(STATUS " CMAKE_CXX_STANDARD : ${CMAKE_CXX_STANDARD}")
16-
message(STATUS " CMAKE_CXX_COMPILER_ID : ${CMAKE_CXX_COMPILER_ID}")
17-
message(STATUS " CMAKE_TOOLCHAIN_FILE : ${CMAKE_TOOLCHAIN_FILE}")
18-
message(STATUS " FLATBUFFERS_BUILD_FLATC : ${FLATBUFFERS_BUILD_FLATC}")
19-
message(STATUS " FLATBUFFERS_BUILD_FLATHASH : ${FLATBUFFERS_BUILD_FLATHASH}")
20-
message(STATUS " FLATBUFFERS_BUILD_FLATLIB : ${FLATBUFFERS_BUILD_FLATLIB}")
21-
message(STATUS " FLATBUFFERS_BUILD_TESTS : ${FLATBUFFERS_BUILD_TESTS}")
22-
message(STATUS " REGISTER_EXAMPLE_CUSTOM_OPS : ${REGISTER_EXAMPLE_CUSTOM_OPS}")
14+
message(STATUS "")
15+
message(STATUS "******** Summary ********")
16+
message(STATUS " BUCK : ${BUCK2}")
17+
message(STATUS " CMAKE_CXX_STANDARD : ${CMAKE_CXX_STANDARD}")
18+
message(STATUS " CMAKE_CXX_COMPILER_ID : ${CMAKE_CXX_COMPILER_ID}")
19+
message(STATUS " CMAKE_TOOLCHAIN_FILE : ${CMAKE_TOOLCHAIN_FILE}")
20+
message(STATUS " FLATBUFFERS_BUILD_FLATC : ${FLATBUFFERS_BUILD_FLATC}")
21+
message(
22+
STATUS " FLATBUFFERS_BUILD_FLATHASH : ${FLATBUFFERS_BUILD_FLATHASH}")
23+
message(
24+
STATUS " FLATBUFFERS_BUILD_FLATLIB : ${FLATBUFFERS_BUILD_FLATLIB}")
25+
message(STATUS " FLATBUFFERS_BUILD_TESTS : ${FLATBUFFERS_BUILD_TESTS}")
26+
message(
27+
STATUS " REGISTER_EXAMPLE_CUSTOM_OPS : ${REGISTER_EXAMPLE_CUSTOM_OPS}")
2328
endfunction()
2429

25-
# This is the funtion to use -Wl, --whole-archive to link static library
30+
# This is the funtion to use -Wl, --whole-archive to link static library NB:
31+
# target_link_options is broken for this case, it only append the interface link
32+
# options of the first library.
2633
function(kernel_link_options target_name)
27-
target_link_options(${target_name}
28-
INTERFACE
29-
# TODO(dbort): This will cause the .a to show up on the link line twice
30-
-Wl,--whole-archive
31-
$<TARGET_FILE:${target_name}>
32-
-Wl,--no-whole-archive
33-
)
34+
# target_link_options(${target_name} INTERFACE
35+
# "$<LINK_LIBRARY:WHOLE_ARCHIVE,target_name>")
36+
target_link_options(
37+
${target_name}
38+
INTERFACE
39+
"SHELL:LINKER:--whole-archive $<TARGET_FILE:${target_name}> LINKER:--no-whole-archive"
40+
)
3441
endfunction()
3542

3643
function(macos_kernel_link_options target_name)
37-
target_link_options(${target_name}
38-
INTERFACE
39-
# Same as kernel_link_options but it's for MacOS linker
40-
-Wl,-force_load,$<TARGET_FILE:${target_name}>
41-
)
44+
target_link_options(
45+
${target_name} INTERFACE
46+
# Same as kernel_link_options but it's for MacOS linker
47+
"SHELL:LINKER:-force_load,$<TARGET_FILE:${target_name}>")
48+
endfunction()
49+
50+
function(target_link_options_shared_lib target_name)
51+
# Ensure that the load-time constructor functions run. By default, the linker
52+
# would remove them since there are no other references to them.
53+
if(APPLE)
54+
macos_kernel_link_options(${target_name})
55+
else()
56+
kernel_link_options(${target_name})
57+
endif()
58+
endfunction()
59+
60+
# Extract source files based on toml config. This is useful to keep buck2 and
61+
# cmake aligned.
62+
function(extract_sources sources_file)
63+
execute_process(
64+
COMMAND ${PYTHON_EXECUTABLE} build/extract_sources.py --buck2=${BUCK2}
65+
--config=build/cmake_deps.toml --out=${sources_file}
66+
OUTPUT_VARIABLE gen_srcs_output
67+
ERROR_VARIABLE gen_srcs_error
68+
RESULT_VARIABLE gen_srcs_exit_code
69+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
70+
if(NOT gen_srcs_exit_code EQUAL 0)
71+
message("Error while generating ${sources_file}. "
72+
"Exit code: ${gen_srcs_exit_code}")
73+
message("Output:\n${gen_srcs_output}")
74+
message("Error:\n${gen_srcs_error}")
75+
message(FATAL_ERROR "executorch: source list generation failed")
76+
endif()
4277
endfunction()

examples/custom_ops/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,9 @@ if(REGISTER_EXAMPLE_CUSTOM_OP EQUAL 1)
6666
elseif(REGISTER_EXAMPLE_CUSTOM_OP EQUAL 2)
6767
set(kernel_sources ${CMAKE_CURRENT_LIST_DIR}/custom_ops_2_out.cpp)
6868
endif()
69-
gen_operators_lib("custom_ops_lib" "${kernel_sources}")
69+
70+
add_library(custom_kernels ${kernel_sources})
71+
target_link_libraries(custom_kernels PRIVATE executorch)
72+
target_compile_options(custom_kernels PUBLIC ${_common_compile_options})
73+
74+
gen_operators_lib("custom_ops_lib" custom_kernels executorch)

kernels/portable/CMakeLists.txt

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# Kernel library for portable kernels. Please this file formatted by running:
8+
# ~~~
9+
# cmake-format --first-comment-is-literal=True CMakeLists.txt
10+
# ~~~
11+
12+
cmake_minimum_required(VERSION 3.19)
13+
14+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
15+
if(NOT CMAKE_CXX_STANDARD)
16+
set(CMAKE_CXX_STANDARD 17)
17+
endif()
18+
19+
if(NOT PYTHON_EXECUTABLE)
20+
set(PYTHON_EXECUTABLE python3)
21+
endif()
22+
# Source root directory for executorch.
23+
if(NOT EXECUTORCH_ROOT)
24+
set(EXECUTORCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)
25+
endif()
26+
# Source root directory for pytorch.
27+
if(NOT TORCH_ROOT)
28+
set(TORCH_ROOT ${EXECUTORCH_ROOT}/third-party/pytorch)
29+
endif()
30+
31+
set(_common_compile_options -Wno-deprecated-declarations)
32+
33+
include(${EXECUTORCH_ROOT}/build/Utils.cmake)
34+
include(${EXECUTORCH_ROOT}/build/Codegen.cmake)
35+
# Portable kernel sources TODO(larryliu0820): use buck2 to gather the sources
36+
file(GLOB_RECURSE _portable_kernels__srcs
37+
"${CMAKE_CURRENT_SOURCE_DIR}/cpu/*.cpp")
38+
list(FILTER _portable_kernels__srcs EXCLUDE REGEX "test/*.cpp")
39+
list(FILTER _portable_kernels__srcs EXCLUDE REGEX "codegen")
40+
# Generate C++ bindings to register kernels into both PyTorch (for AOT) and
41+
# Executorch (for runtime). Here select all ops in functions.yaml
42+
gen_selected_ops("${CMAKE_CURRENT_LIST_DIR}/functions.yaml" "" "")
43+
# Expect gen_selected_ops output file to be selected_operators.yaml
44+
generate_bindings_for_kernels(${CMAKE_CURRENT_SOURCE_DIR}/functions.yaml "")
45+
message("Generated files ${gen_command_sources}")
46+
47+
#
48+
# portable_kernels: Pure-C++ kernel library for ATen ops
49+
#
50+
# Focused on portability and understandability rather than speed.
51+
#
52+
add_library(portable_kernels ${_portable_kernels__srcs})
53+
target_link_libraries(portable_kernels PRIVATE executorch)
54+
target_compile_options(portable_kernels PUBLIC ${_common_compile_options})
55+
56+
# Build a library for _portable_kernels__srcs
57+
#
58+
# portable_ops_lib: Register portable_ops_lib ops kernels into Executorch
59+
# runtime
60+
gen_operators_lib("portable_ops_lib" portable_kernels executorch)

kernels/quantized/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ set(_quantized_sources
5050
)
5151
gen_custom_ops_aot_lib("quantized_ops_aot_lib" "${_quantized_sources}")
5252

53+
add_library(quantized_kernels ${_quantized_kernels__srcs})
54+
target_link_libraries(quantized_kernels PRIVATE executorch)
55+
target_compile_options(quantized_kernels PUBLIC ${_common_compile_options})
5356
# Build a library for _quantized_kernels_srcs
5457
#
5558
# quantized_ops_lib: Register quantized ops kernels into Executorch runtime
56-
gen_operators_lib("quantized_ops_lib" "${_quantized_kernels__srcs}")
59+
gen_operators_lib("quantized_ops_lib" quantized_kernels executorch)

0 commit comments

Comments
 (0)