Skip to content

Commit 7cffa86

Browse files
dbortfacebook-github-bot
authored andcommitted
CMakeLists.txt for executor_runner
Summary: A simple build system that should make it easier for partners to cross-compile, and to integrate into their non-buck2 build systems. This uses the `extract_sources.py` tool from D47979069 to avoid hard-coding lists of source files, pulling them from the buck2 graph instead. D48019443 updates the shipit config to copy CMakeLists.txt to the root in github. Reviewed By: tarun292, larryliu0820, cccclai Differential Revision: D47927863 fbshipit-source-id: b9a66af540c2df79743f926cce30794a57b63b4a
1 parent 5c56a7f commit 7cffa86

File tree

2 files changed

+253
-0
lines changed

2 files changed

+253
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
buck-out/
2+
cmake-out/
23
executorch.egg-info
34
__pycache__/
45
build/lib/

CMakeLists.txt

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
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+
#
8+
# Simple CMake build system for runtime components.
9+
#
10+
# One-time setup:
11+
# ~~~
12+
# (rm -rf cmake-out && mkdir cmake-out && cd cmake-out && cmake ..)
13+
# ~~~
14+
#
15+
# Build:
16+
# ~~~
17+
# cmake --build cmake-out -j32
18+
# ~~~
19+
#
20+
# This file should be formatted with
21+
# ~~~
22+
# cmake-format --first-comment-is-literal=True CMakeLists.txt
23+
# ~~~
24+
# It should also be cmake-lint clean.
25+
#
26+
27+
cmake_minimum_required(VERSION 3.13)
28+
project(executorch)
29+
30+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
31+
if(NOT CMAKE_CXX_STANDARD)
32+
set(CMAKE_CXX_STANDARD 17)
33+
endif()
34+
if(NOT BUCK2)
35+
set(BUCK2 buck2)
36+
endif()
37+
38+
# TODO(dbort): Fix these warnings and remove this flag.
39+
set(COMMON_COMPILE_OPTIONS -Wno-deprecated-declarations)
40+
41+
# Let files say "include <executorch/path/to/header.h>".
42+
set(COMMON_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/..)
43+
44+
#
45+
# The `_<target>_srcs` lists are defined by including ${EXECUTORCH_SRCS_FILE}.
46+
#
47+
48+
if(NOT EXECUTORCH_SRCS_FILE)
49+
# A file wasn't provided. Run a script to extract the source lists from the
50+
# buck2 build system and write them to a file we can include.
51+
#
52+
# NOTE: This will only happen once during cmake setup, so it will not re-run
53+
# if the buck2 targets change.
54+
message(STATUS "executorch: Generating source lists")
55+
set(EXECUTORCH_SRCS_FILE "${CMAKE_CURRENT_BINARY_DIR}/executorch_srcs.cmake")
56+
execute_process(
57+
COMMAND python3 build/extract_sources.py --buck2=${BUCK2}
58+
--config=build/cmake_deps.toml --out=${EXECUTORCH_SRCS_FILE}
59+
OUTPUT_VARIABLE gen_srcs_output
60+
ERROR_VARIABLE gen_srcs_error
61+
RESULT_VARIABLE gen_srcs_exit_code
62+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
63+
if(NOT gen_srcs_exit_code EQUAL 0)
64+
message("Error while generating ${EXECUTORCH_SRCS_FILE}. "
65+
"Exit code: ${gen_srcs_exit_code}")
66+
message("Output:\n${gen_srcs_output}")
67+
message("Error:\n${gen_srcs_error}")
68+
message(FATAL_ERROR "executorch: source list generation failed")
69+
endif()
70+
endif()
71+
72+
# This file defines the `_<target>__srcs` variables used below.
73+
message(STATUS "executorch: Using sources file ${EXECUTORCH_SRCS_FILE}")
74+
include(${EXECUTORCH_SRCS_FILE})
75+
76+
#
77+
# flatc: Flatbuffer commandline tool to generate .h files from .fbs files
78+
#
79+
80+
option(FLATBUFFERS_BUILD_FLATC "" ON)
81+
option(FLATBUFFERS_BUILD_FLATHASH "" OFF)
82+
option(FLATBUFFERS_BUILD_FLATLIB "" OFF)
83+
option(FLATBUFFERS_BUILD_TESTS "" OFF)
84+
option(FLATBUFFERS_INSTALL "" OFF)
85+
add_subdirectory(third-party/flatbuffers)
86+
87+
#
88+
# gflags: Commandline flag libgrary
89+
#
90+
91+
add_subdirectory(third-party/gflags)
92+
93+
#
94+
# program_schema: Generated .h files from schema/*.fbs inputs
95+
#
96+
97+
# The include directory that will contain the generated schema headers.
98+
set(_program_schema__include_dir "${CMAKE_CURRENT_BINARY_DIR}/schema/include")
99+
100+
# Paths to headers generated from the .fbs files.
101+
set(_program_schema__outputs)
102+
foreach(fbs_file ${_program_schema__srcs})
103+
string(REGEX REPLACE "[.]fbs$" "_generated.h" generated "${fbs_file}")
104+
list(APPEND _program_schema__outputs
105+
"${_program_schema__include_dir}/executorch/${generated}")
106+
endforeach()
107+
108+
# Generate the headers from the .fbs files.
109+
add_custom_command(
110+
OUTPUT ${_program_schema__outputs}
111+
COMMAND
112+
flatc --cpp --cpp-std c++11 --gen-mutable --scoped-enums
113+
# Add a subdirectory to the include dir so the files can be included as
114+
# <executorch/schema/x_generated.h>
115+
-o "${_program_schema__include_dir}/executorch/schema"
116+
${_program_schema__srcs}
117+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
118+
DEPENDS flatc ${_program_schema__srcs}
119+
COMMENT "Generating program_schema headers"
120+
VERBATIM)
121+
add_library(program_schema INTERFACE ${_program_schema__outputs})
122+
target_include_directories(
123+
program_schema
124+
INTERFACE ${_program_schema__include_dir}
125+
${CMAKE_CURRENT_SOURCE_DIR}/third-party/flatbuffers/include)
126+
127+
#
128+
# executorch: Core runtime library
129+
#
130+
# Only contains primitive operators; does not contain portable kernels or other
131+
# full operators. Does not contain any backends.
132+
#
133+
134+
add_library(executorch ${_executorch__srcs})
135+
target_link_libraries(executorch PRIVATE program_schema)
136+
target_link_libraries(executorch PRIVATE dl) # For dladdr()
137+
target_include_directories(executorch PUBLIC ${COMMON_INCLUDE_DIRECTORIES})
138+
target_compile_options(executorch PUBLIC ${COMMON_COMPILE_OPTIONS})
139+
140+
#
141+
# portable_kernels: Pure-C++ kernel library for ATen ops
142+
#
143+
# Focused on portability and understandability rather than speed.
144+
#
145+
146+
add_library(portable_kernels ${_portable_kernels__srcs})
147+
target_link_libraries(portable_kernels PRIVATE executorch)
148+
target_compile_options(portable_kernels PUBLIC ${COMMON_COMPILE_OPTIONS})
149+
150+
#
151+
# portable_kernels_bindings: Bindings and registration for all ops defined in
152+
# kernels/portable/functions.yaml
153+
#
154+
# Real integrations should supply their own YAML file that only lists the
155+
# operators necessary for the models that will run.
156+
#
157+
# TODO(dbort): Make it possible to provide a custom YAML file. It will be easier
158+
# once we stop using buck2 for this step.
159+
#
160+
161+
set(_portable_kernels_bindings__generated_files
162+
# Although the codegen tool generates more files, these are the only ones we
163+
# need for non-custom kernels.
164+
NativeFunctions.h RegisterCodegenUnboxedKernelsEverything.cpp)
165+
166+
set(_portable_kernels_bindings__output_dir
167+
"${CMAKE_CURRENT_BINARY_DIR}/portable_kernels_bindings")
168+
169+
# Paths to files generated by the codegen step.
170+
set(_portable_kernels_bindings__outputs)
171+
foreach(gen ${_portable_kernels_bindings__generated_files})
172+
list(APPEND _portable_kernels_bindings__outputs
173+
"${_portable_kernels_bindings__output_dir}/${gen}")
174+
endforeach()
175+
176+
set(_portable_kernels_bindings__cpp_files
177+
${_portable_kernels_bindings__outputs})
178+
list(FILTER _portable_kernels_bindings__cpp_files INCLUDE REGEX "[.]cpp$")
179+
180+
# Build the generated files.
181+
#
182+
# NOTE: This will only happen once during cmake setup, so it will not re-run if
183+
# the functions.yaml file changes. TODO(dbort): Stop using buck2 to do this. Use
184+
# add_custom_command() to run the codegen tool directly.
185+
message(STATUS "portable_kernels_bindings: Generating bindings")
186+
execute_process(
187+
COMMAND ${BUCK2} build //kernels/portable:generated_lib_combined --show-output
188+
OUTPUT_VARIABLE buck_output
189+
ERROR_VARIABLE buck_error
190+
RESULT_VARIABLE buck_exit_code
191+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
192+
if(buck_exit_code EQUAL 0)
193+
# The output will look like
194+
# ~~~
195+
# root//kernels/portable:generated_lib_combined buck-out/<path-we-want>
196+
# ~~~
197+
# Extract the second field while avoiding trailing whitespace.
198+
string(REGEX MATCH "buck-out/[^ \t\r\n]*" srcdir ${buck_output})
199+
200+
# Assemble the list of source files, which live under the buck output dir.
201+
set(_srcfiles)
202+
foreach(gen ${_portable_kernels_bindings__generated_files})
203+
list(APPEND _srcfiles "${CMAKE_CURRENT_SOURCE_DIR}/${srcdir}/${gen}")
204+
endforeach()
205+
206+
file(MAKE_DIRECTORY ${_portable_kernels_bindings__output_dir})
207+
file(COPY ${_srcfiles} DESTINATION ${_portable_kernels_bindings__output_dir})
208+
message(STATUS "portable_kernels_bindings: "
209+
"Copied files to ${_portable_kernels_bindings__output_dir}")
210+
else()
211+
message(
212+
"Error occurred while executing buck2 command. Exit code: ${buck_exit_code}"
213+
)
214+
message("Buck2 Output:\n${buck_output}")
215+
message("Buck2 Error:\n${buck_error}")
216+
message(FATAL_ERROR "portable_kernels_bindings: codegen failed")
217+
endif()
218+
219+
add_library(portable_kernels_bindings)
220+
target_sources(portable_kernels_bindings
221+
PRIVATE ${_portable_kernels_bindings__cpp_files})
222+
target_link_libraries(portable_kernels_bindings PRIVATE executorch)
223+
target_link_libraries(portable_kernels_bindings INTERFACE portable_kernels)
224+
225+
# Ensure that the load-time constructor functions run. By default, the linker
226+
# would remove them since there are no other references to them.
227+
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL
228+
"AppleClang")
229+
target_link_options(
230+
portable_kernels_bindings
231+
INTERFACE
232+
# TODO(dbort): This will cause the .a to show up on the link line twice for
233+
# targets that depend on this library; once because CMake will add it, and
234+
# once because it's in this list of args. See if there's a way to avoid
235+
# that.
236+
-Wl,-force_load,libportable_kernels_bindings.a)
237+
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
238+
# Using gcc
239+
target_link_options(
240+
portable_kernels_bindings INTERFACE
241+
# TODO(dbort): This will cause the .a to show up on the link line twice
242+
-Wl,--whole-archive libportable_kernels_bindings.a -Wl,--no-whole-archive)
243+
endif()
244+
245+
#
246+
# executor_runner: A simple commandline tool that loads and runs a program file.
247+
#
248+
249+
add_executable(executor_runner ${_executor_runner__srcs})
250+
target_link_libraries(executor_runner executorch portable_kernels_bindings
251+
gflags)
252+
target_compile_options(executor_runner PUBLIC ${COMMON_COMPILE_OPTIONS})

0 commit comments

Comments
 (0)