imake RAWCPP errors
Mac OS will any day now remove support for 32-bit applications. Before then, I have to recompile our modified IRAF xgterm application for 64 bits. xgterm is in the IRAF x11iraf package, now community supported at https://github.com/iraf-community/x11iraf. I last compiled the x11iraf package ten years ago. Since then, Apple X11 is gone and XQuartz is now based on X.org. Also, missing now are the xmkmf and imake tooks that the x11iraf package requires.
I found the imake-1.0.8 package and built my own xmkmf and imake tools. I encountered the problems others have brought up before with the Apple clang C preprocessor and followed the advice (mostly from homebrew) to work around that. However, using the GNU gcc 8.3.0 preprocessor, there are still errors:
$ /usr/local/bin/cpp-8 -traditional -DPREPROC='"gcc -E"' mdepend.cpp | /usr/local/bin/gsed -e /^\#/d | /usr/local/bin/gsed -e s/XCOMM/\#/ > ccmakedep
mdepend.cpp:128:6: error: invalid preprocessing directive #Flag
# Flag to tell compiler to output dependencies directly
^~~~
mdepend.cpp:129:6: error: invalid preprocessing directive #For
# For example, with Sun compilers, -xM or -xM1 or
^~~
mdepend.cpp:130:6: error: invalid preprocessing directive #with
# with gcc, -M
^~~~
mdepend.cpp:198:9: warning: missing terminating ' character
| awk '{
^
mdepend.cpp:236:28: warning: missing terminating ' character
| egrep -v '^[^:]*:[ ]*$' >> $DEPENDLINES
^
The imake Makefile runs $(RAWCPP) to process three files: xmkmf.cpp, mdepend.cpp, and mergelib.cpp. mdepend.cpp is the only one that has any make errors. (That is not to say that I am sure the output for the others is valid, however.) The errors at lines 128-130 are because mdepend.cpp does not use XCOMM to introduce comments. After fixing those lines, the remaining warnings allow the make to complete without errors, but the resulting ccmakedep is not valid. For example, this is a portion of the output in ccmakedep, which has had the "\" line continuation in the mdepend.cpp source file removed:
for i in $files
do
$CPPCMD $i
| sed -n "/^#/s;^;$i ;p"
done
This is because all these files are shell scripts, yet their .cpp suffixes cause the C preprocessor to process them as C++ source files. In particular, all the line continuations are removed, resulting in illegal shell syntax.
My fix was to use $(SED) to process these files instead of $(RAWCPP):
--- Makefile.am
+++ Makefile.am
@@ -76,13 +76,13 @@
$(MKHTMLINDEX)
xmkmf: xmkmf.cpp
- $(AM_V_GEN)$(RAWCPP) $(RAWCPPFLAGS) -DCONFIGDIRSPEC='"-I$(XCONFDIR)"' $(srcdir)/xmkmf.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
+ $(AM_V_GEN)$(SED) -e 's%\bCONFIGDIRSPEC\b%-I$(XCONFDIR)%g' $(srcdir)/xmkmf.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
ccmakedep: mdepend.cpp
- $(AM_V_GEN)$(RAWCPP) $(RAWCPPFLAGS) -DPREPROC='"$(PREPROCESSCMD_MKDEPEND)"' $(srcdir)/mdepend.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
+ $(AM_V_GEN)$(SED) -e 's/\bPREPROC\b/$(PREPROCESSCMD_MKDEPEND)/g' $(srcdir)/mdepend.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
mergelib: mergelib.cpp
- $(AM_V_GEN)$(RAWCPP) $(RAWCPPFLAGS) -DARCMD="$(ARCMD)" -DRANLIB="$(RANLIB)" $(srcdir)/mergelib.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
+ $(AM_V_GEN)$(SED) -e 's/\bARCMD\b/$(ARCMD)/g' -e 's/\bRANLIB\b/$(RANLIB)/g' $(srcdir)/mergelib.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
if HAS_PERL
MKHTMLINDEX_SCRIPT = $(srcdir)/mkhtmlindex.pl
--- Makefile.in
+++ Makefile.in
@@ -980,15 +980,14 @@
.PRECIOUS: Makefile
-
xmkmf: xmkmf.cpp
- $(AM_V_GEN)$(RAWCPP) $(RAWCPPFLAGS) -DCONFIGDIRSPEC='"-I$(XCONFDIR)"' $(srcdir)/xmkmf.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
+ $(AM_V_GEN)$(SED) -e 's%\bCONFIGDIRSPEC\b%-I$(XCONFDIR)%g' $(srcdir)/xmkmf.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
ccmakedep: mdepend.cpp
- $(AM_V_GEN)$(RAWCPP) $(RAWCPPFLAGS) -DPREPROC='"$(PREPROCESSCMD_MKDEPEND)"' $(srcdir)/mdepend.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
+ $(AM_V_GEN)$(SED) -e 's/\bPREPROC\b/$(PREPROCESSCMD_MKDEPEND)/g' $(srcdir)/mdepend.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
mergelib: mergelib.cpp
- $(AM_V_GEN)$(RAWCPP) $(RAWCPPFLAGS) -DARCMD="$(ARCMD)" -DRANLIB="$(RANLIB)" $(srcdir)/mergelib.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
+ $(AM_V_GEN)$(SED) -e 's/\bARCMD\b/$(ARCMD)/g' -e 's/\bRANLIB\b/$(RANLIB)/g' $(srcdir)/mergelib.cpp | $(SED) -e /^\#/d | $(SED) -e s/XCOMM/\#/ > $@
mkhtmlindex: $(MKHTMLINDEX_SCRIPT)
$(AM_V_GEN)cp $(MKHTMLINDEX_SCRIPT) $@
This avoids completely the errors caused by parsing a shell script using C++ syntax. Another option is to change the suffix of the files to something that is not treated as C++. Or, GNU cpp accepts the -x lang option (e.g., -x c), which can accomplish the same thing. Or, redirecting the input to stdin works.
Using $(SED) makes the most sense to me. The man page for cpp even warns about misusing the C preprocessor this way. If $(SED) is used, then all the tests of the behavior of RAWCPP in aclocal.m4 can go away. They are not all done properly anyway. I found that aclocal.m4 has a test that the C preprocessor preserves white space. The test is performed using a .c file suffix, which is equivalent to the -x c cpp option. That does preserve the white space. The trouble is, the output from the make does not. The aclocal.m4 test should use the .cpp suffix in the test, which is the actual suffix of the files in the Makefile $(RAWCPP) commands. Had that test been accurate, an error message would have been emitted complaining that RAWCPP "does not preserve whitespace with or without -traditional. I don't know what to do."