mstorsjo / llvm-mingw

An LLVM/Clang/LLD based mingw-w64 toolchain

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Treat file content as command line (feature request)

top-master opened this issue · comments

MingW supports listing .o files in an external file, instead of passing as command-line.
I would like this to be supported by llvm-mingw as well.

Example

For example, consider object_script.Qt5Core.Release file's content to be:

INPUT(
./release/qstring.o
./release/qstringbuilder.o
./release/qstringlist.o
./release/qstringlistmodel.o
./release/qstring_compat.o
);

Then the MingW's command-line can be as short as:

g++ $(LFLAGS) -o $(TARGET) object_script.Qt5Cored.Release  $(LIBS)

Where:

LFLAGS = -shared -Wl,-subsystem,windows -Wl,--out-implib,D:/projects/qt5/qtbase/lib/libQt5Cored.a
LIBS = -lole32 -luuid -lws2_32 -ladvapi32
TARGET = D:/projects/qt5/qtbase/lib/Qt5Cored.dll

However, llvm-mingw gives error:

ld.lld: error: object_script.Qt5Core.Release: unknown file type
clang-17: error: linker command failed with exit code 1

This is an issue about what LLD supports and does not support, in mingw mode.

LLD does support taking a list of command arguments, in a file, when using the "response file" syntax, where you just list the command line arguments in a file, and pass this file to the linker as @filename.

Your example, which uses the extra syntax INPUT(...), and passing it as a regular file, is treating this file as linker script. Linker script is a very large feature, complex and messy to implement, even if the INPUT(...) case looks quite trivial.

The issue here is that some build tools, like qmake in your case, and libtool in some other cases, seem to prefer to use linker script to achieve this, rather than using response files.

In the case of qmake, this was fixed in 2018 in qt/qtbase@d92c25b, to make qmake prefer response files over linker script. This fix is part of qtbase v5.12.0 and later.

They could at least support INPUT( syntax, and leave other parts,
but in my case, I will simply add support for "response file" syntax.

Hence I checked how response file works,
basically the command-line needs an additional @ sign:

g++ $(LFLAGS) -o $(TARGET) @object_script.Qt5Cored.Release  $(LIBS)

Then the importan part, the syntax of the response file:

  • The INPIUT( prefix and the ); suffix are not allowed.

  • Whitespaces and Special-characters need to be escaped, by prefixing each with a backslash.

  • Backslashes that are not used for escaping, need to be escaped themselves, like replace each with a double-backslash, but in a file-path's case, each can simply be replaced with a single forward-slash.