#!/usr/bin/env perl use v5.12; use warnings; use subs qw/for_includes/; open my $fh, ">", "deps.mk"; print $fh "# This file is generated by makedeps.\n"; while (my $f = glob("c/*.cpp")) { $f =~ s,^c/,,; $f =~ s/\.cpp$//; if ($f eq "main") { print $fh "b/\$(EXE):"; } else { print $fh "b/$f.obj:"; } # Print dependencies in source file. my @deps; for_includes "c/$f.cpp", sub { my $f = shift; return if grep { $_ eq $f } @deps; push @deps, $f; print $fh " c/$f"; # Print dependencies in dependency. for_includes "c/$f", sub { my $f = shift; return if grep { $_ eq $f } @deps; push @deps, $f; print $fh " c/$f"; } }; print $fh "\n"; } sub for_includes ($&) { my $f = shift; my $c = shift; state %cache; # Retrieve dependencies from cache. if (exists $cache{$f}) { $c->($_) for @{$cache{$f}}; } # Find dependencies in file. else { open my $gh, "<", $f or die "($f) $!"; while ($_ = <$gh>) { next if /^$/; last if not /#/; next if not /^#include\s*"([^"]+)"/; push @{$cache{$f}}, $1; $c->($1); } } }