Skip to content

Commit

Permalink
Port most of the Mono module build to Meson
Browse files Browse the repository at this point in the history
Missing:
- Test platform: macOS (Should work but I've not tested yet.)
- Finish and test: Windows (Mostly done. Should require a few fixes, but I'm too lazy to reboot right now.)
- Finish and test: All non-desktop platforms (Blocked until implemented for the rest of Godot.)
  - NOTE: For android we were copying shared libs to `#platform/android/java/lib/libs`. How will this work with Meson (out-of-source builds)?

!!! Check TODOs and FIXMEs in 'modules/mono/meson.build'.
  • Loading branch information
neikeq committed Feb 20, 2021
1 parent 5c0c7e6 commit 778402a
Show file tree
Hide file tree
Showing 34 changed files with 1,512 additions and 1,034 deletions.
14 changes: 11 additions & 3 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ option('xaudio2', type: 'boolean', value: false, description: 'Enable the XAudio
option('android_neon', type: 'boolean', value: true, description: 'Enable NEON support (armv7 only)')
option('custom_modules', type: 'array', value: [], description: 'A list of comma-separated directory paths containing custom modules to build')
# add text_server_fb to disabled modules
option('disabled_modules', type: 'array', value: ['mono', 'text_server_fb'], description: 'A list of modules that are to be disabled')
option('disabled_modules', type: 'array', value: ['text_server_fb'], description: 'A list of modules that are to be disabled')
option('disable_all_modules', type: 'boolean', value: false, description: 'A boolean that disables ALL modules.')

# Advanced options
Expand Down Expand Up @@ -54,7 +54,15 @@ option('builtin_graphite', type: 'boolean', value: true, description: 'Use the b
option('builtin_icu', type: 'boolean', value: true, description: 'Use the built-in icu library')

# Mono options
option('mono_glue', type: 'boolean', value: true, description: 'Enable mono glue')

option('mono_prefix', type: 'string', value: '', description: 'Path to the Mono installation directory for the target platform and architecture')
option('mono_bcl', type: 'string', value: '', description: 'Path to a custom Mono BCL (Base Class Library) directory for the target platform')
option('mono_static', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Statically link Mono')
option('mono_glue', type: 'boolean', value: true, description: 'Build with the Mono glue sources')
option('build_cil', type: 'boolean', value: true, description: 'Build C# solutions')
option('copy_mono_root', type: 'boolean', value: true, description: 'Make a copy of the Mono installation directory to bundle with the editor')
# TODO: It would be great if this could be detected automatically instead
option('mono_bundles_zlib', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Specify if the Mono runtime was built with bundled zlib')

# Javascript Options
option('initial_wasm_memory', type: 'integer', value: 16, description: 'Initial WASM memory (in MiB)')
Expand All @@ -68,4 +76,4 @@ option('use_safe_heap', type: 'boolean', value: false, description: 'Use Emscrip
option('javascript_eval', type: 'boolean', value: true, description: 'Enable JavaScript eval interface')
option('threads_enabled', type: 'boolean', value: false, description: 'Enable WebAssembly Threads support (limited browser support)')
option('gdnative_enabled', type: 'boolean', value: false, description: 'Enable WebAssembly GDNative support (produces bigger binaries)')
option('use_closure_compiler', type: 'boolean', value: false, description: 'Use closure compiler to minimize JavaScript code')
option('use_closure_compiler', type: 'boolean', value: false, description: 'Use closure compiler to minimize JavaScript code')
15 changes: 15 additions & 0 deletions modules/mono/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project>
<Target Name="WriteMesonDepList" Condition=" '$(MesonDepListPath)' != '' ">
<Message Importance="High" Text="Writing to depfile ($(ProjectName)): $(MesonDepListPath)" />
<WriteLinesToFile
File="$(MesonDepListPath)"
Lines="%(Compile.FullPath);%(ProjectReference.FullPath);%(MesonWatchImport.FullPath)"
Overwrite="false"
Encoding="utf-8" />
<WriteLinesToFile
File="$(MesonDepListPath)"
Lines="$(ProjectPath)"
Overwrite="false"
Encoding="utf-8" />
</Target>
</Project>
80 changes: 0 additions & 80 deletions modules/mono/build_scripts/api_solution_build.py

This file was deleted.

40 changes: 40 additions & 0 deletions modules/mono/build_scripts/copy_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/python3

import argparse
from shutil import copy2


# Only needed for the stamp file
def touch(path):
import os
with open(path, 'a'):
os.utime(path, None)


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Prints the specified environment variable')
parser.add_argument('src', type=str)
parser.add_argument('dst', type=str)
parser.add_argument('--stamp', type=str)

args = parser.parse_args()

# Only check if directory exists if copy fails

try:
copy2(args.src, args.dst)
except (IOError, FileNotFoundError) as e:
import errno
if isinstance(e, IOError) and e.errno != errno.ENOENT:
raise
import os.path
dst_dir = os.path.dirname(args.dst)
if os.path.isdir(dst_dir):
raise
import os
os.makedirs(dst_dir, exist_ok=True)
copy2(args.src, args.dst)

if args.stamp:
touch(args.stamp)
44 changes: 44 additions & 0 deletions modules/mono/build_scripts/cs_glue_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/python3

import argparse
import sys

# Whatever...
try:
import run_msbuild
except:
from . import run_msbuild


def generate_header(version_header_dst: str, deplist: [str]):
import os

latest_mtime = 0
for filepath in deplist:
mtime = os.path.getmtime(filepath)
latest_mtime = mtime if mtime > latest_mtime else latest_mtime

glue_version = int(latest_mtime) # The latest modified time will do for now

with open(version_header_dst, "w") as version_header:
version_header.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
version_header.write("#ifndef CS_GLUE_VERSION_H\n")
version_header.write("#define CS_GLUE_VERSION_H\n\n")
version_header.write("#define CS_GLUE_VERSION UINT32_C(" + str(glue_version) + ")\n")
version_header.write("\n#endif // CS_GLUE_VERSION_H\n")


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Generate C# glue version header')

run_msbuild.add_arguments_to_parser(parser)

args = parser.parse_args()

result = run_msbuild.run_msbuild_with_args(args)

if result.exit_code != 0:
sys.exit(result.exit_code)

generate_header(args.stamp, result.deplist)
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/usr/bin/python3

import os
import platform

Expand Down Expand Up @@ -62,52 +64,14 @@ def find_mono_root_dir(bits):
return ""


def find_msbuild_tools_path_reg():
import subprocess

vswhere = os.getenv("PROGRAMFILES(X86)")
if not vswhere:
vswhere = os.getenv("PROGRAMFILES")
vswhere += r"\Microsoft Visual Studio\Installer\vswhere.exe"

vswhere_args = ["-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"]

try:
lines = subprocess.check_output([vswhere] + vswhere_args).splitlines()

for line in lines:
parts = line.decode("utf-8").split(":", 1)

if len(parts) < 2 or parts[0] != "installationPath":
continue

val = parts[1].strip()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description='Attempts to find the Mono install directory in the Windows Registry')
parser.add_argument('cpu_family', choices=['x86', 'x86_64'], type=str)

if not val:
raise ValueError("Value of `installationPath` entry is empty")
args = parser.parse_args()

# Since VS2019, the directory is simply named "Current"
msbuild_dir = os.path.join(val, "MSBuild\\Current\\Bin")
if os.path.isdir(msbuild_dir):
return msbuild_dir

# Directory name "15.0" is used in VS 2017
return os.path.join(val, "MSBuild\\15.0\\Bin")

raise ValueError("Cannot find `installationPath` entry")
except ValueError as e:
print("Error reading output from vswhere: " + e.message)
except OSError:
pass # Fine, vswhere not found
except (subprocess.CalledProcessError, OSError):
pass

# Try to find 14.0 in the Registry

try:
subkey = r"SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0"
with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
value = winreg.QueryValueEx(hKey, "MSBuildToolsPath")[0]
return value
except OSError:
return ""
res = find_mono_root_dir(bits='32' if args.cpu_family == 'x86' else '64')
if res:
print(res)
Loading

0 comments on commit 778402a

Please sign in to comment.