Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Kconfig-files.pl: Return source code files associated to a Kconfig symbol. The file linux3.10-Kconfig-ethernet-drivers contains Kconfig symbols for drivers found at drivers/net/ethernet. Each line contains symbols related to one driver.
Each Linux device driver has at least one associated Kconfig symbol. Given a Kconfig symbol, or a set of
symbols, Kconfig-files.pl return the source code files associated to that symbol. It was targeted to
ethernet network drivers.
To use:
$ cd /src/linux/drivers/net/ethernet
$ Kconfig-files.pl ALX
atheros/alx/hw.h
atheros/alx/hw.c
atheros/alx/ethtool.c
atheros/alx/main.c
atheros/alx/alx.h
atheros/alx/reg.h
$ Kconfig-files.pl MLX4_EN,MLX4_EN_DCB,MLX4_CORE |sort -u
mellanox/mlx4/alloc.c
mellanox/mlx4/catas.c
mellanox/mlx4/cmd.c
mellanox/mlx4/cq.c
mellanox/mlx4/en_clock.c
mellanox/mlx4/en_cq.c
mellanox/mlx4/en_dcb_nl.c
mellanox/mlx4/en_ethtool.c
mellanox/mlx4/en_main.c
mellanox/mlx4/en_netdev.c
mellanox/mlx4/en_port.c
mellanox/mlx4/en_port.h
mellanox/mlx4/en_resources.c
mellanox/mlx4/en_rx.c
mellanox/mlx4/en_selftest.c
mellanox/mlx4/en_tx.c
mellanox/mlx4/eq.c
mellanox/mlx4/fw.c
mellanox/mlx4/fw.h
mellanox/mlx4/icm.c
mellanox/mlx4/icm.h
mellanox/mlx4/intf.c
mellanox/mlx4/main.c
mellanox/mlx4/mcg.c
mellanox/mlx4/mlx4_en.h
mellanox/mlx4/mlx4.h
mellanox/mlx4/mr.c
mellanox/mlx4/pd.c
mellanox/mlx4/port.c
mellanox/mlx4/profile.c
mellanox/mlx4/qp.c
mellanox/mlx4/reset.c
mellanox/mlx4/resource_tracker.c
mellanox/mlx4/sense.c
mellanox/mlx4/srq.c
$ cat linux3.10-Kconfig-ethernet-drivers|xargs -P 4 -n 1 Kconfig-files.pl |sort -u > /tmp/all_source_files
Known limitations:
- When passing multiple symbols, there could be repeated files. |sort -u fixes it
- When using generic symbols such as DEBUG_FS, the script can return non related files. This is not the case for ethernet drivers.
#!/bin/perl
# Receives a Kconfig value and returns files associated to that value
# Peter Senna Tschudin <peter.senna@lip6.fr>
#
use File::Basename;
use File::Find::Rule;
use File::Slurp;
use Cwd;
use Cwd qw(realpath);
use strict;
#use v5.6.1;
my $Kconfig = $ARGV[0];
if ($Kconfig =~ /\,/){
foreach my $Kc (split (",", $Kconfig)){
foreach (Kconfig_files($Kc)){
print $_ . "\n";
}
}
exit 0;
}
foreach (Kconfig_files($Kconfig)){
print $_ . "\n";
}
sub Kconfig_files {
my ($Kconfig) = @_;
#
# Find all Makefiles recursively on the current directory
#
my @path_to_Makefiles = file_finder (getcwd,'Makefile');
## Debug
#print "Makefile list: \n";
#foreach (@path_to_Makefiles){
# print $_. "\n";
#}
#print "--------------------------------------------------------------------------------\n";
#
# Select the correct Makefile and save it at $path_to_the_Makefile
#
my $path_to_the_Makefile;
my $Makefile_contents;
foreach (@path_to_Makefiles){
$Makefile_contents = read_file ($_);
if ($Makefile_contents =~ /\(CONFIG_$Kconfig\)/) {
my ($line) = $Makefile_contents =~ /(.*$Kconfig.*)/;
if (!($line =~ '\/$')){
$path_to_the_Makefile = $_;
last;
}
}
}
if (!(-e $path_to_the_Makefile)) {
warn("No Makefile could be found to the Kconfig symbol: " . $Kconfig . "\n");
return;
}
## Debug
#print "The Makefile: " . $path_to_the_Makefile . "\n";
#print "--------------------------------------------------------------------------------\n";
#
# $obj_files contains .o files separated by spaces.
# First save what is after "obj-$(CONFIG_$Kconfig) +="
#
my $obj_files;
#my @tmp_obj_files = ($Makefile_contents =~ m/\(CONFIG_$Kconfig\)\s*[\:\+]=(.*)/g);
my @tmp_obj_files = ($Makefile_contents =~ m/(?>\(CONFIG_$Kconfig\)\s*[:+]*=|\G\s*\\?)\s*\K(?>[^\s.]++|\.(?!o(?:\s|$)))++\.o/g);
foreach (@tmp_obj_files){
$obj_files .= $_ . " ";
}
# Then adds what is after "AAA-objs :=". AAA is the object without the .o
foreach (split(" ", $obj_files)){
# Remove the file extension
my ($obj_files_no_ext) = $_ =~ /(.+?)\.[^.]*$|$/;
# Regex by: http://stackoverflow.com/users/439667/sniffer
#my @filestmp = ($Makefile_contents =~ m/\s*$obj_files_no_ext-objs\s*[:+]=\s*((?:(?:[^\s\\]*?\.o)[\s\n\r\\]*)+)/g);
# Regex by: http://stackoverflow.com/users/2255089/casimir-et-hippolyte
my @filestmp = ($Makefile_contents =~ m/(?>$obj_files_no_ext-objs\s*[:+]*=|\G\s*\\?)\s*\K(?>[^\s.]++|\.(?!o(?:\s|$)))++\.o/g);
foreach (@filestmp) {
$obj_files .= " " . $_;
}
}
# Then adds what is after "AAA-y :=". AAA is the object without the .o
foreach (split(" ", $obj_files)){
# Remove the file extension
my ($obj_files_no_ext) = $_ =~ /(.+?)\.[^.]*$|$/;
my @filestmp = ($Makefile_contents =~ m/(?>\s*$obj_files_no_ext-y\s*[:+]*=|\G\s*\\?)\s*\K(?>[^\s.]++|\.(?!o(?:\s|$)))++\.o/g);
foreach (@filestmp) {
$obj_files .= " " . $_;
}
}
#
# Find .h and .c files from $obj_files
#
my $path_to_the_src_dir = dirname($path_to_the_Makefile);
my @paths_to_src_files;
foreach (split(" ", $obj_files)){
# Remove the file extension
my ($obj_files_no_ext) = $_ =~ /(.+?)\.[^.]*$|$/;
my @hfiles = file_finder($path_to_the_src_dir, $obj_files_no_ext . ".h");
my @cfiles = file_finder($path_to_the_src_dir, $obj_files_no_ext . ".c");
@paths_to_src_files = (@hfiles, @cfiles, @paths_to_src_files);
}
## Debug
#print "Sources from object files: \n";
#foreach (@paths_to_src_files){
# print $_ . "\n";
#}
#print "--------------------------------------------------------------------------------\n";
#
# Add files included from source_files
#
foreach my $path (@paths_to_src_files){
my $src_file = read_file ($path);
my (@includes) = $src_file =~ m/#include "(([^"]+))"/g;
foreach my $included_file (@includes){
# realpath expand? "../" to the correct path
my $path_to_include = realpath($path_to_the_src_dir . "/" . $included_file);
if (!(-e $path_to_include)){
# If the file is not on the current directory, probably
# is one level up, dirname() returns one level up.
# basename() is used as some includes contains directory
# names in it. Examples:
# #include "../cnic_if.h"
# #include "bnx2x/bnx2x_mfw_req.h"
my @file = file_finder(dirname($path_to_the_src_dir), basename($included_file));
$path_to_include = $file[0];
}
# Only add if it is not there yet
if (!(grep(/$path_to_include/, @paths_to_src_files))) {
push(@paths_to_src_files, $path_to_include);
}
}
}
#
# Find .c files from .h files included.
#
foreach my $path (@paths_to_src_files){
my $filename = basename($path);
# We are only interested in .h files.
if ($filename =~ /.c$/){
next;
}
my ($filename_no_ext) = $filename =~ /(.+?)\.[^.]*$|$/;
my $file_dot_c = $filename_no_ext . ".c";
my @file = file_finder($path_to_the_src_dir, $file_dot_c);
if (!(grep(/$file[0]/, @paths_to_src_files))) {
push(@paths_to_src_files, $file[0]);
}
}
return @paths_to_src_files;
}
#
# Look for files $pattern in $dir
#
sub file_finder {
my ($dir, $pattern) = @_;
my $result = '';
my $finder = File::Find::Rule->new;
$finder->file;
$finder->name( $pattern );
return $finder->in( $dir );
}
3C515
8139CP
8139TOO,8139TOO_PIO,8139TOO_TUNE_TWISTER,8139TOO_8129,8139_OLD_RX_RESET
A2065
ACENIC,ACENIC_OMIT_TIGON_I
ADAPTEC_STARFIRE
ALX
AMD8111_ETH
APNE
ARIADNE
ARM_AM79C961A
ARM_AT91_ETHER
ARM_ETHER1
ARM_ETHER3
ARM_ETHERH
ARM_KS8695_ETHER
ATARILANCE
ATL1
ATL1C
ATL1E
ATL2
ATP
AX88796,AX88796_93CX6
B44,B44_PCI_AUTOSELECT,B44_PCICORE_AUTOSELECT
BCM63XX_ENET
BE2NET
BFIN_MAC,BFIN_MAC_USE_L1,BFIN_TX_DESC_NUM,BFIN_RX_DESC_NUM,BFIN_MAC_USE_HWSTAMP
BGMAC
BMAC
BNA
BNX2
BNX2X
BNX2X,BNX2X_SRIOV
BVME6000_NET
CASSINI
CHELSIO_T1,CHELSIO_T1_1G
CHELSIO_T3
CHELSIO_T4
CHELSIO_T4VF
CNIC
CPMAC
CS89x0,CS89x0_PLATFORM
DE2104X
DE4X5
DECLANCE
DL2K
DM9000
DM9102
DNET
E100
E1000
E1000E
EHEA
EL3
ENC28J60
ENIC
EP93XX_ETH
EPIC100
ETHOC
FEALNX
FEC
FEC_MPC52xx,FEC_MPC52xx_MDIO
FORCEDETH
FS_ENET,FS_ENET_MPC5121_FEC,FS_ENET_HAS_SCC,FS_ENET_HAS_FCC,FS_ENET_HAS_FEC,FS_ENET_MDIO_FEC,FS_ENET_MDIO_FCC
FSL_PQ_MDIO
FSL_XGMAC_MDIO
FTGMAC100
FTMAC100
GELIC_NET
GELIC_WIRELESS
GIANFAR,PTP_1588_CLOCK_GIANFAR
GRETH
HAMACHI
HAPPYMEAL
HP100
HPLANCE
HYDRA
IBM_EMAC,IBM_EMAC_DEBUG,IBM_EMAC_RGMII,IBM_EMAC_TAH,IBM_EMAC_ZMII
IBMVETH
IGB
IGBVF
IP1000
IXGB
IXGBE,IXGBE_DCB,IXGBE_HWMON,DEBUG_FS
IXGBEVF
IXP4XX_ETH
JME
KORINA
KS8842
KS8851
KS8851_MLL
KSZ884X_PCI
LANCE
LANTIQ_ETOP
LASI_82596
LPC_ENET
MAC8390
MAC89x0
MACB
MACE,MACE_AAUI_PORT
MACMACE
MACSONIC
MCF8390
MIPS_AU1X00_ENET
MIPS_JAZZ_SONIC
MLX4_EN,MLX4_EN_DCB,MLX4_CORE
MV643XX_ETH
MVMDIO
MVME147_NET
MVME16x_NET
MVNETA
MYRI10GE,MYRI10GE_DCA
NATSEMI
NE2000
NE2K_PCI
NE_H8300
NET_CALXEDA_XGMAC
NET_NETX
NETXEN_NIC
NI65
NIU
NS83820
OCTEON_MGMT_ETHERNET
PASEMI_MAC
PCH_GBE
PCMCIA_3C574
PCMCIA_3C589
PCMCIA_AXNET
PCMCIA_FMVJ18X
PCMCIA_NMCLAN
PCMCIA_PCNET
PCMCIA_SMC91C92
PCMCIA_XIRC2PS
PCMCIA_XIRCOM
PCNET32
PXA168_ETH
QLA3XXX
QLCNIC,QLCNIC_SRIOV
QLGE
R6040
R8169
S2IO
S6GMAC
SB1250_MAC
SC92031
SFC,SFC_MTD,SFC_MCDI_MON,SFC_SRIOV
SGI_IOC3_ETH
SGI_O2MACE_ETH
SGISEEQ
SH_ETH
SIS190
SIS900
SKGE
SKY2
SMC911X
SMC9194
SMC91X
SMSC911X
SMSC9420
SNI_82596
SPIDER_NET
STMMAC_ETH,STMMAC_PLATFORM,STMMAC_PCI,STMMAC_DEBUG_FS,STMMAC_DA
STNIC
SUN3_82586
SUN3LANCE
SUNBMAC
SUNDANCE,SUNDANCE_MMIO
SUNGEM
SUNLANCE
SUNQE
SUNVNET
TC35815
TEHUTI
TI_CPSW,TI_CPTS
TI_DAVINCI_CPDMA
TI_DAVINCI_EMAC
TI_DAVINCI_MDIO
TIGON3
TILE_NET
TLAN
TSI108_ETH
TULIP,TULIP_MWI,TULIP_MMIO,TULIP_NAPI,TULIP_NAPI_HW_MITIGATION,TULIP_DM910X
TYPHOON
UCC_GETH,UGETH_TX_ON_DEMAND
ULI526X
ULTRA
VIA_RHINE,VIA_RHINE_MMIO
VIA_VELOCITY
VORTEX
VXGE
W90P910_ETH
WD80x3
WINBOND_840
WIZNET_W5100
WIZNET_W5300
XILINX_AXI_EMAC
XILINX_EMACLITE
XILINX_LL_TEMAC
XTENSA_XT2000_SONIC
YELLOWFIN
ZORRO8390
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment