[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
execute, spawn-pipe: Support DLL dependencies of Windows executables
From: |
Bruno Haible |
Subject: |
execute, spawn-pipe: Support DLL dependencies of Windows executables |
Date: |
Tue, 22 Oct 2024 22:15:52 +0200 |
Michele Locati noticed that executing programs on Windows has an additional
complexity that does not exist on Unix: On Unix, programs have their runtime
path embedded in the executable ('-rpath' option). On Windows, this is not
the case; instead, DLLs used by the executable are looked up [1]
- in the directory where the executable sits,
- in $PATH,
- in the current directory (this is irrelevant here).
As a consequence, GNU programs on Windows don't install DLLs in $(libdir),
but in $(bindir), so that executables installed in $(bindir) will find them.
But there is a problem when a program (installed in $(bindir)) invokes a
program installed in $(pkglibexecdir). Namely, it will not find its DLLs,
if $(bindir) does not happen to be in the $PATH.
What workarounds exist?
- A package could install all its executables in $(bindir), none in
$(pkglibexecdir).
Problem: Executables from $(pkglibexecdir) are not meant to be public
(i.e. visible to the user).
- A package could install the DLLs both in $(bindir) and $(pkglibexecdir).
Problem: Waste of disk space.
- A package could avoid invoking helper executables and instead incorporate
the helper code in its own executable or libraries.
Problem: A particular platform would dictate the architecture of the
entire package.
- While invoking a program installed in $(pkglibexecdir), $(bindir) gets
added to $PATH.
This is the best solution.
Note that it cannot be implemented by invoking "env PATH=.... program ...",
because there is no 'env' program on native Windows.
Note also that we cannot require the caller to do a
setenv ("PATH", value, 1);
call, because setenv() is not multithread-safe and also because it would
be an ad-hoc "solution".
So, the PATH modifications must be done in the Gnulib modules 'execute'
and 'spawn-pipe'. (The posix_spawn and posix_spawnp functions don't need
modifications, since they already accept an 'envp' parameter which can
contain a definition of PATH.)
This patch implements that.
[1]
https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order
2024-10-22 Bruno Haible <bruno@clisp.org>
execute, spawn-pipe: Support DLL dependencies of Windows executables.
Reported by Michele Locati <michele@locati.it>.
* lib/windows-path.h: New file.
* lib/windows-path.c: New file.
* lib/windows-spawn.h (compose_envblock): Add new_PATH parameter.
(spawnpvech): Add dll_dirs parameter. Call extended_PATH.
* lib/windows-spawn.c: Include windows-path.h.
(compose_envblock): Add new_PATH parameter.
* modules/windows-spawn (Description): Now applies to Cygwin as well.
(Files): Add lib/windows-path.h, lib/windows-path.c.
(configure.ac): Define GL_COND_OBJ_WINDOWS_PATH.
(Makefile.am): Conditionally compile windows-path.c.
(Include): Add windows-path.h.
* lib/spawni.c (__spawni): Update compose_envblock call.
* lib/execute.h (execute): Add dll_dirs parameter.
* lib/execute.c: Include windows-path.h.
(execute): Add dll_dirs parameter. Pass it down to spawnpvech. Call
extended_environ.
* lib/spawn-pipe.h (create_pipe_out, create_pipe_in, create_pipe_bidi):
Add dll_dirs parameter.
* lib/spawn-pipe.c: Include windows-path.h.
(create_pipe): Add dll_dirs parameter. Pass it down to spawnpvech. Call
extended_environ.
(create_pipe_bidi, create_pipe_in, create_pipe_out): Add dll_dirs
parameter.
* lib/javaexec.c (execute_java_class): Update execute invocations.
* lib/cygpath.c (execute_and_read_line): Update create_pipe_in
invocation.
* lib/javaversion.c (execute_and_read_line): Likewise.
* lib/csharpcomp.c (compile_csharp_using_mono,
compile_csharp_using_dotnet, compile_csharp_using_sscli): Update
execute, create_pipe_in invocations.
* lib/csharpexec.c (execute_csharp_using_mono,
execute_csharp_using_dotnet, execute_csharp_using_sscli): Likewise.
* lib/javacomp.c (compile_using_envjavac, compile_using_javac,
execute_and_read_line, is_javac_present): Likewise.
* lib/pipe-filter-gi.c (pipe_filter_gi_create): Update create_pipe_bidi
invocation.
* lib/pipe-filter-ii.c (pipe_filter_ii_execute): Likewise.
* tests/test-execute-main.c (main): Update execute invocations.
* tests/test-execute-script.c (main): Likewise.
* tests/test-spawn-pipe-main.c (main): Update create_pipe_bidi
invocation.
* tests/test-spawn-pipe-script.c (main): Update create_pipe_in
invocations.
* NEWS: Mention the changes.
0001-execute-spawn-pipe-Support-DLL-dependencies-of-Windo.patch
Description: Text Data
- execute, spawn-pipe: Support DLL dependencies of Windows executables,
Bruno Haible <=