Bug 107368

Summary: Use of 'cpp' extension for non-C++ (and non-C) files to be processed with cpp causes unnecessary requirement for cc1plus during build, build process exits 0 even if it's missing
Product: xorg Reporter: Adam Williamson <adamw>
Component: App/xinitAssignee: Xorg Project Team <xorg-team>
Status: RESOLVED MOVED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Adam Williamson 2018-07-25 01:13:21 UTC
Fedora recently removed gcc and gcc-c++ from the default buildroot, meaning packages that need these compilers have to explicitly BuildRequire them. Our xorg-x11-xinit package BuildRequired gcc, but not gcc-c++. Somehow, a build run under these conditions completed, even though it was obviously heavily broken:

https://koji.fedoraproject.org/koji/buildinfo?buildID=1127335
https://kojipkgs.fedoraproject.org//packages/xorg-x11-xinit/1.4.0/2.fc29/data/logs/x86_64/build.log

Note the clear errors in the build.log:

cpp: error trying to exec 'cc1plus': execvp: No such file or directory
cpp: error trying to exec 'cc1plus': execvp: No such file or directory

yet somehow, the 'make -j6' command must have exited 0, or else the package build would have aborted at that point.

The result was a 'successful' package build with a zero-length startx (and probably other weirdness, that's just the only symptom I noticed). Obviously, 'make' should exit with a non-zero exit code in this case.
Comment 1 Adam Williamson 2018-07-25 01:29:29 UTC
Alternatively, perhaps this should be discovered at configure stage - it seems like configure checks that a C compiler is available, but not a C++ compiler.
Comment 2 Alan Coopersmith 2018-07-25 01:32:23 UTC
xinit only needs a C compiler and a C preprocessor - it doesn't know if distros
have packaged those to require C++ components too, but it doesn't need one.
Comment 3 Adam Williamson 2018-07-25 01:41:52 UTC
Oh, I see. Hum. I wonder if it's the .cpp extensions on the files that confuse things? I'll have to ask our compiler folks. Thanks.
Comment 4 Alan Coopersmith 2018-07-25 01:45:49 UTC
BTW, if this is because gcc is confusing *.cpp as being C++ instead of input
to a C pre-processor when calling cpp, then we need a solution that doesn't
reintroduce Bug 69439 that we fixed by passing the input via filename instead
of stdin:
https://cgit.freedesktop.org/xorg/app/xinit/commit/?id=463b85fcf51d8ff5886ebe1f3481e5cb4d603436

Perhaps add "-x c" to the flags we test cpp for in XORG_PROG_RAWCPP in
xorg-macros.m4 ?
Comment 5 Adam Williamson 2018-07-25 01:56:13 UTC
"BTW, if this is because gcc is confusing *.cpp as being C++ instead of input
to a C pre-processor when calling cpp"

I *suspect* that's what's going on, yes, but I'm asking our GCC folks to confirm. Thanks for the pointer to the other bug. Surely it wouldn't be too difficult to just...change the suffix, though? I mean, .cpp *is* pretty well-established by now as meaning "this here is C++ source code".

(Out of interest, why does xinit use the C preprocessor to do this work rather than just doing it with make? Wouldn't that be the more normal way to do it?)
Comment 6 Adam Williamson 2018-07-25 02:24:30 UTC
I confirmed that if I change the expected extension to '.cpreproc' and rename all the input files with that extension, the build works fine with no gcc-c++ installed.
Comment 7 Adam Williamson 2018-07-25 16:12:27 UTC
From Jakub Jelinek:

"If it is not really C or C++, I'd suggest using -xassembler-with-cpp then,
that will cause fewest C/C++ specific changes while preprocessing it.
And also consider -P.

cpp is documented extension for C++:
'FILE.cc'
'FILE.cp'
'FILE.cxx'
'FILE.cpp'
'FILE.CPP'
'FILE.c++'
'FILE.C'
     C++ source code that must be preprocessed.  Note that in '.cxx',
     the last two letters must both be literally 'x'.  Likewise, '.C'
     refers to a literal capital C.

        Jakub"
Comment 8 Adam Williamson 2018-07-25 17:39:25 UTC
Jakub also points out this:

<jakub> e.g. when preprocessing C or C++ with newer gcc versions, if not -P or -xassembler-with-cpp, it can break lines in order to add more #line directives for better location preservation

however, I found something interesting - if I patch the build to use '-xc' or '-xassembler-with-cpp', we get the blank lines at the top of startx! Odd.
Comment 9 Adam Williamson 2018-07-25 17:48:34 UTC
So, hah. If I change the filename to 'startx.foo' but call cpp with '-xc++' I get the file with no blank lines.

So I think what this means is: we get the blank lines when cpp (perhaps only *newer versions* of cpp?) treats the input as C or assembler. We *don't* get blank lines when cpp treats the input as C++. This is actually *the reason why* https://cgit.freedesktop.org/xorg/app/xinit/commit/?id=463b85fcf51d8ff5886ebe1f3481e5cb4d603436 "fixed" the blank line problem: by passing the input as files (not stdin) it triggered cpp's "detect language by extension" behaviour, causing it to treat the files as C++! Thus if we change the file extension, or pass '-xc' or '-xassembler' (overriding the file extension-based detection), we get the blank lines again...

So...in a roundabout way...correct generation of the files really *does* require gcc-c++. :P

This still all seems very hokey to me, btw, it seems like it'd be much more sensible to do this preprocessing with autotools / make.
Comment 10 Alan Coopersmith 2018-07-25 18:18:14 UTC
(In reply to Adam Williamson from comment #5)
> I *suspect* that's what's going on, yes, but I'm asking our GCC folks to
> confirm. Thanks for the pointer to the other bug. Surely it wouldn't be too
> difficult to just...change the suffix, though? I mean, .cpp *is* pretty
> well-established by now as meaning "this here is C++ source code".

Yes, now it is, but it wasn't that well established in the mid 1980's when
the original X developers at MIT chose these file names.

Since then, as far as I know, it's just inertia keeping them in place - why
rename them and risk breaking distro patches if there's no need to do so?

Now that we know they're causing problems, we can consider changing them.

> (Out of interest, why does xinit use the C preprocessor to do this work
> rather than just doing it with make? Wouldn't that be the more normal way to
> do it?)

I know of no way to do this with make directly - how would you handle #ifdef
& #define processing via raw make?  We have converted some of our previous cpp
usage to sed in various places though - that works for cases where we just need
to replace text during the build, needs more work for more complex cases where
we want some sections to vary depending on OS.
Comment 11 Adam Williamson 2018-07-25 18:37:37 UTC
"Yes, now it is, but it wasn't that well established in the mid 1980's when
the original X developers at MIT chose these file names."

Sure, I get that :)

"I know of no way to do this with make directly - how would you handle #ifdef
& #define processing via raw make?"

Well, you'd have to adapt the approach a bit, of course. You couldn't literally use ifdefs. But I'm pretty sure there are good ways of doing it...it just seems like if you were starting from scratch today and the question was "how do we adjust the content of these shell scripts for different platforms?" the answer probably *wouldn't* be "use the C preprocessor to do it" :) Of course IMBW.
Comment 12 Alan Coopersmith 2018-07-25 18:49:11 UTC
We'd do a lot of things differently if we were starting X from scratch today,
but 34-year old systems have a lot of baggage and inertia. 8-)

It used to be worse, before we switched to automake a decade ago all our 
makefiles were generated via the C pre-processor.  (imake is basically a
wrapper around cpp with a bunch of auto-included templates & specialized
header files.)

At this point I think we're in the "Something besides cpp would be great!
Who has time available to figure out how to do that and make it happen?" state.
Comment 13 Adam Williamson 2018-07-25 18:52:57 UTC
Sure, I get that :)

Practically speaking, I guess it'd be nice to figure out why cpp apparently adds the blank lines when treating the files as C or assembler? If we could fix that, we could then just adjust the build process to pass -xc or -xassembler...

For now in Fedora I just kept the gcc-c++ build dependency, with a big comment explaining the reason and pointing to this bug...
Comment 14 GitLab Migration User 2018-08-10 20:31:06 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/xorg/app/xinit/issues/15.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.