Open lb90 opened 3 years ago
I suspect it has to do with the ninja_deps
file...
The build rule for libgdk-win32.a
in build.ninja
is:
build gdk/win32/libgdk-win32.a: STATIC_LINKER
gdk/win32/libgdk-win32.a.p/gdkcairocontext-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkcursor-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkclipboard-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkclipdrop-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkdevicemanager-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkdevice-virtual.c.obj
gdk/win32/libgdk-win32.a.p/gdkdevice-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkdevice-winpointer.c.obj
gdk/win32/libgdk-win32.a.p/gdkdevice-wintab.c.obj
gdk/win32/libgdk-win32.a.p/gdkdisplay-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkdisplaymanager-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkdrag-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkdrop-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkevents-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkglcontext-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkglcontext-win32-wgl.c.obj
gdk/win32/libgdk-win32.a.p/gdkglobals-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkhdataoutputstream-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkinput-winpointer.c.obj
gdk/win32/libgdk-win32.a.p/gdkkeys-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkwin32langnotification.c.obj
gdk/win32/libgdk-win32.a.p/gdkmain-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkmonitor-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkproperty-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkscreen-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkvulkancontext-win32.c.obj
gdk/win32/libgdk-win32.a.p/gdkwin32id.c.obj
gdk/win32/libgdk-win32.a.p/gdksurface-win32.c.obj
LINK_ARGS = "csrD"
STATIC_LINKER is:
# Rules for linking.
rule STATIC_LINKER
command = "gcc-ar" $LINK_ARGS $out $in
description = Linking static target $out
And here's the gcc-ar --help
output describing the command line arguments:
$ gcc-ar --help
Usage: D:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ar.exe [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV] [--plugin <name>] [member-name] [count] archive-file file...
D:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ar.exe -M [<mri-script]
commands:
d - delete file(s) from the archive
m[ab] - move file(s) in the archive
p - print file(s) found in the archive
q[f] - quick append file(s) to the archive
r[ab][f][u] - replace existing or insert new file(s) into the archive
s - act as ranlib
t[O][v] - display contents of the archive
x[o] - extract file(s) from the archive
command specific modifiers:
[a] - put file(s) after [member-name]
[b] - put file(s) before [member-name] (same as [i])
[D] - use zero for timestamps and uids/gids (default)
[U] - use actual timestamps and uids/gids
[N] - use instance [count] of name
[f] - truncate inserted file names
[P] - use full path names when matching
[o] - preserve original dates
[O] - display offsets of files in the archive
[u] - only replace files that are newer than current archive contents
generic modifiers:
[c] - do not warn if the library had to be created
[s] - create an archive index (cf. ranlib)
[l <text> ] - specify the dependencies of this library
[S] - do not build a symbol table
[T] - make a thin archive
[v] - be verbose
[V] - display the version number
@<file> - read options from <file>
--target=BFDNAME - specify the target object format as BFDNAME
--output=DIRNAME - specify the output directory for extraction operations
--record-libdeps=<text> - specify the dependencies of this library
optional:
--plugin <p> - load the specified plugin
emulation options:
No emulation specific options
D:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ar.exe: supported targets: pe-x86-64 pei-x86-64 pe-bigobj-x86-64 elf64-x86-64 elf64-l1om elf64-k1om pe-i386 pei-i386 elf32-i386 elf32-iamcu elf64-little elf64-big elf32-little elf32-big srec symbolsrec verilog tekhex binary ihex plugin
Report bugs to <https://www.sourceware.org/bugzilla/>
So object files are added (modified) in the archive, but existing object files in the archive are not deleted! I guess that's the problem. Maybe we should delete the archive on reconfigure?
That's fascinating. On my machine, this rule looks like this:
# Rules for linking.
rule STATIC_LINKER
command = rm -f $out && gcc-ar $LINK_ARGS $out $in
description = Linking static target $out
It turns out the problem is that this got explicitly disabled on Windows in #1527 due to #1517
What about adding something like meson --internal rm <path>
?
We could, but it's slower because it needs to load the Python interpreter each time. But it's better than something broken.
Adding to this, we could use cmd to replace forward slashes with back slashes: set variable=$out&&del %variable:\=/%
. See https://stackoverflow.com/a/23544993/12126234.
However, I wouldn't rely too much on cmd.exe as it can be a source of obscure bugs or security issues. Consider a source file named like e.g. %PATH%\main.c
We have these problems on unix shells too.
Regarding security, I think that Meson should ban special characters in file names: &, %, $, |, /, \, ', ", <, >, :, ; or even invisible characters
It's not a security issue in the general case, at least on unix the actual command line that gets run is single-quoted and thus treated as a string literal.
It's also a solvable problem on Windows too, e.g. python's subprocess module with shell=False has a security promise that you don't need to worry about shell injection vulnerabilities, since it will safely handle everything for you when given a list of command+argv. As for Meson itself, we should be safe there, as we implement this specially in a cross-platform way by using shlex.quote on unix and a custom implementation at mesonbuild.mesonlib.universal.quote_arg which should follow documented Microsoft practice.
That being said, this is a build system, it runs arbitrary commands arbitrarily, by design. I don't think allowing shell metacharacter injection is a security danger, merely a robustness danger.
Describe the bug
After removing a source file in the Meson build definition, Meson reconfigures and then that source file is not compiled, but the corresponding object file (available from previous compilations) is still passed as input to the linker.
To Reproduce I have created a very simple branch from the master branch that adds a source file to GdkWin32. That source file uses a function from
cabinet.dll
so it adds a new dependency on a system DLL.So I can run Meson and build that branch just fine. But then if I checkout the master branch and try a rebuild I get:
But
gdkfoo-win32.c
does not exist at all in the master branch!Links
Step by step
git clone https://gitlab.gnome.org/lb90/gtk.git --branch new-feature
mkdir gtk-build && cd gtk-build
meson ../gtk --buildtype=debug -Dintrospection=disabled -Dbuild-tests=false && ninja
checkout
themaster
branchninja
againExpected behavior The master branch is built just fine
What happens Building the
libgdk-3-0.dll
target fails at the link stage becausegdkfoo-win32.c.o
is still linked-in, though there's no reference of it anymore in themeson.build
file.system parameters