[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