Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support DiaSDK for cross-compiling with mstorsjo/msvc-wine #14076

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/markdown/Dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -862,9 +862,12 @@ version.
## DIA SDK

*(added 1.6.0)*
*(mstorsjo/msvc-wine environment supported since 1.7.0)*

Microsoft's Debug Interface Access SDK (DIA SDK) is available only on Windows,
when using msvc, clang-cl or clang compiler from Microsoft Visual Studio.
You can also use it when cross-compiling for Windows using mstorsjo/msvc-wine
build environment.

The DIA SDK runtime is not statically linked to target. The default usage
method requires the runtime DLL (msdiaXXX.dll) to be manually registered in the
Expand All @@ -882,7 +885,7 @@ fs = import('fs')
fs.copyfile(dia.get_variable('dll'))

conf = configuration_data()
conf.set('msdia_dll_name', fs.name(dia_dll_name))
conf.set('msdia_dll_name', fs.name(dia.get_variable('dll')))
```

Only the major version is available (eg. version is `14` for msdia140.dll).
Expand Down
6 changes: 6 additions & 0 deletions docs/markdown/snippets/diasdk-msvc-wine.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## Added support for DIA SDK on linux via msvc-wine

Microsoft DIA SDK library (for reading with .PDB files) can now be
used when cross-compiling on linux with mstorsjo/msvc-wine
environment. Both compiling with native clang and MSVC cl over
wine are supported.
65 changes: 60 additions & 5 deletions mesonbuild/dependencies/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,56 @@ def _has_define(compiler: 'Compiler', dname: str, env: 'Environment') -> bool:
defval, _ = compiler.get_define(dname, '', env, [], [])
return defval is not None

# mstorsjo/msvc-wine scripts provides DIA SDK on linux.
# DIA SDK directory is stored at the root of downloaded MSVC files.
# We can find this path from the build environment of msvc-wine.
# msvc-wine can be used in two different ways:
@staticmethod
def _find_msvc_wine_path(compiler: 'Compiler') -> T.Optional[str]:
mlog.debug('looking for msvc-wine')

# One way adds <msvc>/bin/x64 to PATH. From there user executes 'cl' script,
# which sets up VS dev environment and invokes the real cl.exe via wine.
if compiler.id == 'msvc':
mlog.debug('- compiler is cl')
clpath = pathlib.Path(shutil.which('cl'))
if clpath.parent.name not in {'arm', 'arm64', 'x86', 'x64'}:
mlog.debug(f'- cl path does not look like msvc-wine: {clpath}')
return None
if clpath.parents[1].name != 'bin':
mlog.debug(f'- cl path does not look like msvc-wine: {clpath}')
return None
mlog.debug(f'- msvc-wine found at: {clpath.parents[2]}')
return str(clpath.parents[2])

# Other way requires calling <msvc-wine>/msvcenv-native.sh, which
# adds bunch of directories into INCLUDE and LIB envvars, and then
# using native clang-cl. (Meson currently doesn't support clang-cl
# on linux for cross-compiling, only clang with explicit MS-compatibility
# parameters)
# We'll look for '<msvc>/kits/<number>/include/<kit version>/winrt'
# in INCLUDE.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does INCLUDE come from? It is an extremely general name so it is confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It comes from script msvcenv-native.sh, which is part of mstorsjo/msvc-wine. The script is used in same way as vcvars*.bat in MSVC. You source it in your shell before building with clang-cl. The script exports INCLUDE and LIB environment variables, pointing to MSVC headers/libs. Environment variables are then consumed by clang-cl.

See: https://github.com/mstorsjo/msvc-wine?tab=readme-ov-file#use-with-clanglld-in-msvc-mode

elif compiler.id in {'clang', 'clang-cl'}:
mlog.debug('- compiler is clang')
includes = os.environ.get('INCLUDE')
if includes is None:
mlog.debug('- INCLUDES not defined')
return None
winrt_inc = next((i for i in includes.split(';') if i.endswith('/winrt')), None)
if winrt_inc is None:
mlog.debug(f'- winrt include not found in INCLUDES: {includes}')
return None
winrt = pathlib.Path(winrt_inc)
if winrt.parents[1].name != 'include' or winrt.parents[3].name != 'kits':
mlog.debug(f'- winrt path does not look like msvc-wine: {winrt}')
return None
mlog.debug(f'- msvc-wine found at: {winrt.parents[4]}')
return str(winrt.parents[4])

else:
mlog.debug(f'- unsupported compiler id: {compiler.id}')
return None

def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
super().__init__('diasdk', environment, kwargs)
self.is_found = False
Expand All @@ -777,16 +827,21 @@ def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> No
if cpu is None:
raise DependencyException(f'DIA SDK is not supported for "{cpu_family}" architecture')

vsdir = os.environ.get('VSInstallDir')
if vsdir is None:
raise DependencyException("Environment variable VSInstallDir required for DIA SDK is not set")
if environment.machines[mesonlib.MachineChoice.BUILD].is_windows():
vsdir = os.environ.get('VSInstallDir')
if vsdir is None:
raise DependencyException('Environment variable VSInstallDir required for DIA SDK is not set')
else:
vsdir = self._find_msvc_wine_path(compiler)
if vsdir is None:
raise DependencyException('msvc-wine environment not found')

diadir = os.path.join(vsdir, 'DIA SDK')
if self._try_path(diadir, cpu):
mlog.debug('DIA SDK was found at default path: ', diadir)
mlog.debug('DIA SDK was found at: ', diadir)
self.is_found = True
return
mlog.debug('DIA SDK was not found at default path: ', diadir)
mlog.debug('DIA SDK was not found at: ', diadir)

return

Expand Down
Loading