On Nov 24, 2020, at 16:15, Clemens Lang wrote:
> This will become a significant problem with the release of Big Sur,
> since Apple has made -Wimplicit-function-declaration an error by default
> due to details of the calling convention on Apple Silicon.
Thanks Clemens. I've been meaning to write about that problem here. I want to
elaborate on this issue for our developers who haven't been following it
closely.
It's the version of clang shipped with Xcode 12 that introduced the change that
made implicit declaration of functions an error rather than a warning, so it
also affects Catalina users who have upgraded to Xcode 12 (or the matching
CLT). It does not affect our Catalina buildbot worker because I'm keeping it at
Xcode 11.x (with the matching CLT).
There are a zillion ports affected by this issue, so we have a lot of work to
do to fix them all, and we appreciate all developers who have time to pitch in
and fix ports. There's often a tendency for developers to stick to the ports
they know and maintain and to ignore tickets about other ports, but with this
problem the needed fixes are often pretty similar so once you understand how to
fix it once or twice, you can apply that knowledge to fix other ports even if
you're not familiar with those ports.
Before trying to patch the problem yourself, check if there's a new version of
the software available. Maybe updating the port would fix it. If no new version
is available, it can also be worthwhile to see if Debian or another package
management system out there has already developed patches that we could use. If
you do have to develop a patch yourself, and the software is still being
actively developed, you should usually send the patch back to the developers so
they can include it in the next version. Add the URL of your bug report to the
header of your patch.
The way to fix the problem is usually to include the right headers. Often clang
will tell you in the error message what the right header is. If it doesn't, you
can look up the function in the manpages using "man 3" or "man 2". For example
"man 3 exit" tells you that to use "exit" you need to "#include <stdlib.h>".
There are four ways that this problem typically manifests. First, a port could
fail to build in the build phase with an error about implicit function
declarations. This is straightforward; you would usually fix the file mentioned
in the error. Second, a port could fail in the configure phase because one of
the configure tests failed to find something essential because of implicit
function declarations in that specific test in the configure script. This is
more difficult because MacPorts 2.6.4 and earlier don't show you the error in
the main log; you have to look in the config.log. This is the problem that this
change from Clemens is designed to address, by looking through config.log for
you and pulling relevant errors into the main log. To fix the problem, if your
port does not auto(re)conf, patch the configure script tests. If your port does
auto(re)conf, patch the tests in their original files
(configure.ac/configure.in/any .m4 file, possibly even one installed by another
port). A third possibility is that a configure test could get the wrong result
due to implicit function declaration but allow configure to succeed, and then
the build fails later with any number of unexpected errors. The fourth way is
like the third expect that the build succeeds but is built wrong due to wrong
configure results; in this case, in addition to fixing the problem, the
revision would need to be increased to rebuild it.
There are two possible fixes for implicit declaration of function "exit", and
this is a common error because so many configure script tests use it without
including the required header. One possible fix is to add "#include
<stdlib.h>". The other possible fix, provided that "exit" is being called from
"main", is to replace "exit(...)" with "return ...".
Please resist the urge to simply add -Wno-error=implicit-function-declaration
to CFLAGS. This returns you to the way that Xcode 11 and earlier worked and
while it may allow the build to succeed on x86_64, the build could either fail
on arm64 or worse yet succeed but crash at runtime. Apple made this condition
an error for a reason: the compiler needs to know whether a function is
variadic or non-variadic in order to know how to generate the correct machine
code to call the function on arm64, and the way that the compiler knows that is
by seeing a function declaration or definition before the function is called.
In other words, include the header that contains the declaration.
You can find many of the tickets about ports that need fixing by searching the
issue tracker for summary "implicit":
https://trac.macports.org/query?status=!closed&summary=~implicit
If you need examples of how to fix these kinds of problems you can search
commits for "implicit":
https://github.com/macports/macports-ports/search?q=implicit&type=commits
We often name the patchfile "implicit.patch" to make it easier to find so you
can also search your local ports tree for files of that name. We often put the
exact error messages that were encountered that the patch fixes in the header
of the patchfile to make it easier for others to find when trying to figure out
how to fix these errors.
If you want to participate in experiencing and fixing these problems but you
haven't upgraded to Xcode 12, you can fake it by modifying portconfigure.tcl:
--- src/port1.0/portconfigure.tcl.orig
+++ src/port1.0/portconfigure.tcl
configure.classpath
# compiler flags section
default configure.optflags -Os
-default configure.cflags {${configure.optflags}}
-default configure.objcflags {${configure.optflags}}
+default configure.cflags {${configure.optflags}
-Werror=implicit-function-declaration}
+default configure.objcflags {${configure.optflags}
-Werror=implicit-function-declaration}
default configure.cppflags {[portconfigure::configure_get_cppflags]}
proc portconfigure::configure_get_cppflags {} {
global prefix
This is what I'm doing on High Sierra. Note that this will only be accurate for
ports that actually honor MacPorts CFLAGS, but if you encounter a port that
does not, that is in and of itself a bug that should be fixed.