Skip to content

Commit e9b87f4

Browse files
[RFC] Factor out repetitive cmake patterns for llvm-style projects
New projects (particularly out of tree) have a tendency to hijack the existing llvm configuration options and build targets (add_llvm_library, add_llvm_tool). This can lead to some confusion. 1) When querying a configuration variable, do we care about how LLVM was configured, or how these options were configured for the out of tree project? 2) LLVM has lots of defaults, which are easy to miss (e.g. LLVM_BUILD_TOOLS=ON). These options all need to be duplicated in the CMakeLists.txt for the project. In addition, with LLVM Incubators coming online, we need better ways for these incubators to do things the "LLVM way" without alot of futzing. Ideally, this would happen in a way that eases importing into the LLVM monorepo when projects mature. This patch creates some generic infrastructure in llvm/cmake/modules and refactors MLIR to use this infrastructure. This should expand to include add_xxx_library, which is by far the most complicated bit of building a project correctly, since it has to deal with lots of shared library configuration bits. (MLIR currently hijacks the LLVM infrastructure for building libMLIR.so, so this needs to get refactored anyway.) Differential Revision: https://reviews.llvm.org/D85140
1 parent adccc0b commit e9b87f4

File tree

17 files changed

+221
-28
lines changed

17 files changed

+221
-28
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# LLVM-style projects generally have the same directory structure. This file
2+
# provides some bolierplate cmake support for projects that supports this
3+
# directory structure. Note that generally speaking, projects should prefer
4+
# to use their own rules for these rather than relying on the core llvm build
5+
# targets.
6+
7+
# Generally name should be lower case.
8+
function(add_llvm_project_options name)
9+
string(TOUPPER "${name}" uppername)
10+
11+
# Define options to control the inclusion and default build behavior for
12+
# components which may not strictly be necessary (tools, examples, and tests).
13+
#
14+
# This is primarily to support building smaller or faster project files.
15+
option(${uppername}_INCLUDE_TOOLS
16+
"Generate build targets for the ${uppername} tools."
17+
${LLVM_INCLUDE_TOOLS})
18+
option(${uppername}_BUILD_TOOLS
19+
"Build the ${uppername} tools. If OFF, just generate build targets."
20+
${LLVM_BUILD_TOOLS})
21+
22+
option(${uppername}_INCLUDE_UTILS
23+
"Generate build targets for the ${uppername} utils."
24+
${LLVM_INCLUDE_UTILS})
25+
option(${uppername}_BUILD_UTILS
26+
"Build ${uppername} utility binaries. If OFF, just generate build targets."
27+
${LLVM_BUILD_UTILS})
28+
option(${uppername}_INSTALL_UTILS
29+
"Include utility binaries in the 'install' target."
30+
${LLVM_INSTALL_UTILS})
31+
32+
# i.e. Don't install headers, for instance.
33+
option(${uppername}_INSTALL_TOOLCHAIN_ONLY
34+
"Only include toolchain files in the 'install' target."
35+
${LLVM_INSTALL_TOOLCHAIN_ONLY})
36+
37+
option(${uppername}_BUILD_EXAMPLES
38+
"Build the ${uppername} example programs. If OFF, just generate build targets."
39+
${LLVM_BUILD_EXAMPLES})
40+
option(${uppername}_INCLUDE_EXAMPLES
41+
"Generate build targets for the ${uppername} examples"
42+
${LLVM_INCLUDE_EXAMPLES})
43+
if(${uppername}_BUILD_EXAMPLES)
44+
add_definitions(-DBUILD_EXAMPLES)
45+
endif(${uppername}_BUILD_EXAMPLES)
46+
47+
option(${uppername}_BUILD_TESTS
48+
"Build ${uppername} unit tests. If OFF, just generate build targets."
49+
${LLVM_BUILD_TESTS})
50+
option(${uppername}_INCLUDE_TESTS
51+
"Generate build targets for the ${uppername} unit tests."
52+
${LLVM_INCLUDE_TESTS})
53+
if (${uppername}_INCLUDE_TESTS)
54+
add_definitions(-D${uppername}_INCLUDE_TESTS)
55+
endif()
56+
57+
option(${uppername}_INCLUDE_INTEGRATION_TESTS
58+
"Generate build targets for the ${uppername} integration tests."
59+
${LLVM_INCLUDE_INTEGRATION_TESTS})
60+
if (${uppername}_INCLUDE_INTEGRATION_TESTS)
61+
add_definitions(-D${uppername}_INCLUDE_INTEGRATION_TESTS)
62+
endif()
63+
64+
option(${uppername}_INCLUDE_DOCS
65+
"Generate build targets for the ${uppername} docs."
66+
${LLVM_INCLUDE_DOCS})
67+
68+
endfunction(add_llvm_project_options)
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# For project foo, this function generates:
2+
# add_foo_tool(name) (An executable installed by default)
3+
# add_foo_utility(name) (An executable *not* installed by default)
4+
# add_foo_example(name) (An executable which is built, but never installed)
5+
# add_foo_example_library(name) (A library to go along with an example)
6+
7+
# It also assumes the following configuration environment variables
8+
# (see LLVMProjectOptions.cmake)
9+
# FOO_TOOLS_INSTALL_DIR
10+
# FOO_BUILD_TOOLS
11+
# FOO_BUILD_UTILS
12+
# FOO_INSTALL_UTILS
13+
# FOO_BUILD_EXAMPLES
14+
# FOO_HAS_EXPORTS
15+
# FOO_INSTALL_TOOLCHAIN_ONLY
16+
17+
function(add_llvm_project_targets projectname)
18+
string(TOUPPER "${name}" upperprojectname)
19+
20+
macro(add_${projectname}_tool name)
21+
if( NOT ${upperprojectname}_BUILD_TOOLS )
22+
set(EXCLUDE_FROM_ALL ON)
23+
endif()
24+
add_llvm_executable(${name} ${ARGN})
25+
26+
if ( ${name} IN_LIST LLVM_TOOLCHAIN_TOOLS OR NOT ${upperprojectname}_INSTALL_TOOLCHAIN_ONLY)
27+
if( ${upperprojectname}_BUILD_TOOLS )
28+
set(export_to_${projectname}exports)
29+
if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
30+
NOT LLVM_DISTRIBUTION_COMPONENTS)
31+
set(export_to_${projectname}exports EXPORT ${upperprojectname}Exports)
32+
set_property(GLOBAL PROPERTY ${upperprojectname}_HAS_EXPORTS True)
33+
endif()
34+
35+
install(TARGETS ${name}
36+
${export_to_${projectname}exports}
37+
RUNTIME DESTINATION ${${upperprojectname}_TOOLS_INSTALL_DIR}
38+
COMPONENT ${name})
39+
40+
if (NOT LLVM_ENABLE_IDE)
41+
add_llvm_install_targets(install-${name}
42+
DEPENDS ${name}
43+
COMPONENT ${name})
44+
endif()
45+
endif()
46+
endif()
47+
if( ${upperprojectname}_BUILD_TOOLS )
48+
set_property(GLOBAL APPEND PROPERTY ${upperprojectname}_EXPORTS ${name})
49+
endif()
50+
set_target_properties(${name} PROPERTIES FOLDER "Tools")
51+
endmacro(add_${projectname}_tool name)
52+
53+
macro(add_${projectname}_example name)
54+
if( NOT ${upperprojectname}_BUILD_EXAMPLES )
55+
set(EXCLUDE_FROM_ALL ON)
56+
endif()
57+
add_llvm_executable(${name} ${ARGN})
58+
if( ${upperprojectname}_BUILD_EXAMPLES )
59+
install(TARGETS ${name} RUNTIME DESTINATION examples)
60+
endif()
61+
set_target_properties(${name} PROPERTIES FOLDER "Examples")
62+
endmacro(add_${projectname}_example name)
63+
64+
macro(add_${projectname}_example_library name)
65+
if( NOT ${upperprojectname}_BUILD_EXAMPLES )
66+
set(EXCLUDE_FROM_ALL ON)
67+
add_llvm_library(${name} BUILDTREE_ONLY ${ARGN})
68+
else()
69+
add_llvm_library(${name} ${ARGN})
70+
endif()
71+
72+
set_target_properties(${name} PROPERTIES FOLDER "Examples")
73+
endmacro(add_${projectname}_example_library name)
74+
75+
# This is a macro that is used to create targets for executables that are needed
76+
# for development, but that are not intended to be installed by default.
77+
macro(add_${projectname}_utility name)
78+
if ( NOT ${upperprojectname}_BUILD_UTILS )
79+
set(EXCLUDE_FROM_ALL ON)
80+
endif()
81+
82+
add_llvm_executable(${name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN})
83+
set_target_properties(${name} PROPERTIES FOLDER "Utils")
84+
if (NOT ${upperprojectname}_INSTALL_TOOLCHAIN_ONLY)
85+
if (${upperprojectname}_INSTALL_UTILS AND ${upperprojectname}_BUILD_UTILS)
86+
set(export_to_${projectname}exports)
87+
if (${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
88+
NOT LLVM_DISTRIBUTION_COMPONENTS)
89+
set(export_to_${projectname}exports EXPORT ${upperprojectname}Exports)
90+
set_property(GLOBAL PROPERTY ${upperprojectname}_HAS_EXPORTS True)
91+
endif()
92+
93+
install(TARGETS ${name}
94+
${export_to_${projectname}exports}
95+
RUNTIME DESTINATION ${LLVM_UTILS_INSTALL_DIR}
96+
COMPONENT ${name})
97+
98+
if (NOT LLVM_ENABLE_IDE)
99+
add_llvm_install_targets(install-${name}
100+
DEPENDS ${name}
101+
COMPONENT ${name})
102+
endif()
103+
set_property(GLOBAL APPEND PROPERTY ${upperprojectname}_EXPORTS ${name})
104+
elseif(${upperprojectname}_BUILD_UTILS)
105+
set_property(GLOBAL APPEND PROPERTY ${upperprojectname}_EXPORTS_BUILDTREE_ONLY ${name})
106+
endif()
107+
endif()
108+
endmacro(add_${projectname}_utility name)
109+
endfunction(add_llvm_project_targets)

mlir/CMakeLists.txt

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ set_target_properties(mlir-headers PROPERTIES FOLDER "Misc")
2121
add_dependencies(mlir-headers mlir-generic-headers)
2222
add_custom_target(mlir-doc)
2323

24+
# Get a bunch of LLVM-style default options.
25+
include(LLVMProjectOptions)
26+
add_llvm_project_options(mlir)
27+
2428
# Build the CUDA conversions and run according tests if the NVPTX backend
2529
# is available
2630
if ("NVPTX" IN_LIST LLVM_TARGETS_TO_BUILD)
@@ -44,13 +48,6 @@ set(MLIR_CUDA_RUNNER_ENABLED 0 CACHE BOOL "Enable building the mlir CUDA runner"
4448
set(MLIR_ROCM_RUNNER_ENABLED 0 CACHE BOOL "Enable building the mlir ROCm runner")
4549
set(MLIR_VULKAN_RUNNER_ENABLED 0 CACHE BOOL "Enable building the mlir Vulkan runner")
4650

47-
option(MLIR_INCLUDE_TESTS
48-
"Generate build targets for the MLIR unit tests."
49-
${LLVM_INCLUDE_TESTS})
50-
51-
option(MLIR_INCLUDE_INTEGRATION_TESTS
52-
"Generate build targets for the MLIR integration tests.")
53-
5451
#-------------------------------------------------------------------------------
5552
# Python Bindings Configuration
5653
# Requires:
@@ -83,42 +80,46 @@ if(MLIR_BINDINGS_PYTHON_ENABLED)
8380
"extension = '${PYTHON_MODULE_EXTENSION}")
8481
endif()
8582

83+
# Get a bunch of default targets
84+
include(LLVMProjectTargets)
85+
add_llvm_project_targets(mlir)
86+
8687
include_directories( "include")
8788
include_directories( ${MLIR_INCLUDE_DIR})
8889

8990
# Adding tools/mlir-tblgen here as calling add_tablegen sets some variables like
9091
# MLIR_TABLEGEN_EXE in PARENT_SCOPE which gets lost if that folder is included
9192
# from another directory like tools
92-
add_subdirectory(tools/mlir-tblgen)
93+
if (MLIR_INCLUDE_TOOLS)
94+
add_subdirectory(tools/mlir-tblgen)
95+
endif()
9396

9497
add_subdirectory(include/mlir)
9598
add_subdirectory(lib)
9699
# C API needs all dialects for registration, but should be built before tests.
97100
add_subdirectory(lib/CAPI)
98101
if (MLIR_INCLUDE_TESTS)
99-
add_definitions(-DMLIR_INCLUDE_TESTS)
100102
add_subdirectory(unittests)
101103
add_subdirectory(test)
102104
endif()
103105
if (MLIR_INCLUDE_INTEGRATION_TESTS)
104-
add_definitions(-DMLIR_INCLUDE_INTEGRATION_TESTS)
105106
add_subdirectory(integration_test)
106107
endif()
107108
# Tools needs to come late to ensure that MLIR_ALL_LIBS is populated.
108109
# Generally things after this point may depend on MLIR_ALL_LIBS or libMLIR.so.
109-
add_subdirectory(tools)
110+
if (MLIR_INCLUDE_TOOLS)
111+
add_subdirectory(tools)
112+
endif()
110113

111-
if( LLVM_INCLUDE_EXAMPLES )
114+
if (MLIR_INCLUDE_EXAMPLES)
112115
add_subdirectory(examples)
113116
endif()
114117

115-
option(MLIR_INCLUDE_DOCS "Generate build targets for the MLIR docs."
116-
${LLVM_INCLUDE_DOCS})
117118
if (MLIR_INCLUDE_DOCS)
118119
add_subdirectory(docs)
119120
endif()
120121

121-
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
122+
if (NOT MLIR_INSTALL_TOOLCHAIN_ONLY)
122123
install(DIRECTORY include/mlir include/mlir-c
123124
DESTINATION include
124125
COMPONENT mlir-headers

mlir/cmake/modules/AddMLIR.cmake

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ function(add_mlir_interface interface)
2424
endfunction()
2525

2626

27-
# Generate Documentation
27+
# Generate Documentation using the mlir-doc rule
28+
# doc_filename: the basename of a .td tablegen file
29+
# command: the tablegen command to run, typically "-gen-op-doc",
30+
# "-gen-pass-doc", or "-gen-dialect-doc"
31+
# output_file: the basename of a .md markdown file to be output
32+
# output_directory: the directory to place the output
2833
function(add_mlir_doc doc_filename command output_file output_directory)
2934
set(LLVM_TARGET_DEFINITIONS ${doc_filename}.td)
3035
tablegen(MLIR ${output_file}.md ${command} "-I${MLIR_MAIN_INCLUDE_DIR}" "-I${MLIR_INCLUDE_DIR}")
@@ -40,7 +45,7 @@ function(add_mlir_doc doc_filename command output_file output_directory)
4045
endfunction()
4146

4247
# Declare an mlir library which can be compiled in libMLIR.so
43-
# In addition to everything that llvm_add_librar accepts, this
48+
# In addition to everything that llvm_add_library accepts, this
4449
# also has the following option:
4550
# EXCLUDE_FROM_LIBMLIR
4651
# Don't include this library in libMLIR.so. This option should be used

mlir/examples/standalone/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,17 @@ list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
3131
include(TableGen)
3232
include(AddLLVM)
3333
include(AddMLIR)
34+
35+
# Get a bunch of LLVM-style default options.
36+
include(LLVMProjectOptions)
37+
add_llvm_project_options(standalone)
38+
3439
include(HandleLLVMOptions)
3540

41+
# Get a bunch of default targets
42+
include(LLVMProjectTargets)
43+
add_llvm_project_targets(standalone)
44+
3645
include_directories(${LLVM_INCLUDE_DIRS})
3746
include_directories(${MLIR_INCLUDE_DIRS})
3847
include_directories(${PROJECT_SOURCE_DIR}/include)

mlir/examples/standalone/standalone-opt/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ set(LIBS
66
MLIROptLib
77
MLIRStandalone
88
)
9-
add_llvm_executable(standalone-opt standalone-opt.cpp)
9+
add_standalone_tool(standalone-opt standalone-opt.cpp)
1010

1111
llvm_update_compile_flags(standalone-opt)
1212
target_link_libraries(standalone-opt PRIVATE ${LIBS})

mlir/examples/standalone/standalone-translate/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set(LLVM_LINK_COMPONENTS
55
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
66
get_property(translation_libs GLOBAL PROPERTY MLIR_TRANSLATION_LIBS)
77

8-
add_llvm_executable(standalone-translate
8+
add_standalone_tool(standalone-translate
99
standalone-translate.cpp
1010
)
1111
llvm_update_compile_flags(standalone-translate)

mlir/examples/toy/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ set_target_properties(Toy PROPERTIES FOLDER Examples)
33

44
macro(add_toy_chapter name)
55
add_dependencies(Toy ${name})
6-
add_llvm_example(${name} ${ARGN})
6+
add_mlir_example(${name} ${ARGN})
77
endmacro(add_toy_chapter name)
88

99
add_subdirectory(Ch1)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# RUN: %cmake %mlir_src_root/examples/standalone -DCMAKE_CXX_COMPILER=%host_cxx -DCMAKE_C_COMPILER=%host_cc -DMLIR_DIR=%llvm_lib_dir/cmake/mlir ; %cmake --build . --target check-standalone | tee %t | FileCheck %s
2+
# RUN: %cmake --build . --target mlir-doc
23

34
# CHECK: Passed: 3
45
# UNSUPPORTED: windows, android

mlir/tools/mlir-cpu-runner/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set(LLVM_LINK_COMPONENTS
44
nativecodegen
55
)
66

7-
add_llvm_tool(mlir-cpu-runner
7+
add_mlir_tool(mlir-cpu-runner
88
mlir-cpu-runner.cpp
99
)
1010
llvm_update_compile_flags(mlir-cpu-runner)

mlir/tools/mlir-cuda-runner/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ if(MLIR_CUDA_RUNNER_ENABLED)
6868
LIST(APPEND targets_to_link "LLVM${t}")
6969
ENDFOREACH(t)
7070

71-
add_llvm_tool(mlir-cuda-runner
71+
add_mlir_tool(mlir-cuda-runner
7272
mlir-cuda-runner.cpp
7373

7474
DEPENDS

mlir/tools/mlir-linalg-ods-gen/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ set(LLVM_LINK_COMPONENTS
22
Core
33
Support
44
)
5-
add_llvm_tool(mlir-linalg-ods-gen
5+
add_mlir_tool(mlir-linalg-ods-gen
66
mlir-linalg-ods-gen.cpp
77
)
88
llvm_update_compile_flags(mlir-linalg-ods-gen)

mlir/tools/mlir-opt/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ add_mlir_library(MLIRMlirOptMain
5050
${LIBS}
5151
)
5252

53-
add_llvm_tool(mlir-opt
53+
add_mlir_tool(mlir-opt
5454
mlir-opt.cpp
5555

5656
DEPENDS

mlir/tools/mlir-reduce/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ set(LIBS
4343
MLIRTransformUtils
4444
)
4545

46-
add_llvm_tool(mlir-reduce
46+
add_mlir_tool(mlir-reduce
4747
OptReductionPass.cpp
4848
Passes/OpReducer.cpp
4949
ReductionNode.cpp

mlir/tools/mlir-rocm-runner/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ if(MLIR_ROCM_RUNNER_ENABLED)
104104
LIST(APPEND targets_to_link "LLVM${t}")
105105
ENDFOREACH(t)
106106

107-
add_llvm_tool(mlir-rocm-runner
107+
add_mlir_tool(mlir-rocm-runner
108108
mlir-rocm-runner.cpp
109109

110110
DEPENDS

mlir/tools/mlir-translate/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set(LLVM_LINK_COMPONENTS
55
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
66
get_property(translation_libs GLOBAL PROPERTY MLIR_TRANSLATION_LIBS)
77

8-
add_llvm_tool(mlir-translate
8+
add_mlir_tool(mlir-translate
99
mlir-translate.cpp
1010
)
1111
llvm_update_compile_flags(mlir-translate)

0 commit comments

Comments
 (0)