我有两个源目录...
一个目录具有自动生成的代码。 另一个目录的代码采用自动生成的代码,并向代码添加自定义...
我想自动合并这两个源目录,以便每个文件的源路径的basename
替换自动生成的源目录中的`basename。示例:
SRC_AUTO := $(wildcard path1/path2/src_auto/*.cpp)
SRC_WORK := $(wildcard path3/path4/src_work/*.cpp)
# How to achieve this with GNU Make without going out to $shell or perl...
SRC_MERGED := overlay_basename($SRC_WORK, $SRC_AUTO)
示例:
SRC_AUTO := \
./path1/path2/src_auto/pathz/file1.cpp \
./path1/path2/src_auto/pathx/pathy/file2.cpp \
./path1/path2/src_auto/file3.cpp
SRC_WORK := \
./path3/path4/src_work/file1.cpp \
./path3/path4/src_work/file3.cpp
#This is what I need to generate automatically
SRC_MERGED := \
path1/path2/src_auto/pathx/pathy/file2.cpp \
path3/path4/src_work/file1.cpp \
path3/path4/src_work/file3.cpp
除了有更多文件外... SRC_WORK覆盖从文件路径的基本名称键入的SRC_AUTO。
这是我基本上想从GNU用perl伪代码生成的内容:
@SRC_AUTO = ( ...list of automatically generated files.. );
@SRC_WORK = ( ...list of customized files copied from auto directory );
%unique = ();
foreach $file (@SRC_WORK) {
$base = basename($file);
$unique{$base} = $file;
}
foreach $file (@SRC_AUTO) {
$base = basename($file);
if (!defined($unique{$base}) {
$unique{$base} = $file;
}
}
@merged_list = ();
foreach $key (keys %unique) {
$file = $unique{$key};
push(@merged_list, $file);
}
@sorted_merged_list = sort(@merged_list);
return @sorted_merged_list;
更新,经过一些改进,我现在有了以下perl脚本:(现在,如果您仅能使用单个内置函数从gnu make中自动执行此操作,而不会遇到调用脚本的脚本不稳定的脚本环境。 ):
#!/usr/bin/perl
# Automatically Generated Source Code
$dir_auto = "../src_auto";
# Overlayed Source Code
$dir_work = "../src_work";
#Merge File Output
$merge_list = "source.txt";
use File::Find;
sub OverlaySource($$)
{
my $dir_auto = shift;
my $dir_work = shift;
my %unique = ();
my @cpp_work;
find( sub {
my $file = $_;
if ($file =~ /\.cpp$/) {
$path = $dir_work . "/" . $file;
$unique{$file} = $path;
}
}, $dir_work);
my @cpp_auto;
find( sub {
my $file = $_;
return if (defined($unique{$file}));
if ($file =~ /\.cpp$/) {
$path = $dir_auto . "/" . $file;
$unique{$file} = $path;
}
}, $dir_auto);
my @tmp = ();
foreach $key (keys %unique) {
$file = $unique{$key};
push(@tmp, $file);
}
my @cpp_files = sort @tmp;
return @cpp_files;
}
$dir_auto = "../src_auto";
$dir_work = "../src_work";
my @cpp_files = OverlaySource($dir_auto, $dir_work);
print "Creating File: $merge_list\n";
open(F, ">${merge_list}");
foreach $file (@cpp_files) {
print F "$file\n";
}
close(F);
答案 0 :(得分:2)
这应该做您想要的:
SRC_MERGED := $(filter-out $(addprefix %/,$(notdir $(SRC_WORK))),$(SRC_AUTO)) $(SRC_WORK)
说明:
$(notdir $(SRC_WORK))
返回$(SRC_WORK)
中所有单词的基本名称:file1.cpp file3.cpp
。$(addprefix %/,$(notdir $(SRC_WORK)))
将%/
前缀添加到1的结果中;这是制作模式的列表(%
是通配符):%/file1.cpp %/file3.cpp
。$(filter-out $(addprefix %/,$(notdir $(SRC_WORK))),$(SRC_AUTO))
返回$(SRC_AUTO)
中所有与$(addprefix %/,$(notdir $(SRC_WORK)))
中的任何模式都不匹配的单词:./path1/path2/src_auto/pathx/pathy/file2.cpp
。 $(filter-out $(addprefix %/,$(notdir $(SRC_WORK))),$(SRC_AUTO)) $(SRC_WORK)
仅将$(SRC_WORK)
连接到3的结果:
./path1/path2/src_auto/pathx/pathy/file2.cpp ./path3/path4/src_work/file1.cpp ./path3/path4/src_work/file3.cpp