[Mesa-dev] [PATCH 23/48] meson: Add support for wrapping llvm
Eric Engestrom
eric.engestrom at intel.com
Tue Jun 12 11:50:51 UTC 2018
On Monday, 2018-06-11 15:55:50 -0700, Dylan Baker wrote:
> For building on Windows (when not using cygwin), the assumption is that
> LLVM will have to be handled via a binary wrap. In this case the user
> wanting to use LLVM is this way will need to create a directory in
> subprojects (any name is fine), and pass that name via the -Dllvm-wrap
> option (for example, assuming subprojects/llvm, -Dllvm-wrap=llvm), which
> must have a meson.build file and the installed LLVM to link with (this
> can be either static or dynamic). There is documentation for what this
> needs to look like and how to define it.
> ---
> docs/meson.html | 66 +++++++++
> meson.build | 128 ++++++++++--------
> meson_options.txt | 6 +
> .../drivers/swr/rasterizer/jitter/meson.build | 13 +-
> 4 files changed, 154 insertions(+), 59 deletions(-)
>
> diff --git a/docs/meson.html b/docs/meson.html
> index 29907a60a9c..6697dbb34ef 100644
> --- a/docs/meson.html
> +++ b/docs/meson.html
> @@ -132,6 +132,72 @@ dependency interface. It will search <code>$PATH</code> (or <code>%PATH%</code>
> llvm-config, so using an LLVM from a non-standard path is as easy as
> <code>PATH=/path/with/llvm-config:$PATH meson build</code>.
> </p></dd>
> +
> +<dd><p>On windows (and in other cases), using llvm-config is either undesirable
> +or impossible. Meson's solution for this is a
> +<a href="http://mesonbuild.com/Wrap-dependency-system-manual.html">wrap</a>, in
> +this case a "binary wrap". Follow the steps below:</p>
> +<ul>
> + <li>Install the binaries and headers into a directory under the $mesa_src/subprojects</li>
> + <li>Add a meson build.build file to that directory (more on that later)</li>
> + <li>add -Dllvm-wrap=$directory to your meson configuration (where $directory is the the directory under subprojects</li>
nit: put <code> around cli args, vars, paths, and functions :)
(here and below)
> +</ul>
> +
> +<p>The wrap file must define the following:</p>
> +<ul>
> + <li>ext_llvm: a declare_dependency() object with include_directories, dependencies, and version set)</li>
> +</ul>
> +
> +<p>It may also define:</p>
> +<ul>
> + <li>irbuilder_h: a file() object pointing to llvm/IR/IRBuilder.h (for SWR)</li>
> +</ul>
> +
> +<p>such a meson.build file might look like:</p>
> +<pre>
> +project('llvm', ['cpp'])
> +
> +cpp = meson.get_compiler('cpp')
> +
> +_deps = []
> +_search = join_paths(meson.current_source_dir(), 'lib')
> +foreach d : ['libLLVMCodeGen', 'libLLVMScalarOpts', 'libLLVMAnalysis',
> + 'libLLVMTransformUtils', 'libLLVMCore', 'libLLVMX86CodeGen',
> + 'libLLVMSelectionDAG', 'libLLVMipo', 'libLLVMAsmPrinter',
> + 'libLLVMInstCombine', 'libLLVMInstrumentation', 'libLLVMMC',
> + 'libLLVMGlobalISel', 'libLLVMObjectYAML', 'libLLVMDebugInfoPDB',
> + 'libLLVMVectorize', 'libLLVMPasses', 'libLLVMSupport',
> + 'libLLVMLTO', 'libLLVMObject', 'libLLVMDebugInfoCodeView',
> + 'libLLVMDebugInfoDWARF', 'libLLVMOrcJIT', 'libLLVMProfileData',
> + 'libLLVMObjCARCOpts', 'libLLVMBitReader', 'libLLVMCoroutines',
> + 'libLLVMBitWriter', 'libLLVMRuntimeDyld', 'libLLVMMIRParser',
> + 'libLLVMX86Desc', 'libLLVMAsmParser', 'libLLVMTableGen',
> + 'libLLVMFuzzMutate', 'libLLVMLinker', 'libLLVMMCParser',
> + 'libLLVMExecutionEngine', 'libLLVMCoverage', 'libLLVMInterpreter',
> + 'libLLVMTarget', 'libLLVMX86AsmParser', 'libLLVMSymbolize',
> + 'libLLVMDebugInfoMSF', 'libLLVMMCJIT', 'libLLVMXRay',
> + 'libLLVMX86AsmPrinter', 'libLLVMX86Disassembler',
> + 'libLLVMMCDisassembler', 'libLLVMOption', 'libLLVMIRReader',
> + 'libLLVMLibDriver', 'libLLVMDlltoolDriver', 'libLLVMDemangle',
> + 'libLLVMBinaryFormat', 'libLLVMLineEditor',
> + 'libLLVMWindowsManifest', 'libLLVMX86Info', 'libLLVMX86Utils']
> + _deps += cpp.find_library(d, dirs : _search)
> +endforeach
> +
> +ext_llvm = declare_dependency(
> + include_directories : include_directories('include'),
> + dependencies : _deps,
> + version : '6.0.0',
> +)
> +
> +irbuilder_h = files('include/llvm/IR/IRBuilder.h')
> +</pre>
> +
> +<p>It is very important that version is defined and is accurate, if it is not,
> +workarounds for the wrong version of LLVM might be used resulting in build
> +failures.</p>
> +
> +</dd>
> </dl>
>
> <dl>
> diff --git a/meson.build b/meson.build
> index 0b0203bc03d..67577241953 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1145,20 +1145,6 @@ if dep_libdrm.found()
> endif
> endif
>
> -llvm_modules = ['bitwriter', 'engine', 'mcdisassembler', 'mcjit']
> -if with_amd_vk or with_gallium_radeonsi or with_gallium_r600
> - llvm_modules += ['amdgpu', 'bitreader', 'ipo']
> - if with_gallium_r600
> - llvm_modules += 'asmparser'
> - endif
> -endif
> -if with_gallium_opencl
> - llvm_modules += [
> - 'all-targets', 'linker', 'coverage', 'instrumentation', 'ipo', 'irreader',
> - 'lto', 'option', 'objcarcopts', 'profiledata',
> - ]
> - # TODO: optional modules
> -endif
>
> if with_amd_vk or with_gallium_radeonsi
> _llvm_version = '>= 5.0.0'
> @@ -1171,51 +1157,85 @@ else
> endif
>
> _llvm = get_option('llvm')
> -if _llvm == 'auto'
> - dep_llvm = dependency(
> - 'llvm', version : _llvm_version, modules : llvm_modules,
> - required : with_amd_vk or with_gallium_radeonsi or with_gallium_swr or with_gallium_opencl,
> - )
> - with_llvm = dep_llvm.found()
> -elif _llvm == 'true'
> - dep_llvm = dependency('llvm', version : _llvm_version, modules : llvm_modules)
> - with_llvm = true
> -else
> - dep_llvm = null_dep
> - with_llvm = false
> -endif
> -if with_llvm
> - _llvm_version = dep_llvm.version().split('.')
> - # Development versions of LLVM have an 'svn' or 'git' suffix, we don't want
> - # that for our version checks.
> - # svn suffixes are stripped by meson as of 0.43, and git suffixes are
> - # strippped as of 0.44, but we support older meson versions.
> -
> - # 3 digits versions in LLVM only started from 3.4.1 on
> - if dep_llvm.version().version_compare('>= 3.4.1')
> - _llvm_patch = _llvm_version[2]
> +llvm_wrap = get_option('llvm-wrap')
> +if llvm_wrap != '' and _llvm != 'false'
> + dep_llvm = subproject(llvm_wrap).get_variable('ext_llvm')
> + if dep_llvm.version().version_compare(_llvm_version)
> + with_llvm = true
> + _ver = dep_llvm.version().split('.')
> + pre_args += [
> + '-DHAVE_LLVM=0x0 at 0@0 at 1@'.format(_ver[0], _ver[1]),
> + '-DMESA_LLVM_VERSION_PATCH=@0@'.format(_ver[2]),
> + ]
> + elif _llvm == 'auto'
> + with_llvm = false
> + dep_llvm = null_dep
> else
> - _llvm_patch = '0'
> + error('LLVM wrap version is @0@, but components require @1@'.format(
> + dep_llvm.version(), _llvm_version))
> endif
> -
> - if _llvm_patch.endswith('svn')
> - _llvm_patch = _llvm_patch.split('s')[0]
> - elif _llvm_patch.contains('git')
> - _llvm_patch = _llvm_patch.split('g')[0]
> +else
> + llvm_modules = ['bitwriter', 'engine', 'mcdisassembler', 'mcjit']
> + if with_amd_vk or with_gallium_radeonsi or with_gallium_r600
> + llvm_modules += ['amdgpu', 'bitreader', 'ipo']
> + if with_gallium_r600
> + llvm_modules += 'asmparser'
> + endif
> endif
> - pre_args += [
> - '-DHAVE_LLVM=0x0 at 0@0 at 1@'.format(_llvm_version[0], _llvm_version[1]),
> - '-DMESA_LLVM_VERSION_PATCH=@0@'.format(_llvm_patch),
> - ]
> + if with_gallium_opencl
> + llvm_modules += [
> + 'all-targets', 'linker', 'coverage', 'instrumentation', 'ipo', 'irreader',
> + 'lto', 'option', 'objcarcopts', 'profiledata',
> + ]
> + # TODO: optional modules
> + endif
> +
> + if _llvm == 'auto'
> + dep_llvm = dependency(
> + 'llvm', version : _llvm_version, modules : llvm_modules,
> + required : with_amd_vk or with_gallium_radeonsi or with_gallium_swr or with_gallium_opencl,
> + )
> + with_llvm = dep_llvm.found()
> + elif _llvm == 'true'
> + dep_llvm = dependency('llvm', version : _llvm_version, modules : llvm_modules)
> + with_llvm = true
> + else
> + dep_llvm = null_dep
> + with_llvm = false
> + endif
> + if with_llvm
> + _llvm_version = dep_llvm.version().split('.')
> + # Development versions of LLVM have an 'svn' or 'git' suffix, we don't want
> + # that for our version checks.
> + # svn suffixes are stripped by meson as of 0.43, and git suffixes are
> + # strippped as of 0.44, but we support older meson versions.
> +
> + # 3 digits versions in LLVM only started from 3.4.1 on
> + if dep_llvm.version().version_compare('>= 3.4.1')
> + _llvm_patch = _llvm_version[2]
> + else
> + _llvm_patch = '0'
> + endif
> +
> + if _llvm_patch.endswith('svn')
> + _llvm_patch = _llvm_patch.split('s')[0]
> + elif _llvm_patch.contains('git')
> + _llvm_patch = _llvm_patch.split('g')[0]
> + endif
> + pre_args += [
> + '-DHAVE_LLVM=0x0 at 0@0 at 1@'.format(_llvm_version[0], _llvm_version[1]),
> + '-DMESA_LLVM_VERSION_PATCH=@0@'.format(_llvm_patch),
> + ]
>
> - # LLVM can be built without rtti, turning off rtti changes the ABI of C++
> - # programs, so we need to build all C++ code in mesa without rtti as well to
> - # ensure that linking works.
> - if dep_llvm.get_configtool_variable('has-rtti') == 'NO'
> - cpp_args += '-fno-rtti'
> + # LLVM can be built without rtti, turning off rtti changes the ABI of C++
> + # programs, so we need to build all C++ code in mesa without rtti as well to
> + # ensure that linking works.
> + if dep_llvm.get_configtool_variable('has-rtti') == 'NO'
> + cpp_args += '-fno-rtti'
> + endif
> + elif with_amd_vk or with_gallium_radeonsi or with_gallium_swr
> + error('The following drivers require LLVM: Radv, RadeonSI, SWR. One of these is enabled, but LLVM is disabled.')
> endif
> -elif with_amd_vk or with_gallium_radeonsi or with_gallium_swr
> - error('The following drivers require LLVM: Radv, RadeonSI, SWR. One of these is enabled, but LLVM is disabled.')
> endif
>
> dep_glvnd = null_dep
> diff --git a/meson_options.txt b/meson_options.txt
> index ad06916fc40..3989bb40739 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -238,6 +238,12 @@ option(
> choices : ['auto', 'true', 'false'],
> description : 'Build with LLVM support.'
> )
> +option(
> + 'llvm-wrap',
> + type : 'string',
> + value : '',
> + description : 'Use LLVM wrap dependency. This bypasses llvm-config, and is useful for cross compiling. This should be set to the value of the suproject. It expects an external_dependency called "ext_llvm"',
> +)
> option(
> 'valgrind',
> type : 'combo',
> diff --git a/src/gallium/drivers/swr/rasterizer/jitter/meson.build b/src/gallium/drivers/swr/rasterizer/jitter/meson.build
> index 5c201990b50..7b6537d8b7e 100644
> --- a/src/gallium/drivers/swr/rasterizer/jitter/meson.build
> +++ b/src/gallium/drivers/swr/rasterizer/jitter/meson.build
> @@ -18,15 +18,18 @@
> # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> # SOFTWARE.
>
> +if llvm_wrap != ''
> + _irbuilder_h = subproject('llvm').get_variable('irbuilder_h')
> +else
> + _irbuilder_h = join_paths(
> + dep_llvm.get_configtool_variable('includedir'), 'llvm', 'IR', 'IRBuilder.h'
> + )
> +endif
>
> gen_builder_hpp = custom_target(
> 'gen_builder.hpp',
> input : [
> - swr_gen_llvm_ir_macros_py,
> - join_paths(
> - dep_llvm.get_configtool_variable('includedir'), 'llvm', 'IR',
> - 'IRBuilder.h'
> - )
> + swr_gen_llvm_ir_macros_py, _irbuilder_h,
> ],
> output : 'gen_builder.hpp',
> command : [
> --
> 2.17.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list