3if(NOT DEFINED MIM_PLUGIN_LIST)
4 set(MIM_PLUGIN_LIST
"" CACHE INTERNAL
"MIM_PLUGIN_LIST")
6if(NOT DEFINED MIM_PLUGIN_LAYOUT)
7 set(MIM_PLUGIN_LAYOUT
"" CACHE INTERNAL
"MIM_PLUGIN_LAYOUT")
10if(NOT MIM_TARGET_NAMESPACE)
11 set(MIM_TARGET_NAMESPACE
"")
14option(MIM_BUILD_LL_RUNTIME
"Compile the ll backend's C runtime wrappers to LLVM IR (requires clang)." ON)
15find_program(MIM_CLANG NAMES clang)
16if(MIM_BUILD_LL_RUNTIME AND NOT MIM_CLANG)
18 "MimIR: clang not found; ll backend C runtime wrappers will not be built. "
19 "Set MIM_CLANG or disable MIM_BUILD_LL_RUNTIME to silence this."
59function(add_mim_plugin)
62 if(NOT PLUGIN MATCHES
"^[A-Za-z0-9_]+$")
63 message(FATAL_ERROR
"Mim plugin names may only contain letters, digits, and underscores")
66 string(LENGTH
"${PLUGIN}" PLUGIN_LENGTH)
67 if(PLUGIN_LENGTH GREATER 8)
68 message(FATAL_ERROR
"Mim plugin '${PLUGIN}' exceeds the maximum supported length of 8 characters")
71 cmake_parse_arguments(
79 set(PLUGIN_MIM ${CMAKE_CURRENT_LIST_DIR}/${PLUGIN}.mim)
80 set(OUT_PLUGIN_MIM ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/mim/${PLUGIN}.mim)
81 set(PLUGIN_MD ${CMAKE_BINARY_DIR}/docs/plug/${PLUGIN}.md)
82 set(AUTOGEN_H ${CMAKE_BINARY_DIR}/include/mim/plug/${PLUGIN}/autogen.h)
83 set(AUTOGEN_PY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/mim/${PLUGIN}.py)
85 file(READ
"${PLUGIN_MIM}" plugin_file_contents)
88 string(REGEX REPLACE
"/\\*[^*]*\\*+([^/*][^*]*\\*+)*/" "" plugin_file_contents
"${plugin_file_contents}")
91 string(REPLACE
"\n" ";" plugin_lines
"${plugin_file_contents}")
95 ${CMAKE_BINARY_DIR}/docs/plug/
96 ${CMAKE_BINARY_DIR}/include/mim/plug/${PLUGIN}
97 ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/mim/
105 COMMAND $<TARGET_FILE:${MIM_TARGET_NAMESPACE}mim> ${PLUGIN_MIM} -P
"${CMAKE_SOURCE_DIR}/src/mim/plug" -P
"${CMAKE_CURRENT_LIST_DIR}/.." --bootstrap
106 --output-h ${AUTOGEN_H}
107 --output-md ${PLUGIN_MD}
108 --output-py ${AUTOGEN_PY}
109 MAIN_DEPENDENCY ${PLUGIN_MIM}
110 DEPENDS ${MIM_TARGET_NAMESPACE}mim
111 COMMENT
"Bootstrapping MimIR plugin '${PLUGIN_MIM}'"
115 OUTPUT ${OUT_PLUGIN_MIM}
116 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PLUGIN_MIM} ${OUT_PLUGIN_MIM}
117 DEPENDS ${PLUGIN_MIM}
118 COMMENT
"Copy '${PLUGIN_MIM}' to '${OUT_PLUGIN_MIM}'"
121 add_custom_target(mim_internal_${PLUGIN}
129 if(PLUGIN IN_LIST MIM_PLUGIN_LIST)
130 message(FATAL_ERROR
"Mim plugin '${PLUGIN}' is already registered")
133 list(APPEND MIM_PLUGIN_LIST
"${PLUGIN}")
134 string(APPEND MIM_PLUGIN_LAYOUT
"<tab type=\"user\" url=\"@ref ${PLUGIN}\" title=\"${PLUGIN}\"/>")
137 set(MIM_PLUGIN_LIST
"${MIM_PLUGIN_LIST}" CACHE INTERNAL
"MIM_PLUGIN_LIST")
138 set(MIM_PLUGIN_LAYOUT
"${MIM_PLUGIN_LAYOUT}" CACHE INTERNAL
"MIM_PLUGIN_LAYOUT")
143 add_library(mim_${PLUGIN} MODULE)
144 add_dependencies(mim_${PLUGIN}
145 mim_internal_${PLUGIN}
149 target_sources(mim_${PLUGIN}
153 target_include_directories(mim_${PLUGIN}
155 $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
157 if(EXISTS
"${CMAKE_CURRENT_LIST_DIR}/include")
158 target_include_directories(mim_${PLUGIN}
160 "${CMAKE_CURRENT_LIST_DIR}/include"
163 target_link_libraries(mim_${PLUGIN}
166 ${MIM_TARGET_NAMESPACE}libmim
168 set_target_properties(mim_${PLUGIN}
170 CXX_VISIBILITY_PRESET hidden
171 VISIBILITY_INLINES_HIDDEN 1
172 WINDOWS_EXPORT_ALL_SYMBOLS OFF
174 LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/mim
180 if(${PARSED_INSTALL})
185 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mim
186 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/mim
187 RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/mim
188 INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mim
191 FILES ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/mim/${PLUGIN}.mim
192 DESTINATION ${CMAKE_INSTALL_LIBDIR}/mim
196 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mim/plug/${PLUGIN}
198 if(EXISTS
"${CMAKE_CURRENT_LIST_DIR}/include")
200 DIRECTORY
"${CMAKE_CURRENT_LIST_DIR}/include/"
201 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
229function(add_mim_runtime)
232 cmake_parse_arguments(
240 if(NOT MIM_BUILD_LL_RUNTIME OR NOT MIM_CLANG)
244 set(RT_DIR ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/mim/rt)
245 file(MAKE_DIRECTORY ${RT_DIR})
246 set(RT_LL ${RT_DIR}/${PLUGIN}_rt.ll)
249 foreach(src ${PARSED_SOURCES})
250 list(APPEND ABS_SOURCES ${CMAKE_CURRENT_LIST_DIR}/${src})
253 list(LENGTH ABS_SOURCES N_SOURCES)
254 if(N_SOURCES EQUAL 1)
257 COMMAND ${MIM_CLANG} -S -emit-llvm -O2 ${ABS_SOURCES} -o ${RT_LL}
258 DEPENDS ${ABS_SOURCES}
259 COMMENT
"Compiling MimIR runtime '${PLUGIN}' to LLVM IR"
263 find_program(MIM_LLVM_LINK NAMES llvm-link)
264 if(NOT MIM_LLVM_LINK)
266 "add_mim_runtime(${PLUGIN}) with multiple SOURCES needs llvm-link to merge them"
270 foreach(src ${PARSED_SOURCES})
271 get_filename_component(stem ${src} NAME_WE)
272 set(bc ${RT_DIR}/${PLUGIN}_${stem}.bc)
275 COMMAND ${MIM_CLANG} -emit-llvm -O2 -c ${CMAKE_CURRENT_LIST_DIR}/${src} -o ${bc}
276 DEPENDS ${CMAKE_CURRENT_LIST_DIR}/${src}
277 COMMENT
"Compiling MimIR runtime source '${src}' to LLVM bitcode"
280 list(APPEND RT_BCS ${bc})
284 COMMAND ${MIM_LLVM_LINK} -S ${RT_BCS} -o ${RT_LL}
286 COMMENT
"Linking MimIR runtime '${PLUGIN}' into a single LLVM IR module"
291 add_custom_target(mim_runtime_${PLUGIN} ALL DEPENDS ${RT_LL})
292 if(TARGET mim_${PLUGIN})
293 add_dependencies(mim_${PLUGIN} mim_runtime_${PLUGIN})
295 if(${PARSED_INSTALL})
298 DESTINATION ${CMAKE_INSTALL_LIBDIR}/mim/rt