Skip to content

Commit 39dbce1

Browse files
authored
[microTVM] Build standalone_crt with cmake instead of makefile (#13600)
Build standalone_crt with cmake instead of makefile to allow for better portability of microTVM code to other build environments. fixes #13533
1 parent 721f115 commit 39dbce1

File tree

2 files changed

+141
-113
lines changed

2 files changed

+141
-113
lines changed

cmake/modules/StandaloneCrt.cmake

Lines changed: 141 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ if(MSVC)
2323
# When building for Windows, use standard CMake for compatibility with
2424
# Visual Studio build tools and not require Make to be on the system.
2525

26+
# TODO: test building with this MSVC conditional code removed
27+
# when USE_MICRO is enabled
28+
2629
set(CRT_CONFIG, "src/runtime/micro/crt_config.h")
2730

2831
add_library(host_standalone_crt
@@ -40,129 +43,154 @@ if(MSVC)
4043

4144
else()
4245

43-
message(STATUS "Build standalone CRT for microTVM")
46+
function(create_crt_library CRT_LIBRARY)
4447

45-
function(tvm_crt_define_targets)
46-
# Build an isolated build directory, separate from the TVM tree.
47-
list(APPEND CRT_FILE_COPY_JOBS
48-
"3rdparty/libcrc/include *.h -> include"
49-
"3rdparty/libcrc/src crcccitt.c -> src/runtime/crt/microtvm_rpc_common"
50-
"3rdparty/libcrc/tab gentab_ccitt.inc -> src/runtime/crt/tab"
51-
"3rdparty/dlpack/include *.h -> include"
52-
"3rdparty/dmlc-core/include *.h -> include"
53-
"include/tvm/runtime c_*_api.h -> include/tvm/runtime"
54-
"include/tvm/runtime metadata_types.h -> include/tvm/runtime"
55-
"include/tvm/runtime/crt *.h -> include/tvm/runtime/crt"
56-
"src/runtime/crt Makefile -> ."
57-
"src/runtime/crt/include *.h -> include"
58-
"src/runtime/crt/aot_executor *.c -> src/runtime/crt/aot_executor"
59-
"src/runtime/crt/aot_executor_module *.c -> src/runtime/crt/aot_executor_module"
60-
"src/runtime/crt/common *.c -> src/runtime/crt/common"
61-
"src/runtime/crt/graph_executor *.c -> src/runtime/crt/graph_executor"
62-
"src/runtime/crt/graph_executor_module *.c -> src/runtime/crt/graph_executor_module"
63-
"src/runtime/crt/host *.cc -> template/host"
64-
"src/runtime/crt/host *.py -> template/host"
65-
"src/runtime/crt/host Makefile.template -> template/host"
66-
"src/runtime/crt/memory *.c -> src/runtime/crt/memory"
67-
"src/runtime/crt/microtvm_rpc_common *.cc -> src/runtime/crt/microtvm_rpc_common"
68-
"src/runtime/crt/microtvm_rpc_server *.cc -> src/runtime/crt/microtvm_rpc_server"
69-
"src/runtime/minrpc *.h -> src/runtime/minrpc"
70-
"src/support generic_arena.h -> src/support"
71-
"src/support ssize.h -> src/support"
72-
"src/runtime/crt crt_config-template.h -> template"
73-
)
74-
75-
set(standalone_crt_base "${CMAKE_CURRENT_BINARY_DIR}/standalone_crt")
76-
77-
foreach(job_spec IN LISTS CRT_FILE_COPY_JOBS)
78-
string(REPLACE " " ";" job_spec "${job_spec}")
79-
list(LENGTH job_spec job_spec_length)
80-
math(EXPR job_spec_length_mod "${job_spec_length} % 3")
81-
if(NOT "${job_spec_length_mod}" EQUAL 1)
82-
message(FATAL_ERROR "CRT copy job spec list length is ${job_spec_length}; parsed job spec is ${job_spec}")
83-
endif()
84-
math(EXPR job_spec_stop "${job_spec_length} - 3")
85-
86-
list(GET job_spec 0 job_src_base)
87-
set(job_src_base "${CMAKE_CURRENT_SOURCE_DIR}/${job_src_base}")
88-
foreach(copy_pattern_index RANGE 1 "${job_spec_stop}" 3)
89-
list(GET job_spec ${copy_pattern_index} copy_pattern)
90-
math(EXPR copy_dest_index "${copy_pattern_index} + 2")
91-
list(GET job_spec ${copy_dest_index} copy_dest)
92-
93-
tvm_file_glob(GLOB_RECURSE copy_files
94-
RELATIVE "${job_src_base}"
95-
"${job_src_base}/${copy_pattern}")
96-
list(LENGTH copy_files copy_files_length)
97-
if("${copy_files_length}" EQUAL 0)
98-
message(FATAL_ERROR "CRT copy job matched 0 files: ${job_src_base}/${copy_pattern} -> ${copy_dest}")
99-
endif()
100-
foreach(copy_src IN LISTS copy_files)
101-
get_filename_component(dest_path "${standalone_crt_base}/${copy_dest}/${copy_src}" ABSOLUTE)
102-
tvm_micro_add_copy_file(host_isolated_build_deps ${job_src_base}/${copy_src} ${dest_path})
103-
endforeach()
104-
endforeach()
105-
endforeach()
48+
set(CRT_LIBRARY_NAME host_standalone_crt_${CRT_LIBRARY})
49+
set(CRT_LIBRARY_SOURCES "")
10650

107-
add_custom_target(standalone_crt DEPENDS ${host_isolated_build_deps})
51+
foreach(FILE_NAME IN LISTS ARGN)
52+
list(APPEND CRT_LIBRARY_SOURCES ${FILE_NAME})
53+
endforeach()
10854

109-
get_filename_component(host_build_dir_abspath "${CMAKE_CURRENT_BINARY_DIR}/host_standalone_crt" ABSOLUTE)
55+
add_library(${CRT_LIBRARY_NAME}
56+
STATIC
57+
${CRT_LIBRARY_SOURCES})
11058

111-
if(${VERBOSE})
112-
set(make_quiet QUIET=)
113-
else(${VERBOSE})
114-
set(make_quiet )
115-
endif(${VERBOSE})
59+
# add this library to the list of CRT libraries
60+
set(CRT_LIBRARIES ${CRT_LIBRARIES} ${CRT_LIBRARY_NAME} PARENT_SCOPE)
11661

117-
list(APPEND crt_libraries memory graph_executor microtvm_rpc_server microtvm_rpc_common common) # NOTE: listed in link order.
118-
foreach(crt_lib_name IN LISTS crt_libraries)
119-
list(APPEND crt_library_paths "host_standalone_crt/lib${crt_lib_name}.a")
120-
endforeach()
62+
target_include_directories(${CRT_LIBRARY_NAME}
63+
PUBLIC
64+
${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/micro/
65+
${STANDALONE_CRT_BASE}/include)
12166

122-
set(make_common_args
123-
"CRT_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/micro/crt_config.h"
124-
"BUILD_DIR=${host_build_dir_abspath}"
125-
"EXTRA_CFLAGS=-fPIC"
126-
"EXTRA_CXXFLAGS=-fPIC"
127-
"EXTRA_LDFLAGS=-fPIC"
128-
"${make_quiet}")
129-
130-
add_custom_command(
131-
OUTPUT ${crt_library_paths}
132-
COMMAND make ARGS ${make_common_args} clean
133-
COMMAND make ARGS ${make_common_args} all
134-
WORKING_DIRECTORY "${standalone_crt_base}"
135-
DEPENDS standalone_crt ${host_isolated_build_deps})
136-
137-
add_custom_target(host_standalone_crt DEPENDS ${crt_library_paths})
138-
139-
foreach(crt_lib IN LISTS crt_libraries)
140-
set(cmake_crt_lib_name host_standalone_crt_${crt_lib})
141-
list(APPEND cmake_crt_libraries ${cmake_crt_lib_name})
142-
add_library(${cmake_crt_lib_name} STATIC IMPORTED GLOBAL)
143-
set(cmake_crt_lib_path "${CMAKE_CURRENT_BINARY_DIR}/host_standalone_crt/lib${crt_lib}.a")
144-
add_dependencies(${cmake_crt_lib_name} host_standalone_crt "${cmake_crt_lib_path}")
145-
set_target_properties(${cmake_crt_lib_name} PROPERTIES
146-
IMPORTED_LOCATION "${cmake_crt_lib_path}"
147-
IMPORTED_OBJECTS "${cmake_crt_lib_path}"
148-
PUBLIC_HEADER "${crt_headers}")
149-
endforeach()
67+
set_target_properties(${CRT_LIBRARY_NAME}
68+
PROPERTIES
69+
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/host_standalone_crt
70+
POSITION_INDEPENDENT_CODE ON)
15071

151-
# Create the `crttest` target if we can find GTest. If not, we create dummy
152-
# targets that give the user an informative error message.
153-
if(GTEST_FOUND)
154-
tvm_file_glob(GLOB TEST_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/tests/crt/*.cc)
155-
add_executable(crttest ${TEST_SRCS})
156-
target_include_directories(crttest SYSTEM PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/standalone_crt/include ${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/micro)
157-
target_link_libraries(crttest PRIVATE ${cmake_crt_libraries} GTest::GTest GTest::Main pthread dl)
158-
set_target_properties(crttest PROPERTIES EXCLUDE_FROM_ALL 1)
159-
set_target_properties(crttest PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1)
160-
gtest_discover_tests(crttest)
161-
endif()
72+
# make these libraries dependent on standalone_crt which depends on host_isolated_build_deps to avoid
73+
# race with the file copy jobs
74+
add_dependencies(${CRT_LIBRARY_NAME} standalone_crt)
16275

16376
endfunction()
16477

165-
tvm_crt_define_targets()
78+
message(STATUS "Build standalone CRT for microTVM")
79+
80+
# Build an isolated build directory, separate from the TVM tree.
81+
list(APPEND CRT_FILE_COPY_JOBS
82+
"3rdparty/libcrc/include *.h -> include"
83+
"3rdparty/libcrc/src crcccitt.c -> src/runtime/crt/microtvm_rpc_common"
84+
"3rdparty/libcrc/tab gentab_ccitt.inc -> src/runtime/crt/tab"
85+
"3rdparty/dlpack/include *.h -> include"
86+
"3rdparty/dmlc-core/include *.h -> include"
87+
"include/tvm/runtime c_*_api.h -> include/tvm/runtime"
88+
"include/tvm/runtime metadata_types.h -> include/tvm/runtime"
89+
"include/tvm/runtime/crt *.h -> include/tvm/runtime/crt"
90+
"src/runtime/crt Makefile -> ."
91+
"src/runtime/crt/include *.h -> include"
92+
"src/runtime/crt/aot_executor *.c -> src/runtime/crt/aot_executor"
93+
"src/runtime/crt/aot_executor_module *.c -> src/runtime/crt/aot_executor_module"
94+
"src/runtime/crt/common *.c -> src/runtime/crt/common"
95+
"src/runtime/crt/graph_executor *.c -> src/runtime/crt/graph_executor"
96+
"src/runtime/crt/graph_executor_module *.c -> src/runtime/crt/graph_executor_module"
97+
"src/runtime/crt/host *.cc -> template/host"
98+
"src/runtime/crt/host *.py -> template/host"
99+
"src/runtime/crt/host Makefile.template -> template/host"
100+
"src/runtime/crt/memory *.c -> src/runtime/crt/memory"
101+
"src/runtime/crt/microtvm_rpc_common *.cc -> src/runtime/crt/microtvm_rpc_common"
102+
"src/runtime/crt/microtvm_rpc_server *.cc -> src/runtime/crt/microtvm_rpc_server"
103+
"src/runtime/minrpc *.h -> src/runtime/minrpc"
104+
"src/support generic_arena.h -> src/support"
105+
"src/support ssize.h -> src/support"
106+
"src/runtime/crt crt_config-template.h -> template"
107+
)
108+
109+
set(STANDALONE_CRT_BASE ${CMAKE_CURRENT_BINARY_DIR}/standalone_crt)
110+
111+
foreach(job_spec IN LISTS CRT_FILE_COPY_JOBS)
112+
string(REPLACE " " ";" job_spec "${job_spec}")
113+
list(LENGTH job_spec job_spec_length)
114+
math(EXPR job_spec_length_mod "${job_spec_length} % 3")
115+
if(NOT "${job_spec_length_mod}" EQUAL 1)
116+
message(FATAL_ERROR "CRT copy job spec list length is ${job_spec_length}; parsed job spec is ${job_spec}")
117+
endif()
118+
math(EXPR job_spec_stop "${job_spec_length} - 3")
119+
120+
list(GET job_spec 0 job_src_base)
121+
set(job_src_base "${CMAKE_CURRENT_SOURCE_DIR}/${job_src_base}")
122+
foreach(copy_pattern_index RANGE 1 "${job_spec_stop}" 3)
123+
list(GET job_spec ${copy_pattern_index} copy_pattern)
124+
math(EXPR copy_dest_index "${copy_pattern_index} + 2")
125+
list(GET job_spec ${copy_dest_index} copy_dest)
126+
127+
tvm_file_glob(GLOB_RECURSE copy_files
128+
RELATIVE "${job_src_base}"
129+
"${job_src_base}/${copy_pattern}")
130+
list(LENGTH copy_files copy_files_length)
131+
if("${copy_files_length}" EQUAL 0)
132+
message(FATAL_ERROR "CRT copy job matched 0 files: ${job_src_base}/${copy_pattern} -> ${copy_dest}")
133+
endif()
134+
foreach(copy_src IN LISTS copy_files)
135+
get_filename_component(dest_path "${STANDALONE_CRT_BASE}/${copy_dest}/${copy_src}" ABSOLUTE)
136+
tvm_micro_add_copy_file(host_isolated_build_deps ${job_src_base}/${copy_src} ${dest_path})
137+
endforeach()
138+
endforeach()
139+
endforeach()
140+
141+
add_custom_target(standalone_crt DEPENDS ${host_isolated_build_deps})
142+
143+
set(CRT_LIBRARIES "")
144+
set(RUNTIME_CRT_SOURCE_DIR ${STANDALONE_CRT_BASE}/src/runtime/crt)
145+
146+
# these create_crt_library() targets are in link order and the common library needs to be last
147+
create_crt_library(aot_executor
148+
${RUNTIME_CRT_SOURCE_DIR}/aot_executor/aot_executor.c)
149+
150+
create_crt_library(aot_executor_module
151+
${RUNTIME_CRT_SOURCE_DIR}/aot_executor_module/aot_executor_module.c)
152+
153+
create_crt_library(graph_executor
154+
${RUNTIME_CRT_SOURCE_DIR}/graph_executor/graph_executor.c
155+
${RUNTIME_CRT_SOURCE_DIR}/graph_executor/load_json.c)
156+
157+
create_crt_library(graph_executor_module
158+
${RUNTIME_CRT_SOURCE_DIR}/graph_executor_module/graph_executor_module.c)
159+
160+
create_crt_library(memory
161+
${RUNTIME_CRT_SOURCE_DIR}/memory/page_allocator.c
162+
${RUNTIME_CRT_SOURCE_DIR}/memory/stack_allocator.c)
163+
164+
create_crt_library(microtvm_rpc_common
165+
${RUNTIME_CRT_SOURCE_DIR}/microtvm_rpc_common/crcccitt.c
166+
${RUNTIME_CRT_SOURCE_DIR}/microtvm_rpc_common/frame_buffer.cc
167+
${RUNTIME_CRT_SOURCE_DIR}/microtvm_rpc_common/framing.cc
168+
${RUNTIME_CRT_SOURCE_DIR}/microtvm_rpc_common/session.cc
169+
${RUNTIME_CRT_SOURCE_DIR}/microtvm_rpc_common/write_stream.cc)
170+
171+
create_crt_library(microtvm_rpc_server
172+
${RUNTIME_CRT_SOURCE_DIR}/microtvm_rpc_server/rpc_server.cc)
173+
174+
create_crt_library(common
175+
${RUNTIME_CRT_SOURCE_DIR}/common/crt_backend_api.c
176+
${RUNTIME_CRT_SOURCE_DIR}/common/crt_runtime_api.c
177+
${RUNTIME_CRT_SOURCE_DIR}/common/func_registry.c
178+
${RUNTIME_CRT_SOURCE_DIR}/common/ndarray.c
179+
${RUNTIME_CRT_SOURCE_DIR}/common/packed_func.c)
180+
181+
add_custom_target(host_standalone_crt DEPENDS ${CRT_LIBRARIES} standalone_crt)
182+
183+
# Create the `crttest` target if we can find GTest. If not, we create dummy
184+
# targets that give the user an informative error message.
185+
if(GTEST_FOUND)
186+
tvm_file_glob(GLOB TEST_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/tests/crt/*.cc)
187+
add_executable(crttest ${TEST_SRCS})
188+
target_include_directories(crttest SYSTEM PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/standalone_crt/include ${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/micro)
189+
target_link_libraries(crttest PRIVATE ${CRT_LIBRARIES} GTest::GTest GTest::Main pthread dl)
190+
set_target_properties(crttest PROPERTIES EXCLUDE_FROM_ALL 1)
191+
set_target_properties(crttest PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1)
192+
gtest_discover_tests(crttest)
193+
endif()
166194

167195
set(TVM_CRT_LINKER_LIB host_standalone_crt_microtvm_rpc_common)
168196
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")

include/tvm/runtime/crt/crt.h

100755100644
File mode changed.

0 commit comments

Comments
 (0)