Bug 1617794 - Wrap Windows tools with Wine on cross builds. r=dmajor

Windows programs run via Wine don't like Unix absolute paths (they look
like command line arguments), so we need to use relative paths.

Mingw already run fxc2 via wine, but for some reason it doesn't care
about the Unix absolute paths. genshaders does need some adjustements to
run properly with the real fxc.

Now, on actual Windows, because the temporary directory where
tempfile.NamedTemporaryFile creates files by default is not necessarily
on the same drive as where the command runs from, a relative path can't
be constructed. So we also force the temporary file to be created in the
current (obj) directory.

There is no similar concern for other files because we only go from
objdir to srcdir, and the build system already doesn't support both
being on a separate drive.

While here, flush stdout when the genshared script writes to it, so that
the messages are printed out immediately rather than randomly, later,
after output from subprocesses.

Differential Revision: https://phabricator.services.mozilla.com/D64294

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mike Hommey 2020-02-27 04:42:57 +00:00
parent b197e1f783
commit d747b65211
12 changed files with 84 additions and 37 deletions

View File

@ -17,7 +17,7 @@ MIDL_GENERATED_FILES = \
$(MIDL_GENERATED_FILES): done_gen ;
done_gen: $(srcdir)/IGeckoCustom.idl
$(MIDL) $(MIDL_FLAGS) -I $(srcdir) -Oicf $(srcdir)/IGeckoCustom.idl
$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -I $(srcdir_rel) -Oicf $(srcdir_rel)/IGeckoCustom.idl
touch $@
export:: done_gen

View File

@ -2,7 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
IA2DIR = $(topsrcdir)/other-licenses/ia2
IA2DIR = $(srcdir_rel)/$(DEPTH)/other-licenses/ia2
GARBAGE += $(MIDL_GENERATED_FILES) \
$(MIDL_UNUSED_GENERATED_FILES) \
@ -92,15 +92,15 @@ endif
midl_done : $(addprefix $(IA2DIR)/,$(MIDL_INTERFACES) $(MIDL_ENUMS))
for idl in $(sort $(subst FORCE,,$?) $(addsuffix .idl,$(addprefix $(IA2DIR)/,$(missing_base)))); do \
$(MIDL) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -Oicf $$idl; \
$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -Oicf $$idl; \
done
touch $@
# The intent of this rule is to generate the .tlb file that is referenced in the
# .rc file for IA2Marshal.dll
typelib_done : $(addprefix $(srcdir)/,$(MIDL_LIBRARIES))
typelib_done : $(addprefix $(srcdir_rel)/,$(MIDL_LIBRARIES))
for idl in $?; do \
$(MIDL) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -D _MIDL_DECLARE_WIREM_HANDLE -dlldata `basename $$idl .idl`.c -Oicf $$idl; \
$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -D _MIDL_DECLARE_WIREM_HANDLE -dlldata `basename $$idl .idl`.c -Oicf $$idl; \
done
touch $@

View File

@ -20,8 +20,7 @@ done_gen: $(srcdir)/ISimpleDOM.idl \
$(srcdir)/ISimpleDOMNode.idl \
$(srcdir)/ISimpleDOMDocument.idl \
$(srcdir)/ISimpleDOMText.idl
$(MIDL) $(MIDL_FLAGS) -I $(srcdir) -robust -Oicf $(srcdir)/ISimpleDOM.idl
$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -I $(srcdir_rel) -robust -Oicf $(srcdir_rel)/ISimpleDOM.idl
touch $@
export:: done_gen

View File

@ -2,8 +2,8 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
IA2DIR = $(topsrcdir)/other-licenses/ia2
MSAADIR = $(topsrcdir)/accessible/interfaces/msaa
IA2DIR = $(srcdir_rel)/$(DEPTH)/other-licenses/ia2
MSAADIR = $(srcdir_rel)/$(DEPTH)/accessible/interfaces/msaa
GARBAGE += $(MIDL_GENERATED_FILES) midl_done
MIDL_GENERATED_FILES = \
@ -22,7 +22,7 @@ export:: $(MIDL_GENERATED_FILES)
$(MIDL_GENERATED_FILES): midl_done ;
midl_done: $(srcdir)/HandlerData.acf $(srcdir)/HandlerData.idl
$(MIDL) $(MIDL_FLAGS) $(DEFINES) -I $(topobjdir) -I $(DIST)/include -I $(IA2DIR) -I $(MSAADIR) -Oicf -acf $(srcdir)/HandlerData.acf $(srcdir)/HandlerData.idl
$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) $(DEFINES) -I $(DEPTH) -I $(DEPTH)/dist/include -I $(IA2DIR) -I $(MSAADIR) -Oicf -acf $(srcdir_rel)/HandlerData.acf $(srcdir_rel)/HandlerData.idl
touch $@
INSTALL_TARGETS += midl

View File

@ -16,7 +16,7 @@ MIDL_GENERATED_FILES = \
$(MIDL_GENERATED_FILES): done_gen ;
done_gen: $(srcdir)/Accessible.idl
$(MIDL) $(MIDL_FLAGS) -Oicf $(srcdir)/Accessible.idl
$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -Oicf $(srcdir_rel)/Accessible.idl
touch $@
export:: done_gen

View File

@ -676,12 +676,26 @@ $(CWASMOBJS):
$(REPORT_BUILD_VERBOSE)
$(WASM_CC) $(OUTOPTION)$@ -c $(WASM_CFLAGS) $($(notdir $<)_FLAGS) $<
WINEWRAP = $(if $(and $(filter %.exe,$1),$(WINE)),$(WINE) $1,$1)
# Windows program run via Wine don't like Unix absolute paths (they look
# like command line arguments). So when needed, create relative paths
# from absolute paths. We start with $(DEPTH), which gets us to topobjdir,
# then add "/.." for each component of topobjdir, which gets us to /.
# then we can add the absolute path after that and we have a relative path,
# albeit longer than it could be.
ifdef WINE
relativize = $(if $(filter /%,$1),$(DEPTH)$(subst $(space),,$(foreach d,$(subst /, ,$(topobjdir)),/..))$1,$1)
else
relativize = $1
endif
ifdef ASFILES
# The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
# a '-c' flag.
$(ASOBJS):
$(REPORT_BUILD_VERBOSE)
$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $<
$(call WINEWRAP,$(AS)) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(call relativize,$<)
endif
define syms_template
@ -725,7 +739,7 @@ endif
$(SOBJS):
$(REPORT_BUILD)
$(AS) $(ASOUTOPTION)$@ $(SFLAGS) $($(notdir $<)_FLAGS) -c $<
$(call WINEWRAP,$(AS)) $(ASOUTOPTION)$@ $(SFLAGS) $($(notdir $<)_FLAGS) -c $(call relativize,$<)
$(CPPOBJS):
$(REPORT_BUILD_VERBOSE)
@ -854,7 +868,7 @@ $(RESFILE): %.res: $(RCFILE)
ifdef GNU_CC
$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) $(OUTOPTION)$@ $<
else
$(RC) $(RCFLAGS) -r $(DEFINES) $(INCLUDES) $(OUTOPTION)$@ $<
$(call WINEWRAP,$(RC)) $(RCFLAGS) -r $(DEFINES) $(INCLUDES:-I%=-I$(call relativize,%)) $(OUTOPTION)$@ $(call relativize,$<)
endif
# Cancel GNU make built-in implicit rules

View File

@ -83,7 +83,7 @@ def run_fxc(shader_model,
fxc_location,
'-nologo',
'-T{0}'.format(shader_model),
shader_file,
os.path.relpath(shader_file),
'-E{0}'.format(shader_name),
'-Vn{0}'.format(shader_name),
'-Vi',
@ -97,9 +97,10 @@ def run_fxc(shader_model,
deps = None
with ScopedTempFilename() as temp_filename:
argv += ['-Fh{0}'.format(temp_filename)]
argv += ['-Fh{0}'.format(os.path.relpath(temp_filename))]
sys.stdout.write('{0}\n'.format(' '.join(argv)))
sys.stdout.flush()
proc_stdout = subprocess.check_output(argv)
proc_stdout = decode_console_text(sys.stdout, proc_stdout)
deps = find_dependencies(proc_stdout)
@ -127,6 +128,10 @@ def find_dependencies(fxc_output):
continue
dep_path = m.group(1)
dep_path = os.path.normpath(dep_path)
# When run via Wine, FXC's output contains Windows paths on the Z drive.
# We want to normalize them back to unix paths for the build system.
if 'Linux' in buildconfig.substs['HOST_OS_ARCH'] and dep_path.lower().startswith('z:'):
dep_path = dep_path[2:].replace('\\', '/')
if os.path.isfile(dep_path):
deps.add(dep_path)
return deps
@ -155,7 +160,7 @@ class ScopedTempFilename(object):
self.name = None
def __enter__(self):
with tempfile.NamedTemporaryFile(delete=False) as tmp:
with tempfile.NamedTemporaryFile(dir=os.getcwd(), delete=False) as tmp:
self.name = tmp.name
return self.name

View File

@ -536,6 +536,11 @@ check_prog('HFS_TOOL', extra_programs.HFS_TOOL,
check_prog('RPMBUILD', extra_programs.RPMBUILD,
allow_missing=True)
wine = check_prog(
'WINE', ['wine'], allow_missing=True,
when=depends(target, host, compile_environment)(
lambda t, h, c: c and t.kernel == 'WINNT' and h.kernel == 'Linux'))
@depends(target)
@imports('os')
@ -562,13 +567,19 @@ def makensis_progs(target):
nsis = check_prog('MAKENSISU', makensis_progs, allow_missing=True)
# Make sure the version of makensis is up to date.
@depends_if(nsis)
@depends(nsis, wine)
@checking('for NSIS version')
@imports('re')
def nsis_version(nsis):
def nsis_version(nsis, wine):
if not nsis:
return None
nsis_min_version = '3.0b1'
out = check_cmd_output(nsis, '-version',
onerror=lambda: die('Failed to get nsis version.'))
onerror = lambda: die('Failed to get nsis version.')
if wine and nsis.lower().endswith('.exe'):
out = check_cmd_output(wine, nsis, '-version', onerror=onerror)
else:
out = check_cmd_output(nsis, '-version', onerror=onerror)
m = re.search(r'(?<=v)[0-9]+\.[0-9]+((a|b|rc)[0-9]+)?', out)
if not m:

View File

@ -22,8 +22,13 @@ def archive_exe(pkg_dir, tagfile, sfx_package, package, use_upx):
if use_upx:
final_sfx = mozpath.join(tmpdir, '7zSD.sfx')
subprocess.check_call([
buildconfig.substs.get('UPX', 'upx'),
upx = buildconfig.substs.get('UPX', 'upx')
wine = buildconfig.substs.get('WINE')
if wine and upx.lower().endswith('.exe'):
cmd = [wine, upx]
else:
cmd = [upx]
subprocess.check_call(cmd + [
'--best',
'-o',
final_sfx,

View File

@ -685,11 +685,14 @@ class Dumper_Win32(Dumper):
compressed_file = path[:-1] + '_'
# ignore makecab's output
makecab = buildconfig.substs['MAKECAB']
success = subprocess.call([makecab, "-D",
"CompressionType=MSZIP",
path, compressed_file],
stdout=open(os.devnull, 'w'),
stderr=subprocess.STDOUT)
wine = buildconfig.substs.get('WINE')
if wine and makecab.lower().endswith('.exe'):
cmd = [wine, makecab]
else:
cmd = [makecab]
success = subprocess.call(
cmd + ["-D", "CompressionType=MSZIP", path, compressed_file],
stdout=open(os.devnull, 'w'), stderr=subprocess.STDOUT)
if success == 0 and os.path.exists(compressed_file):
os.unlink(path)
return True

View File

@ -1153,10 +1153,10 @@ midl = check_prog('MIDL', midl_names, when=check_for_midl, allow_missing=True,
paths=sdk_bin_path)
@depends(c_compiler, target,
@depends(c_compiler, target, host,
when=depends(midl, target)(lambda m, t: m and t.kernel == 'WINNT'))
@imports(_from='mozbuild.shellutil', _import='quote')
def midl_flags(c_compiler, target):
def midl_flags(c_compiler, target, host):
if c_compiler and c_compiler.type == 'clang-cl':
env = {
'x86': 'win32',
@ -1165,7 +1165,19 @@ def midl_flags(c_compiler, target):
}[target.cpu]
flags = ['-env', env]
return flags + ['-cpp_cmd', c_compiler.compiler]
if host.os == 'WINNT':
return flags + ['-cpp_cmd', c_compiler.compiler]
else:
# If cross-compiling, for now, we'll assume we can find the
# Windows version of clang-cl in the PATH. It is required because
# while Wine is able to spawn Linux processes from Windows
# programs(!), the calling program doesn't have access to the process
# output and can't wait for it to finish. Midl runs clang-cl as
# a preprocessor and expects to read its output...
clang_cl_exe = find_program('clang-cl.exe')
if not clang_cl_exe:
die("Cannot find clang-cl.exe")
return flags + ['-cpp_cmd', clang_cl_exe]
# mingw
return {
@ -1393,8 +1405,6 @@ with only_when(compile_environment):
fxc = check_prog('FXC', ('fxc.exe', 'fxc2.exe'), when=depends(target)
(lambda t: t.kernel == 'WINNT'),
paths=sdk_bin_path)
wine = check_prog('WINE', ['wine'], when=depends(target, host)
(lambda t, h: t.kernel == 'WINNT' and h.kernel == 'Linux'))
# VPX

View File

@ -53,9 +53,9 @@ $(CONFIG_DIR)/setup.exe::
$(INSTALL) $(addprefix $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/,$(TOOLKIT_NSIS_FILES)) $(CONFIG_DIR)
$(INSTALL) $(addprefix $(MOZILLA_DIR)/other-licenses/nsis/Plugins/,$(CUSTOM_NSIS_PLUGINS)) $(CONFIG_DIR)
$(INSTALL) $(addprefix $(MOZILLA_DIR)/other-licenses/nsis/,$(CUSTOM_UI)) $(CONFIG_DIR)
cd $(CONFIG_DIR) && $(MAKENSISU) $(MAKENSISU_FLAGS) installer.nsi
cd $(CONFIG_DIR) && $(call WINEWRAP,$(MAKENSISU)) $(MAKENSISU_FLAGS) installer.nsi
ifdef MOZ_STUB_INSTALLER
cd $(CONFIG_DIR) && $(MAKENSISU) $(MAKENSISU_FLAGS) stub.nsi
cd $(CONFIG_DIR) && $(call WINEWRAP,$(MAKENSISU)) $(MAKENSISU_FLAGS) stub.nsi
endif
ifdef ZIP_IN
@ -105,7 +105,7 @@ $(CONFIG_DIR)/helper.exe: $(HELPER_DEPS)
$(PPL_LOCALE_ARGS) $(AB_CD) $(CONFIG_DIR)
$(INSTALL) $(addprefix $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/,$(TOOLKIT_NSIS_FILES)) $(CONFIG_DIR)
$(INSTALL) $(addprefix $(MOZILLA_DIR)/other-licenses/nsis/Plugins/,$(CUSTOM_NSIS_PLUGINS)) $(CONFIG_DIR)
cd $(CONFIG_DIR) && $(MAKENSISU) $(MAKENSISU_FLAGS) uninstaller.nsi
cd $(CONFIG_DIR) && $(call WINEWRAP,$(MAKENSISU)) $(MAKENSISU_FLAGS) uninstaller.nsi
uninstaller:: $(CONFIG_DIR)/helper.exe
$(NSINSTALL) -D $(DIST)/bin/uninstall
@ -124,7 +124,7 @@ maintenanceservice_installer::
$(PPL_LOCALE_ARGS) $(AB_CD) $(CONFIG_DIR)
$(INSTALL) $(addprefix $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/,$(TOOLKIT_NSIS_FILES)) $(CONFIG_DIR)
$(INSTALL) $(addprefix $(MOZILLA_DIR)/other-licenses/nsis/Plugins/,$(CUSTOM_NSIS_PLUGINS)) $(CONFIG_DIR)
cd $(CONFIG_DIR) && $(MAKENSISU) $(MAKENSISU_FLAGS) maintenanceservice_installer.nsi
cd $(CONFIG_DIR) && $(call WINEWRAP,$(MAKENSISU)) $(MAKENSISU_FLAGS) maintenanceservice_installer.nsi
$(NSINSTALL) -D $(DIST)/bin/
cp $(CONFIG_DIR)/maintenanceservice_installer.exe $(DIST)/bin
endif