#42547: imake @1.0.5_1 Proposed fix for imake / clang inoperability -----------------------+-------------------------------- Reporter: qbarnes@… | Owner: macports-tickets@… Type: defect | Status: new Priority: Normal | Milestone: Component: ports | Version: 2.2.1 Keywords: | Port: -----------------------+-------------------------------- There's been a number of bugs submitted against various ports packages which break build because of xmkmf/imake not working with clang. (#41951, #40862, #41293, #41434, et. al.). There's been various hacks and workarounds to the packages, but nothing I've found that addresses the imake problem directly. I have a patch set attached to fix imake for this problem. This can not only fix it for various dependent ports, but will fix it for people wanting to use xmkmf and imake on non-macports packages (like me). I'm not an active Macports maintainer, so please scrutinize my proposed changes carefully. If this patchset is accepted as a changeset, I would also recommend deleting the two IMAKECPP environment appends from src/port1.0/portconfigure.tcl. Once imake is fixed, this workaround in portconfigure.tcl is unnecessary and actually causes problems and additional work for port maintainers. When building software that uses xmkmf, there is no need to blacklist clang, but these IMAKECPP environment changes require maintainers to always blacklist clang or manually set IMAKECPP themselves to override. In my suggested changes to imake, I do blacklist clang, but there is no reason I had to. It just saves some amount of hacking on imakemdep.h. The main change to the Portfile is to change imakemdep.h to set the DEFAULT_CC macro to ${configure.cc}, so I set that via blacklisting clang. I had considered making the imake package dependent on gcc42 or gcc48 and using "gcc-mp-4.2" (or -4.8), instead of ${configure.cc}, but thought the blacklist/${configure.cc} approach was better. In imakemdep.h there is no need to define both DEFAULT_CPP and DEFAULT_CC as had been previously done. DEFAULT_CC takes precedence. The patch file has three changes. One is for the DEFAULT_CC string that gets replaced with ${configure.cc}. The second one was in the last patch file. There is no need for it now since we're not building with clang, but I kept it anyways. I also made the equivalent change later down in the file has well. If the imake maintainer desires, just leave off the last two deltas. I left them in though because with the right changes to imakemdep.h it should be possible to build imake with clang, just not use it for imake's preprocessor. I tried for some time to see if I could get clang to work with imake, but I concluded that it is impossible, at least for now with the way clang is currently implemented. If someone wants to prove me wrong, I'd be happy to hear it. I'll summarize my findings and conclusions here if anyone wants to pick up the torch and cares to try. With clang, its preprocessor has two modes of operation, "traditional" and "standards compliant". Though in traditional mode, it does not follow many other K&R C preprocessors do when filtering out comments. With many K&R C preprocessors a comment (e.g. {{{/**/}}}) will be completely removed. However, clang inserts a whitespace, which is allowed (thus creating the 'X11 .rules' file not found error). In standard mode, we have ## operators, but they won't work for what the compiler considers invalid preprocessing tokens. Even if that were worked around somehow, the clang preprocessor also mangles tab characters replacing them with a single space character -- a fatal flaw for a makefile. From my reading of ISO C99, Annex A.1.1, I don't see how a character sequence such as '<TopLevelProject' is declared an invalid preprocessing token given the last entry of the definition of a "preprocessing-token". If someone knows why, I'm curious. If you would, please send me an email of what I'm not reading correctly. The general problem with imake though is that it should never have been designed to use a C preprocessor on a non-C files. For upstream imake developers, the only real fix is to abandon using a C preprocessor and provide a compatible preprocessor as part of the package. I also tried using "mcpp" in -@kr mode as the cpp for imake. It failed with a memory fault. -- Ticket URL: <https://trac.macports.org/ticket/42547> MacPorts <http://www.macports.org/> Ports system for OS X