Skip to content

Commit

Permalink
port1.0: configure: Add check for implicit decls
Browse files Browse the repository at this point in the history
On macOS 11, implicit function declarations are now errors by default.
This may affect configure checks and actually cause software to compile
differently without us knowing.

Add a post-configure check that scans any config.log files in
${configure.dir} for indicators of such problems and warn about them, so
they will not go unnoticed. Extract the list of functions that were
found to be undeclared and check them against a whitelist of glob
expressions initialized from a file in

  _resources/port1.0/checks/implicit_function_declaration/macosx${configure.sdk_version}.sdk.list

so that functions that are legitimately undeclared on macOS can be
whitelisted globally. Note that the whitelist in

  configure.checks.implicit_function_declaration.whitelist

can also be edited per-Portfile, should that become necessary.
  • Loading branch information
neverpanic committed Nov 24, 2020
1 parent 1916d6f commit 938d852
Showing 1 changed file with 79 additions and 0 deletions.
79 changes: 79 additions & 0 deletions src/port1.0/portconfigure.tcl
Expand Up @@ -33,11 +33,13 @@
package provide portconfigure 1.0
package require portutil 1.0
package require portprogress 1.0
package require struct::set

set org.macports.configure [target_new org.macports.configure portconfigure::configure_main]
target_provides ${org.macports.configure} configure
target_requires ${org.macports.configure} main fetch checksum extract patch
target_prerun ${org.macports.configure} portconfigure::configure_start
target_postrun ${org.macports.configure} portconfigure::configure_end

This comment has been minimized.

Copy link
@ryandesign

ryandesign Nov 28, 2020

Contributor

Should this be portconfigure::configure_finish to match the existing portdestroot::destroot_finish, portactivate::activate_finish, portunarchive::unarchive_finish?

This comment has been minimized.

Copy link
@neverpanic

neverpanic Nov 28, 2020

Author Member

Certainly. See f613d8a.


namespace eval portconfigure {
}
Expand Down Expand Up @@ -1723,3 +1725,80 @@ proc portconfigure::configure_main {args} {
}
return 0
}

options configure.checks.implicit_function_declaration \
configure.checks.implicit_function_declaration.whitelist
default configure.checks.implicit_function_declaration yes
default configure.checks.implicit_function_declaration.whitelist {[portconfigure::load_implicit_function_declaration_whitelist ${configure.sdk_version}]}

proc portconfigure::check_implicit_function_declarations {} {
global \
configure.dir \
configure.checks.implicit_function_declaration.whitelist

# Map from function name to config.log that used it without declaration
array set undeclared_functions {}

fs-traverse -tails file ${configure.dir} {
if {[file tail $file] eq "config.log" && [file isfile [file join ${configure.dir} $file]]} {
# We could do the searching ourselves, but using a tool optimized for this purpose is likely much faster
# than using Tcl.
#
# Using /usr/bin/grep here, so we don't accidentally pick up a macports-installed grep which might
# currently not be runnable due to a missing library.
set args [list "/usr/bin/grep" "--" "-Wimplicit-function-declaration"]
lappend args [file join ${configure.dir} $file]

if {![catch {set result [exec -- {*}$args]}]} {
foreach line [split $result "\n"] {
if {[regexp -- "implicit declaration of function '(\[^']+)'" $line -> function]} {

This comment has been minimized.

Copy link
@ryandesign

ryandesign Dec 7, 2020

Contributor

It should also check for implicitly declaring library function '...' as in:

$ grep \ implicit -r work/lha-7c3cd95/config.log
work/lha-7c3cd95/config.log:conftest.c:97:29: error: implicitly declaring library function 'exit' with type 'void (int) __attribute__((noreturn))' [-Werror,-Wimplicit-function-declaration]
work/lha-7c3cd95/config.log:conftest.c:102:9: error: implicitly declaring library function 'exit' with type 'void (int) __attribute__((noreturn))' [-Werror,-Wimplicit-function-declaration]

This comment has been minimized.

Copy link
@ryandesign

ryandesign Dec 7, 2020

Contributor
set is_whitelisted no
foreach whitelisted ${configure.checks.implicit_function_declaration.whitelist} {
if {[string match -nocase $whitelisted $function]} {
set is_whitelisted yes
break
}
}
if {!$is_whitelisted} {
::struct::set include undeclared_functions($function) $file
} else {
ui_debug [format "Ignoring implicit declaration of function '%s', because it is whitelisted" $function]
}
}
}
}
}
}

if {[array size undeclared_functions] > 0} {
ui_warn "Configuration logfiles contain indications of -Wimplicit-function-declaration, check that features were not accidentially disabled:"
foreach {function files} [array get undeclared_functions] {
ui_msg [format " %s: found in %s" $function [join $files ", "]]
}
}
}

proc portconfigure::load_implicit_function_declaration_whitelist {sdk_version} {
set whitelist {}

set whitelist_file [getdefaultportresourcepath "port1.0/checks/implicit_function_declaration/macosx${sdk_version}.sdk.list"]
if {[file exists $whitelist_file]} {
set fd [open $whitelist_file r]
while {[gets $fd whitelist_entry] >= 0} {
lappend whitelist $whitelist_entry
}
close $fd
}

return $whitelist
}

proc portconfigure::configure_end {args} {
global \
configure.dir \
configure.checks.implicit_function_declaration

if {[file isdirectory ${configure.dir}] && ${configure.checks.implicit_function_declaration}} {
portconfigure::check_implicit_function_declarations
}
}

0 comments on commit 938d852

Please sign in to comment.