Skip to content

Commit d2c3fe7

Browse files
larryliu0820facebook-github-bot
authored andcommitted
Install libexecutorch.a and libportable_kernels.a (#1036)
Summary: This PR is the first one to decentralize options only used by examples, from root level CMakeLists.txt to examples directories. To install these two libraries (`libexecutorch.a` and `libportable_kernels.a`), user needs to run: ``` cmake -DBUCK2="$BUCK" \ -DCMAKE_INSTALL_PREFIX=cmake-out \ -DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \ -Bcmake-out . cmake --build cmake-out -j9 --target install ``` Then in the console output we will have: ``` -- Installing: /home/larryliu/executorch/cmake-out/lib/libportable_kernels.a -- Installing: /home/larryliu/executorch/cmake-out/lib/libexecutorch.a -- Installing: /home/larryliu/executorch/cmake-out/lib/cmake/ExecuTorch/ExecuTorchConfig.cmake ``` In order to find these libraries, we can do the following in example CMakeLists.txt: ``` find_package(ExecuTorch REQUIRED) ``` Then the example CMakeLists.txt can depend on `executorch` and `portable_kernels`. Reviewed By: dbort Differential Revision: D50482400 Pulled By: larryliu0820
1 parent 7814dd7 commit d2c3fe7

File tree

6 files changed

+173
-68
lines changed

6 files changed

+173
-68
lines changed

CMakeLists.txt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ endif()
5454
if(NOT CMAKE_BUILD_TYPE)
5555
set(CMAKE_BUILD_TYPE Debug)
5656
endif()
57+
# ------------------------------ OPTIONS -------------------------------------
58+
# WARNING: Please don't add example specific options in this CMakeLists.txt.
59+
# Instead please use `find_package(executorch REQUIRED)` in the example
60+
# directory and add a new executable in the example `CMakeLists.txt`.
5761

5862
# _default_release_disabled_options: default value for options that should be
5963
# disabled in Release mode by default. Users can still manually enable them,
@@ -111,16 +115,9 @@ option(BUILD_SELECTIVE_BUILD_TEST
111115

112116
option(EXECUTORCH_BUILD_SIZE_TEST "Whether to build size test" OFF)
113117

114-
# Selective build options.
115-
option(EXECUTORCH_SELECT_ALL_OPS
116-
"Whether to register all ops defined in portable kernel library." ON)
117-
118118
# Option to register op list
119119
option(EXECUTORCH_SELECT_OPS_LIST "Register the following list of ops" OFF)
120120

121-
# Option to register ops from yaml file
122-
option(EXECUTORCH_SELECT_OPS_YAML "Register all the ops from a given yaml file"
123-
OFF)
124121
# Do not enable select all ops if any of the other select options is on.
125122
if(EXECUTORCH_SELECT_OPS_LIST OR EXECUTORCH_SELECT_OPS_YAML)
126123
set(EXECUTORCH_SELECT_ALL_OPS OFF)
@@ -281,6 +278,16 @@ if(EXECUTORCH_BUILD_GFLAGS)
281278
add_subdirectory(third-party/gflags)
282279
endif()
283280

281+
282+
# Install `executorch` library as well as `ExecuTorchConfig.cmake`
283+
# under ${CMAKE_INSTALL_PREFIX}/
284+
install(
285+
TARGETS executorch
286+
DESTINATION lib
287+
INCLUDES DESTINATION ${_common_include_directories}
288+
)
289+
install(FILES build/ExecuTorchConfig.cmake DESTINATION lib/cmake/ExecuTorch)
290+
284291
#
285292
# executor_runner: Host tool that demonstrates program execution.
286293
#

build/Utils.cmake

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -79,27 +79,37 @@ function(target_link_options_shared_lib target_name)
7979
endfunction()
8080

8181
# Extract source files based on toml config. This is useful to keep buck2 and
82-
# cmake aligned.
82+
# cmake aligned. Do not regenerate if file exists.
8383
function(extract_sources sources_file)
84-
if(EXECUTORCH_ROOT)
85-
set(executorch_root ${EXECUTORCH_ROOT})
84+
if(EXISTS "${sources_file}")
85+
message(STATUS "executorch: Using source file list ${sources_file}")
8686
else()
87-
set(executorch_root ${CMAKE_CURRENT_SOURCE_DIR})
88-
endif()
89-
execute_process(
90-
COMMAND
91-
${PYTHON_EXECUTABLE} ${executorch_root}/build/extract_sources.py
92-
--buck2=${BUCK2} --config=${executorch_root}/build/cmake_deps.toml
93-
--out=${sources_file}
94-
OUTPUT_VARIABLE gen_srcs_output
95-
ERROR_VARIABLE gen_srcs_error
96-
RESULT_VARIABLE gen_srcs_exit_code
97-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
98-
if(NOT gen_srcs_exit_code EQUAL 0)
99-
message("Error while generating ${sources_file}. "
100-
"Exit code: ${gen_srcs_exit_code}")
101-
message("Output:\n${gen_srcs_output}")
102-
message("Error:\n${gen_srcs_error}")
103-
message(FATAL_ERROR "executorch: source list generation failed")
87+
# A file wasn't generated. Run a script to extract the source lists from the
88+
# buck2 build system and write them to a file we can include.
89+
#
90+
# NOTE: This will only happen once during cmake setup, so it will not re-run
91+
# if the buck2 targets change.
92+
message(STATUS "executorch: Generating source file list ${sources_file}")
93+
if(EXECUTORCH_ROOT)
94+
set(executorch_root ${EXECUTORCH_ROOT})
95+
else()
96+
set(executorch_root ${CMAKE_CURRENT_SOURCE_DIR})
97+
endif()
98+
execute_process(
99+
COMMAND
100+
${PYTHON_EXECUTABLE} ${executorch_root}/build/extract_sources.py
101+
--buck2=${BUCK2} --config=${executorch_root}/build/cmake_deps.toml
102+
--out=${sources_file}
103+
OUTPUT_VARIABLE gen_srcs_output
104+
ERROR_VARIABLE gen_srcs_error
105+
RESULT_VARIABLE gen_srcs_exit_code
106+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
107+
if(NOT gen_srcs_exit_code EQUAL 0)
108+
message("Error while generating ${sources_file}. "
109+
"Exit code: ${gen_srcs_exit_code}")
110+
message("Output:\n${gen_srcs_output}")
111+
message("Error:\n${gen_srcs_error}")
112+
message(FATAL_ERROR "executorch: source list generation failed")
113+
endif()
104114
endif()
105115
endfunction()

build/executorch-config.cmake

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
# Config defining how CMake should find ExecuTorch package. CMake will search
8+
# for this file and find ExecuTorch package if it is installed.
9+
# Typical usage is:
10+
#
11+
# find_package(executorch REQUIRED)
12+
13+
cmake_minimum_required(VERSION 3.19)
14+
15+
set(_root "${CMAKE_CURRENT_LIST_DIR}/../..")
16+
add_library(executorch STATIC IMPORTED)
17+
find_library(
18+
EXECUTORCH_LIBRARY_PATH executorch HINTS "${_root}"
19+
)
20+
set_target_properties(
21+
executorch PROPERTIES IMPORTED_LOCATION "${EXECUTORCH_LIBRARY_PATH}"
22+
)
23+
target_include_directories(executorch INTERFACE ${_root})
24+
25+
add_library(portable_kernels STATIC IMPORTED)
26+
find_library(
27+
PORTABLE_KERNELS_PATH portable_kernels HINTS "${_root}"
28+
)
29+
set_target_properties(
30+
portable_kernels PROPERTIES IMPORTED_LOCATION "${PORTABLE_KERNELS_PATH}"
31+
)
32+
target_include_directories(portable_kernels INTERFACE ${_root})

examples/selective_build/CMakeLists.txt

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,57 @@
1515
# ~~~
1616
# It should also be cmake-lint clean.
1717
#
18-
1918
cmake_minimum_required(VERSION 3.19)
19+
project(selective_build_example)
20+
21+
if(NOT PYTHON_EXECUTABLE)
22+
set(PYTHON_EXECUTABLE python3)
23+
endif()
24+
2025
set(EXECUTORCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)
2126
set(TORCH_ROOT ${EXECUTORCH_ROOT}/third-party/pytorch)
2227
include(${EXECUTORCH_ROOT}/build/Utils.cmake)
2328
include(${EXECUTORCH_ROOT}/build/Codegen.cmake)
2429

30+
set(_common_compile_options -Wno-deprecated-declarations -fPIC)
31+
32+
# Let files say "include <executorch/path/to/header.h>".
33+
set(_common_include_directories ${EXECUTORCH_ROOT}/..)
34+
35+
find_package(executorch CONFIG REQUIRED)
36+
find_package(
37+
gflags REQUIRED PATHS ${CMAKE_CURRENT_BINARY_DIR}/../../third-party
38+
)
39+
40+
target_include_directories(executorch INTERFACE ${_common_include_directories})
41+
42+
# ------------------------------ OPTIONS BEGIN -------------------------------
43+
44+
# Option to register ops from yaml file
45+
option(EXECUTORCH_SELECT_OPS_YAML "Register all the ops from a given yaml file"
46+
OFF)
47+
48+
# Option to register op list
49+
option(EXECUTORCH_SELECT_OPS_LIST "Register a list of ops, separated by comma"
50+
OFF)
51+
52+
# Selective build options.
53+
option(EXECUTORCH_SELECT_ALL_OPS
54+
"Whether to register all ops defined in portable kernel library." OFF)
55+
# ------------------------------- OPTIONS END --------------------------------
56+
57+
#
58+
# The `_<target>_srcs` lists are defined by including ${EXECUTORCH_SRCS_FILE}.
59+
#
60+
set(
61+
EXECUTORCH_SRCS_FILE
62+
"${CMAKE_CURRENT_BINARY_DIR}/../../executorch_srcs.cmake"
63+
)
64+
65+
extract_sources(${EXECUTORCH_SRCS_FILE})
66+
67+
include(${EXECUTORCH_SRCS_FILE})
68+
2569
#
2670
# select_build_lib: C++ library to register selected ops in custom kernel
2771
# library
@@ -30,7 +74,6 @@ set(_kernel_lib)
3074
if(EXECUTORCH_SELECT_OPS_YAML)
3175
set(_custom_ops_yaml
3276
${EXECUTORCH_ROOT}/examples/portable/custom_ops/custom_ops.yaml)
33-
gen_selected_ops("${_custom_ops_yaml}" "" "")
3477
set(kernel_sources
3578
${EXECUTORCH_ROOT}/examples/portable/custom_ops/custom_ops_1_out.cpp
3679
${EXECUTORCH_ROOT}/examples/portable/custom_ops/custom_ops_2_out.cpp)
@@ -55,16 +98,13 @@ generate_bindings_for_kernels(${EXECUTORCH_ROOT}/kernels/portable/functions.yaml
5598
"${_custom_ops_yaml}")
5699
gen_operators_lib("select_build_lib" ${_kernel_lib} executorch)
57100

58-
set(_updated__srcs)
59-
foreach(_src ${_executor_runner__srcs})
60-
list(APPEND _updated__srcs "${EXECUTORCH_ROOT}/${_src}")
61-
endforeach()
101+
list(TRANSFORM _executor_runner__srcs PREPEND "${EXECUTORCH_ROOT}/")
62102

63103
#
64104
# selective_build_test: test binary to allow different operator libraries to
65105
# link to
66106
#
67-
add_executable(selective_build_test ${_updated__srcs})
107+
add_executable(selective_build_test ${_executor_runner__srcs})
68108
if(CMAKE_BUILD_TYPE EQUAL "RELEASE")
69109
target_link_options(selective_build_test PRIVATE "LINKER:--gc-sections")
70110
endif()

examples/selective_build/test_selective_build.sh

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ set -e
1515
# shellcheck source=/dev/null
1616
source "$(dirname "${BASH_SOURCE[0]}")/../../.ci/scripts/utils.sh"
1717

18+
cmake_install_executorch_lib() {
19+
echo "Installing libexecutorch.a and libportable_kernels.a"
20+
rm -rf cmake-out
21+
retry cmake -DBUCK2="$BUCK" \
22+
-DCMAKE_INSTALL_PREFIX=cmake-out \
23+
-DCMAKE_BUILD_TYPE=Release \
24+
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \
25+
-Bcmake-out .
26+
cmake --build cmake-out -j9 --target install --config Release
27+
}
28+
1829
test_buck2_select_all_ops() {
1930
echo "Exporting MobilenetV3"
2031
${PYTHON_EXECUTABLE} -m examples.portable.scripts.export --model_name="mv3"
@@ -59,20 +70,22 @@ test_cmake_select_all_ops() {
5970
echo "Exporting MobilenetV3"
6071
${PYTHON_EXECUTABLE} -m examples.portable.scripts.export --model_name="mv3"
6172

62-
(rm -rf cmake-out \
63-
&& mkdir cmake-out \
64-
&& cd cmake-out \
65-
&& retry cmake -DBUCK2="$BUCK" \
66-
-DBUILD_SELECTIVE_BUILD_TEST=ON \
73+
local example_dir=examples/selective_build
74+
local build_dir=cmake-out/${example_dir}
75+
rm -rf ${build_dir}
76+
retry cmake -DBUCK2="$BUCK" \
6777
-DCMAKE_BUILD_TYPE=Release \
6878
-DEXECUTORCH_SELECT_ALL_OPS=ON \
69-
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" ..)
79+
-DCMAKE_INSTALL_PREFIX=cmake-out \
80+
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \
81+
-B${build_dir} \
82+
${example_dir}
7083

71-
echo "Build selective build test"
72-
cmake --build cmake-out -j9 --config Release
84+
echo "Building ${example_dir}"
85+
cmake --build ${build_dir} -j9 --config Release
7386

7487
echo 'Running selective build test'
75-
cmake-out/examples/selective_build/selective_build_test --model_path="./mv3.pte"
88+
${build_dir}/selective_build_test --model_path="./mv3.pte"
7689

7790
echo "Removing mv3.pte"
7891
rm "./mv3.pte"
@@ -82,25 +95,27 @@ test_cmake_select_ops_in_list() {
8295
echo "Exporting MobilenetV2"
8396
${PYTHON_EXECUTABLE} -m examples.portable.scripts.export --model_name="mv2"
8497

98+
local example_dir=examples/selective_build
99+
local build_dir=cmake-out/${example_dir}
85100
# set MAX_KERNEL_NUM=17: 14 primops, add, mul
86-
(rm -rf cmake-out \
87-
&& mkdir cmake-out \
88-
&& cd cmake-out \
89-
&& retry cmake -DBUCK2="$BUCK" \
90-
-DMAX_KERNEL_NUM=17 \
91-
-DBUILD_SELECTIVE_BUILD_TEST=ON \
101+
rm -rf ${build_dir}
102+
retry cmake -DBUCK2="$BUCK" \
92103
-DCMAKE_BUILD_TYPE=Release \
104+
-DMAX_KERNEL_NUM=17 \
93105
-DEXECUTORCH_SELECT_OPS_LIST="aten::convolution.out,\
94106
aten::_native_batch_norm_legit_no_training.out,aten::hardtanh.out,aten::add.out,\
95107
aten::mean.out,aten::view_copy.out,aten::permute_copy.out,aten::addmm.out,\
96108
aten,aten::clone.out" \
97-
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" ..)
109+
-DCMAKE_INSTALL_PREFIX=cmake-out \
110+
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \
111+
-B${build_dir} \
112+
${example_dir}
98113

99-
echo "Build selective build test"
100-
cmake --build cmake-out -j9 --config Release
114+
echo "Building ${example_dir}"
115+
cmake --build ${build_dir} -j9 --config Release
101116

102117
echo 'Running selective build test'
103-
cmake-out/examples/selective_build/selective_build_test --model_path="./mv2.pte"
118+
${build_dir}/selective_build_test --model_path="./mv2.pte"
104119

105120
echo "Removing mv2.pte"
106121
rm "./mv2.pte"
@@ -109,21 +124,22 @@ aten,aten::clone.out" \
109124
test_cmake_select_ops_in_yaml() {
110125
echo "Exporting custom_op_1"
111126
${PYTHON_EXECUTABLE} -m examples.portable.custom_ops.custom_ops_1
112-
113-
(rm -rf cmake-out \
114-
&& mkdir cmake-out \
115-
&& cd cmake-out \
116-
&& retry cmake -DBUCK2="$BUCK" \
117-
-DBUILD_SELECTIVE_BUILD_TEST=ON \
127+
local example_dir=examples/selective_build
128+
local build_dir=cmake-out/${example_dir}
129+
rm -rf ${build_dir}
130+
retry cmake -DBUCK2="$BUCK" \
118131
-DCMAKE_BUILD_TYPE=Release \
119132
-DEXECUTORCH_SELECT_OPS_YAML=ON \
120-
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" ..)
133+
-DCMAKE_INSTALL_PREFIX=cmake-out \
134+
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \
135+
-B${build_dir} \
136+
${example_dir}
121137

122-
echo "Build selective build test"
123-
cmake --build cmake-out -j9 --config Release
138+
echo "Building ${example_dir}"
139+
cmake --build ${build_dir} -j9 --config Release
124140

125141
echo 'Running selective build test'
126-
cmake-out/examples/selective_build/selective_build_test --model_path="./custom_ops_1.pte"
142+
${build_dir}/selective_build_test --model_path="./custom_ops_1.pte"
127143

128144
echo "Removing custom_ops_1.pte"
129145
rm "./custom_ops_1.pte"
@@ -141,6 +157,7 @@ fi
141157

142158
if [[ $1 == "cmake" ]];
143159
then
160+
cmake_install_executorch_lib
144161
test_cmake_select_all_ops
145162
test_cmake_select_ops_in_list
146163
test_cmake_select_ops_in_yaml

kernels/portable/CMakeLists.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,8 @@ list(FILTER _portable_kernels__srcs EXCLUDE REGEX "test/*.cpp")
3939
list(FILTER _portable_kernels__srcs EXCLUDE REGEX "codegen")
4040
# Generate C++ bindings to register kernels into both PyTorch (for AOT) and
4141
# Executorch (for runtime). Here select all ops in functions.yaml
42-
if(EXECUTORCH_SELECT_OPS_YAML)
43-
set(_yaml "${CMAKE_CURRENT_LIST_DIR}/functions.yaml")
44-
endif()
45-
gen_selected_ops(
46-
"${_yaml}" "${EXECUTORCH_SELECT_OPS_LIST}" "${EXECUTORCH_SELECT_ALL_OPS}")
42+
set(_yaml "${CMAKE_CURRENT_LIST_DIR}/functions.yaml")
43+
gen_selected_ops("${_yaml}" "" "")
4744
# Expect gen_selected_ops output file to be selected_operators.yaml
4845
generate_bindings_for_kernels(${CMAKE_CURRENT_SOURCE_DIR}/functions.yaml "")
4946
message("Generated files ${gen_command_sources}")
@@ -62,3 +59,5 @@ target_compile_options(portable_kernels PUBLIC ${_common_compile_options})
6259
# portable_ops_lib: Register portable_ops_lib ops kernels into Executorch
6360
# runtime
6461
gen_operators_lib("portable_ops_lib" portable_kernels executorch)
62+
63+
install(TARGETS portable_kernels DESTINATION lib)

0 commit comments

Comments
 (0)