Skip to content
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

GCC /dev/null conversion #1840

Closed
mati865 opened this issue Oct 19, 2016 · 14 comments
Closed

GCC /dev/null conversion #1840

mati865 opened this issue Oct 19, 2016 · 14 comments

Comments

@mati865
Copy link
Collaborator

mati865 commented Oct 19, 2016

GCC 7 (master branch) introduced selftest in gcc/Makefile.in https://github.com/gcc-mirror/gcc/blob/master/gcc/Makefile.in#L1876
It revealed bug in our GCC:

gcc -nostdinc -x c /dev/null -S -fself-test
cc1.exe: fatal error: input file 'nul.s' is the same as output file
compilation terminated.

Minimal test case: gcc -x c /dev/null -S
Interesting thing is that replacing -S with -c hides this error.
Removing -S also hides this issue (fails on linking):

$ gcc -x c /dev/null
D:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/6.2.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function `main':
C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain'
collect2.exe: error: ld returned 1 exit status

Part of discussion with @Mistuke:

Just figured it out,

I noticed if I pass

$ gcc -x c '/dev/nullss' -S

gcc.exe: error: E:/msys64/dev/nullss: No such file or directory

I do get the full directory. It turns out the unix path is being converted by the shell.

$ cygpath -w /dev/null

.\NUL

Which explains the error, why it’s trying to find nul.s,

It happens without the -S as well:

E:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/5.3.0/cc1.exe -quiet -v -iprefix E:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/5.3.0/ -D_REENTRANT nul -quiet -dumpbase nul -mtune=generic -march=x86-64 -auxbase nul -version -o E:\msys64\tmp\ccA3Bn6s.s

But the driver doesn’t seem to care then.

I don’t know why It worked for the other repo though. Is it possible to turn off this path conversion and then try?

Cheers,

Tamar

@Alexpux and @mingwandroid, you were creating patches. Do you have any clue?

@Mistuke
Copy link
Contributor

Mistuke commented Oct 21, 2016

So, i think the goal is to prevent msys2 from converting this path.

msys2/MSYS2-packages#84 and https://sourceforge.net/p/msys2/wiki/Porting/ seem relevant here. Looks like setting MSYS2_ARG_CONV_EXCL=/dev/null before building should solve it.

@Mistuke
Copy link
Contributor

Mistuke commented Oct 21, 2016

And indeed it does:

Tamar@Rocky MINGW64 ~
$ MSYS2_ARG_CONV_EXCL=/dev/null gcc -x c /dev/null -S

Tamar@Rocky MINGW64 ~
$

You can probably add it to the PKGBUILD somewhere no @mati865 ?

@mati865
Copy link
Collaborator Author

mati865 commented Oct 21, 2016

@Mistuke it would have to be patched in GCC sources.

@rallenh
Copy link

rallenh commented Nov 2, 2016

I found that the MSYS2 file/path conversion exclusion didn't work:

MSYS2_ARG_CONV_EXCL=/dev/null /c/mingwtrunk/x86_64-trunk-posix-seh-rt_v4-rev0/build/gcc-trunk/./gcc/xgcc -B/c/mingwtrunk/x86_64-trunk-posix-seh-rt_v4-rev0/build/gcc-trunk/./gcc/ -nostdinc -x c /dev/null -S -fself-test
xgcc.exe: error: /dev/null: No such file or directory
xgcc.exe: warning: '-x c' after last input file has no effect
xgcc.exe: fatal error: no input files
compilation terminated.
make[3]: *** [Makefile:1920: s-selftest] Error 1
make[3]: Leaving directory '/c/mingwtrunk/x86_64-trunk-posix-seh-rt_v4-rev0/build/gcc-trunk/gcc'
make[2]: *** [Makefile:4559: all-stage1-gcc] Error 2
make[2]: Leaving directory '/c/mingwtrunk/x86_64-trunk-posix-seh-rt_v4-rev0/build/gcc-trunk'
make[1]: *** [Makefile:21252: stage1-bubble] Error 2
make[1]: Leaving directory '/c/mingwtrunk/x86_64-trunk-posix-seh-rt_v4-rev0/build/gcc-trunk'
make: *** [Makefile:947: all] Error 2

What I did do to handle this was create an empty file with a filename that's removed in the mostlyclean make target:

Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in (revision 241757)
+++ gcc/Makefile.in (working copy)
@@ -1879,7 +1879,7 @@
 # Specify a dummy input file to placate the driver.
 # Specify -nostdinc to work around missing WIND_BASE environment variable
 # required for *-wrs-vxworks-* targets.
-SELFTEST_FLAGS = -nostdinc -x c /dev/null -S -fself-test
+SELFTEST_FLAGS = -nostdinc -x c $(shell echo -n > tmp-selftest && echo tmp-selftest) -S -fself-test

 # Run the selftests during the build once we have a driver and a cc1,
 # so that self-test failures are caught as early as possible.

Which then I was able to get a working gcc:

gcc version 7.0.0 20161101 (experimental) (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

Links for the changes to GCC:
https://github.com/gcc-mirror/gcc/commit/99b4f3a2d5bf2c137de9731e27b483eb6b462fd9
https://github.com/gcc-mirror/gcc/commit/441751466e69eaf8d8da7c0d388055509b35bc63
https://github.com/gcc-mirror/gcc/commit/c2d86129ef8141bb214958ca90be15fbeb42f4b1

Is it portable to use /dev/null as input? All GCC targets supports this?

@mati865
Copy link
Collaborator Author

mati865 commented Nov 3, 2016

@rallenh It was talked about on IRC. MSYS2_ARG_CONV_EXCL trick will work only for MSYS2 GCC package (not mingw-w64).
I was removing -S -fself-test part to compile GCC for myself.

Is it portable to use /dev/null as input? All GCC targets supports this?

I think it's fine on all POSIX targets. On Windows it's ok until you add -S argument.

@rallenh
Copy link

rallenh commented Nov 3, 2016

@mati865 Ah. I see. I didn't catch that. Thanks for the clarification.

I don't understand why you'd ask xgcc to build an assembly file from /dev/null (or an empty for that matter). Is the s-selftest target just to confirm it produces an assembly file with .file and .ident directives and doesn't emit errors on invocation?

@Alexpux
Copy link
Member

Alexpux commented Nov 3, 2016

@mati865 @rallenh MSYS2_ARG_CONV_EXCL works only for MINGW packages because for MSYS2 programs no paths conversion needed

@Mistuke
Copy link
Contributor

Mistuke commented Nov 3, 2016

@mati865 Sorry I promised to look into this, but have been dealing with some issues with my apartment and hadn't had the chance.

Anyway, the bug is a tiny one, should be easy to fix.

What is happening is that:

The MSYS shell is converting /dev/null into \\.\NUL. This can be confirmed by the output of

Tamar@Rocky MINGW64 ~/ghc2
$ cygpath -w /dev/null
\\.\NUL

Now this is great, because it means the test IS portable.

The driver thus receives gcc -x c \\.\NUL -S as the input. However, gcc et al don't support raw device paths (I believe). So internally the c driver is converting this NT device path to the modern windows equivalent of nul which is a shorthand for \Device\nul before it calls the compiler.

You can confirm this by seeing what the driver makes a call to

E:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/6.2.0/cc1.exe -quiet -iprefix E:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/6.2.0/ -D_REENTRANT nul -quiet -dumpbase nul -mtune=generic -march=x86-64 -auxbase nul -o nul.s

Now there's the error. When you add -S the system doesn't recognize that nul is a special device driver or endpoint as it does everywhere else, so naively it appends a .s to the filename.

This is why the test breaks only when using -S.

Portable workaround is to change the test to explicitly give an output file.

$ gcc -x c /dev/null -S -o /dev/null

Because the driver won't touch the name then. GCC sources should be patch to correctly treat nul in the filename generation for -S and not append the .s to nul.

I'll see if I can find some time tonight to whip up a patch. If I do, it likely won't be posted until sometime next week.

@Mistuke
Copy link
Contributor

Mistuke commented Nov 3, 2016

Sorry, I've had my coffee now.

GCC isn't treating the /dev/null specially at all, it's just creating a file null.s as well. On Windows of course nul.<anything> is illegal. So the self test is just.. wrong.. I'll submit a patch.

@Mistuke
Copy link
Contributor

Mistuke commented Nov 3, 2016

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78196 is the upstream report.

@mati865
Copy link
Collaborator Author

mati865 commented Nov 3, 2016

@Mistuke no problem. I've also been very busy lately.
Thanks for taking care of it.

@Mistuke
Copy link
Contributor

Mistuke commented Nov 7, 2016

I've committed the patches upstream. GCC should build now.

@mati865 mati865 closed this as completed Nov 7, 2016
@mati865
Copy link
Collaborator Author

mati865 commented Nov 7, 2016

@zap8600
Copy link

zap8600 commented Feb 10, 2022

Hi. I'm attempting to compile gcc 7.1.0. The build goes well until I reach s-selftest. I get the error nul: invalid argument. SELFTEST_FLAGS is set to -nostdinc -x c /dev/null -S -o /dev/null -fself-test. How can this be fixed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants
@mati865 @Mistuke @Alexpux @rallenh @zap8600 and others