Skip to content

llvm-rc: not merging string literals for paths #51286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jeremyd2019 opened this issue Sep 22, 2021 · 8 comments
Closed

llvm-rc: not merging string literals for paths #51286

jeremyd2019 opened this issue Sep 22, 2021 · 8 comments
Labels
bugzilla Issues migrated from bugzilla llvm-tools All llvm tools that do not have corresponding tag

Comments

@jeremyd2019
Copy link
Contributor

Bugzilla Link 51944
Version 12.0
OS Windows NT
CC @mstorsjo

Extended Description

I'm not really sure if this is something that only works in windres or if it also works in rc.exe. I came across this rc in virt-viewer

llvm-rc: Error in ICON statement (ID 2):
Is a directory
'['D:/a/temp/msys/msys64/clang64/bin/windres.EXE', '-DICONDIR=\"C://mingw-w64-virt-viewer/src/build-x86_64-w64-mingw32/icons\"', '-DMANIFESTDIR=\"C:/_/mingw-w64-virt-viewer/src/virt-viewer-10.0/src\"', '-i', 'src/virt-viewer.rc', '-o', 'src/virt-viewer-rc.o']' returned non-zero exit status 1.

The RC file in question is https://gitlab.com/virt-viewer/virt-viewer/-/blob/v10.0/src/virt-viewer.rc.in , and the ICON statement is

2 ICON ICONDIR "/virt-viewer.ico"

I assume they meant for that to somehow transform into 2 ICON "C:/_/mingw-w64-virt-viewer/src/build-x86_64-w64-mingw32/icons/virt-viewer.ico". This reminded me of https://reviews.llvm.org/D105621#inline-1004064 but this is in an ICON statement not a user defined resource.

@jeremyd2019
Copy link
Contributor Author

This project was already using meson configure_file on the rc file so I worked around this by subbing in the full paths there rather than trying to use the preprocessor in this way. https://github.com/msys2/MINGW-packages/blob/360e0b78af982809fb35fa5ed94078f613bea6e5/mingw-w64-virt-viewer/001-rc-generation-fixes.patch

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
@jeremyd2019
Copy link
Contributor Author

Another, more common instance seems to exist in an rc file provided by wxWidgets (intended to be included in the rc file for programs using wxWidgets) for their default manifest: https://github.com/wxWidgets/wxWidgets/blob/866cdfe20000178145896497c23ce4598cc88068/include/wx/msw/wx.rc#L122

@jeremyd2019 jeremyd2019 changed the title llvm-rc: not merging string literals in ICON type llvm-rc: not merging string literals for paths Feb 3, 2022
@ZachBacon
Copy link

What seems to be odd is that the issue Jeremy is referencing is what I'm experiencing in an clang msys2 environment in a ci setup. But locally it builds just fine.

Anyways here's the ci logs

https://github.com/ZachBacon/visualboyadvance-m/runs/5057487429?check_suite_focus=true

@hmartinez82
Copy link

hmartinez82 commented Jun 26, 2022

I was able to reproduce this while building GIMP for Windows using Clang in MSYS2.

Making all in .
make[3]: Entering directory '/d/Dev/Github/gimp/app'
windres --define ORIGINALFILENAME_STR="gimp-2.99.exe" \
        --define INTERNALNAME_STR="gimp-2.99" \
        --define TOP_SRCDIR="`echo .. | sed 's*//*/*'`" \
        -I"`echo ../app | sed 's%/\+%/%'`" \
        -I"`echo ../app | sed 's%/\+%/%'`"\
        -I"`echo .. | sed 's%/\+%/%'`"\
        ../build/windows/gimp.rc gimp-2.99.rc.o
llvm-rc: Error in ICON statement (ID 1):
Is a directory
make[3]: *** [Makefile:1640: gimp-2.99.rc.o] Error 1

The rc file contents:

...
#include "winuser.h"
1	ICON	QUOTE(TOP_SRCDIR) "/build/windows/wilber.ico"
2	ICON	QUOTE(TOP_SRCDIR) "/build/windows/fileicon.ico"
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST QUOTE(TOP_SRCDIR) "/build/windows/gimp.manifest"

@mstorsjo
Copy link
Member

I finally took some time to finish my half-done attempt at fixing this, and posted it for review at #68685.

gnomesysadmins pushed a commit to GNOME/gimp that referenced this issue Oct 10, 2023
This should hopefully fix this error in the CI:

> llvm-rc: Error in ICON statement (ID 1):

See: llvm/llvm-project#51286
gnomesysadmins pushed a commit to GNOME/gimp that referenced this issue Oct 11, 2023
This should hopefully fix this error in the CI:

> llvm-rc: Error in ICON statement (ID 1):

See: llvm/llvm-project#51286
mstorsjo added a commit to mstorsjo/llvm-project that referenced this issue Oct 12, 2023
A number of constructs allow more than one string literal
for what represents one single string - version info values,
string tables, user data resources, etc. This mostly works
like how a C compiler merges consecutive string literals,
like "foo" "bar" as producing the same as "foobar". This is
beneficial for producing strings with some elements provided
by the preprocessor.

MS rc.exe only supports this in a few fixed locations (most of
which are already supported), while GNU windres supports this
essentially anywhere in any string. See
b989fcb for one recent change
that extended support for this in one specific resource.

A reasonable use case for multiple concatenated string literals
that GNU windres accepts is `1 ICON DIR "/name.ico"`, where the
directory is provided via the preprocessor, expanding to another
string literal; this is llvm#51286.

To support this, extend the tokenizer to concatenate consecutive
quoted string tokens, when invoked in windres mode.

For cases where the difference between narrow and wide strings
is significant (e.g. in userdata resources), GNU windres treats
`L"aaa" "bbb"` the same as `L"aaabbb"`, contrary to rc.exe
which treats it as the wide string `"aaa"` followed by the
narrow string `"bbb"`. Similarly, windres rejects the sequence
`"aaa" L"bbb"`.

However, in contexts where the end result actually is UTF16,
GNU windres does accept such mismatched string representations.
Therefore, it seems clear that GNU windres doesn't do the
merging on the string token level.

Many of the existing windres tests happen to use
tag-stringtable-basic.rc as test input; this file contains a
case of `"wor" L"ld"` which now is rejected by the tokenizer in
windres mode - therefore switch those tests, where the actual input
file doesn't matter, to a different file.
gnomesysadmins pushed a commit to GNOME/gimp that referenced this issue Oct 12, 2023
This should hopefully fix this error in the CI:

> llvm-rc: Error in ICON statement (ID 1):

See: llvm/llvm-project#51286
gnomesysadmins pushed a commit to GNOME/gimp that referenced this issue Oct 14, 2023
This should hopefully fix this error in the CI:

> llvm-rc: Error in ICON statement (ID 1):

See: llvm/llvm-project#51286
gnomesysadmins pushed a commit to GNOME/gimp that referenced this issue Oct 15, 2023
This should hopefully fix this error in the CI:

> llvm-rc: Error in ICON statement (ID 1):

See: llvm/llvm-project#51286
gnomesysadmins pushed a commit to GNOME/gimp that referenced this issue Oct 15, 2023
This should hopefully fix this error in the CI:

> llvm-rc: Error in ICON statement (ID 1):

See: llvm/llvm-project#51286
mstorsjo added a commit to mstorsjo/llvm-project that referenced this issue Oct 16, 2023
GNU windres supports this, while MS rc.exe doesn't.

MS rc.exe only supports treating consecutive string literals as
if they were fused into one in a few fixed locations (most of
which are already supported), while GNU windres supports this
essentially anywhere in any string. See
b989fcb for one recent change
that extended support for this in one specific resource.

A reasonable use case for multiple concatenated string literals
that GNU windres accepts is `1 ICON DIR "/name.ico"`, where the
directory is provided via the preprocessor, expanding to another
string literal; this is llvm#51286.

Extend the parser to try to consume all consecutive string
tokens, whenever reading a filename. Adjust the handling of user
data resources read from a file to use the readFilename() helper.

While this probably doesn't cover every single case where GNU
windres might accept concatenated string literals, this is
the primary missing case that has been reported so far.
mstorsjo added a commit that referenced this issue Oct 16, 2023
GNU windres supports this, while MS rc.exe doesn't.

MS rc.exe only supports treating consecutive string literals as if they
were fused into one in a few fixed locations (most of which are already
supported), while GNU windres supports this essentially anywhere in any
string. See
b989fcb for one recent change that
extended support for this in one specific resource.

A reasonable use case for multiple concatenated string literals that GNU
windres accepts is `1 ICON DIR "/name.ico"`, where the directory is
provided via the preprocessor, expanding to another string literal; this
is #51286.

Extend the parser to try to consume all consecutive string tokens,
whenever reading a filename. Adjust the handling of user data resources
read from a file to use the readFilename() helper.

While this probably doesn't cover every single case where GNU windres
might accept concatenated string literals, this is the primary missing
case that has been reported so far.
@mstorsjo
Copy link
Member

mstorsjo commented Oct 16, 2023

Fixed by 6f41510.

@mati865 and others - you may want to cherrypick this into msys2.

I'm not entirely sure about requesting a backport to 17.x here for this (it's too late for 17.0.3 which is cut tomorrow, and we're pretty far down the release branch already so the threshold for what to backport is pretty high by 17.0.4). Or any opinions from @cjacek or @tru?

(Also, theoretically, this could affect using llvm-rc in the MS rc mode, as it interprets things slightly differently, but I think it's mostly theoretical to come up with a legal case that now would be parsed differently?)

@tru
Copy link
Collaborator

tru commented Oct 16, 2023

It doesn't look like a regression to me. So my vote is for it to wait until 18.x unless I am misunderstanding the PR.

@mstorsjo
Copy link
Member

It doesn't look like a regression to me. So my vote is for it to wait until 18.x unless I am misunderstanding the PR.

Yep, not a regression; I was contemplating the backport-worthyness in the category "other small and safe bugfix/improvement", but I agree that this can wait to 18.x.

gnomesysadmins pushed a commit to GNOME/gimp that referenced this issue Feb 26, 2024
It was only used for the gimp-win-a64 job and was coming from MSYS2 repository
which already dropped it:
msys2/MINGW-packages@a98352b

The first patch is still needed as the upstream fix is meant to appear in clang
18 according to bug report, yet our CI still uses clang 17.0.6. See:
llvm/llvm-project#51286
gnomesysadmins pushed a commit to GNOME/gimp that referenced this issue Feb 26, 2024
It was only used for the gimp-win-a64 job and was coming from MSYS2 repository
which already dropped it:
msys2/MINGW-packages@a98352b

The first patch is still needed as the upstream fix is meant to appear in clang
18 according to bug report, yet our CI still uses clang 17.0.6. See:
llvm/llvm-project#51286
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla llvm-tools All llvm tools that do not have corresponding tag
Projects
None yet
Development

No branches or pull requests

6 participants