[clang][scan-build] Treat --use-cc and --use-c++ as shell commands (#131932)

So that things like --use-cc="ccache gcc" work.

Fixes #26594.

Also use the slightly simpler shellwords instead of quotewords.
This commit is contained in:
Florian Ragwitz 2025-03-24 03:09:03 -07:00 committed by GitHub
parent 27d9a3a39e
commit cc5f8293b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -51,63 +51,40 @@ sub silent_system {
# Compiler command setup. # Compiler command setup.
##===----------------------------------------------------------------------===## ##===----------------------------------------------------------------------===##
# Search in the PATH if the compiler exists {
sub SearchInPath { my ($DefaultCCompiler, $DefaultCXXCompiler);
my $file = shift;
foreach my $dir (split (':', $ENV{PATH})) {
if (-x "$dir/$file") {
return 1;
}
}
return 0;
}
my $Compiler; my $os = `uname -s`;
my $Clang; if ($os =~ m/Darwin/) {
my $DefaultCCompiler; $DefaultCCompiler = 'clang';
my $DefaultCXXCompiler; $DefaultCXXCompiler = 'clang++';
my $IsCXX; } elsif ($os =~ m/(FreeBSD|OpenBSD)/) {
my $AnalyzerTarget; $DefaultCCompiler = 'cc';
$DefaultCXXCompiler = 'c++';
# If on OSX, use xcrun to determine the SDK root. } else {
my $UseXCRUN = 0; $DefaultCCompiler = 'gcc';
$DefaultCXXCompiler = 'g++';
if (`uname -s` =~ m/Darwin/) { }
$DefaultCCompiler = 'clang';
$DefaultCXXCompiler = 'clang++'; sub DetermineCompiler {
# Older versions of OSX do not have xcrun to my ($is_cxx) = @_;
# query the SDK location. my $default = $is_cxx ? $DefaultCXXCompiler : $DefaultCCompiler;
if (-x "/usr/bin/xcrun") { my $opt = $ENV{$is_cxx ? 'CCC_CXX' : 'CCC_CC'};
$UseXCRUN = 1; return defined $opt ? shellwords($opt) : $default;
} }
} elsif (`uname -s` =~ m/(FreeBSD|OpenBSD)/) {
$DefaultCCompiler = 'cc';
$DefaultCXXCompiler = 'c++';
} else {
$DefaultCCompiler = 'gcc';
$DefaultCXXCompiler = 'g++';
} }
if ($FindBin::Script =~ /c\+\+-analyzer/) { sub DetermineClang {
$Compiler = $ENV{'CCC_CXX'}; my ($is_cxx) = @_;
if (!defined $Compiler || (! -x $Compiler && ! SearchInPath($Compiler))) { $Compiler = $DefaultCXXCompiler; } my $default = $is_cxx ? 'clang++' : 'clang';
my $opt = $ENV{$is_cxx ? 'CLANG_CXX' : 'CLANG'};
$Clang = $ENV{'CLANG_CXX'}; return defined $opt ? $opt : $default;
if (!defined $Clang || ! -x $Clang) { $Clang = 'clang++'; }
$IsCXX = 1
}
else {
$Compiler = $ENV{'CCC_CC'};
if (!defined $Compiler || (! -x $Compiler && ! SearchInPath($Compiler))) { $Compiler = $DefaultCCompiler; }
$Clang = $ENV{'CLANG'};
if (!defined $Clang || ! -x $Clang) { $Clang = 'clang'; }
$IsCXX = 0
} }
$AnalyzerTarget = $ENV{'CLANG_ANALYZER_TARGET'}; my $IsCXX = $FindBin::Script =~ /c\+\+-analyzer/;
my ($Compiler, @CompilerArgs) = DetermineCompiler($IsCXX);
my $Clang = DetermineClang($IsCXX);
my $AnalyzerTarget = $ENV{'CLANG_ANALYZER_TARGET'};
##===----------------------------------------------------------------------===## ##===----------------------------------------------------------------------===##
# Cleanup. # Cleanup.
@ -199,7 +176,7 @@ sub GetCCArgs {
die "could not find clang line\n" if (!defined $line); die "could not find clang line\n" if (!defined $line);
# Strip leading and trailing whitespace characters. # Strip leading and trailing whitespace characters.
$line =~ s/^\s+|\s+$//g; $line =~ s/^\s+|\s+$//g;
my @items = quotewords('\s+', 0, $line); my @items = shellwords($line);
my $cmd = shift @items; my $cmd = shift @items;
die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/ || basename($cmd) =~ /llvm/)); die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/ || basename($cmd) =~ /llvm/));
# If this is the llvm-driver the internal command will look like "llvm clang ...". # If this is the llvm-driver the internal command will look like "llvm clang ...".
@ -462,9 +439,9 @@ my $Output;
my %Uniqued; my %Uniqued;
# Forward arguments to gcc. # Forward arguments to gcc.
my $Status = system($Compiler,@ARGV); my $Status = system($Compiler,@CompilerArgs,@ARGV);
if (defined $ENV{'CCC_ANALYZER_LOG'}) { if (defined $ENV{'CCC_ANALYZER_LOG'}) {
print STDERR "$Compiler @ARGV\n"; print STDERR "$Compiler @CompilerArgs @ARGV\n";
} }
if ($Status) { exit($Status >> 8); } if ($Status) { exit($Status >> 8); }
@ -698,8 +675,9 @@ if ($ForceAnalyzeDebugCode) {
# If we are on OSX and have an installation where the # If we are on OSX and have an installation where the
# default SDK is inferred by xcrun use xcrun to infer # default SDK is inferred by xcrun use xcrun to infer
# the SDK. # the SDK. Older versions of OSX do not have xcrun to
if (not $HasSDK and $UseXCRUN) { # query the SDK location.
if (not $HasSDK and -x '/usr/bin/xcrun') {
my $sdk = `/usr/bin/xcrun --show-sdk-path -sdk macosx`; my $sdk = `/usr/bin/xcrun --show-sdk-path -sdk macosx`;
chomp $sdk; chomp $sdk;
push @CompileOpts, "-isysroot", $sdk; push @CompileOpts, "-isysroot", $sdk;