* Deal with directory components in header file references (e.g.,

`#include "foo/../bar/bla.h"') by building an appropriate tree of
  symlinks.
This commit is contained in:
Eelco Dolstra 2004-07-06 13:45:14 +00:00
parent 08de98f8b6
commit 0920fe3038
6 changed files with 87 additions and 7 deletions

View file

@ -1,3 +1,4 @@
[ (import ./trivial)
(import ./simple-header)
(import ./not-so-simple-header)
]

View file

@ -0,0 +1 @@
#define WHAT "World"

View file

@ -0,0 +1,14 @@
let {
inherit (import ../../lib) compileC link;
hello = link {objects = compileC {
main = ./foo/hello.c;
localIncludes = [
[./foo/fnord/indirect.h "fnord/indirect.h"]
[./bar/hello.h "fnord/../../bar/hello.h"]
];
};};
body = [hello];
}

View file

@ -0,0 +1,3 @@
#define HELLO "Hello"
#include "../../bar/hello.h"

View file

@ -0,0 +1,9 @@
#include <stdio.h>
#include "fnord/indirect.h"
int main(int argc, char * * argv)
{
printf(HELLO " " WHAT "\n");
return 0;
}

View file

@ -1,18 +1,70 @@
. $stdenv/setup
mainName=$(basename $main | cut -c34-)
ln -s $main $mainName
echo "compiling $mainName..."
# Turn $localIncludes into an array.
localIncludes=($localIncludes)
# Determine how many `..' levels appear in the header file references.
# E.g., if there is some reference `../../foo.h', then we have to
# insert two extra levels in the directory structure, so that `a.c' is
# stored at `dotdot/dotdot/a.c', and a reference from it to
# `../../foo.h' resolves to `dotdot/dotdot/../../foo.h' == `foo.h'.
n=0
while test $n -lt ${#localIncludes[*]}; do
source=${localIncludes[n]}
target=${localIncludes[$((n+1))]}
ln -s $source $target
n=$((n + 2))
maxDepth=0
for ((n = 0; n < ${#localIncludes[*]}; n += 2)); do
target=${localIncludes[$((n + 1))]}
# Split the target name into path components using some IFS magic.
savedIFS="$IFS"
IFS=/
components=($target)
depth=0
for ((m = 0; m < ${#components[*]}; m++)); do
c=${components[m]}
if test "$c" = ".."; then
depth=$((depth + 1))
fi
done
IFS="$savedIFS"
if test $depth -gt $maxDepth; then
maxDepth=$depth;
fi
done
# Create the extra levels in the directory hierarchy.
prefix=
for ((n = 0; n < maxDepth; n++)); do
prefix="dotdot/$prefix"
done
# Create symlinks to the header files.
for ((n = 0; n < ${#localIncludes[*]}; n += 2)); do
source=${localIncludes[n]}
target=${localIncludes[$((n + 1))]}
# Create missing directories. We use IFS magic to split the path
# into path components.
savedIFS="$IFS"
IFS=/
components=($prefix$target)
fullPath=(.)
for ((m = 0; m < ${#components[*]} - 1; m++)); do
fullPath=("${fullPath[@]}" ${components[m]})
if ! test -d "${fullPath[*]}"; then
mkdir "${fullPath[*]}"
fi
done
IFS="$savedIFS"
ln -s $source $prefix$target
done
# Create a symlink to the main file.
ln -s $main $prefix$mainName
mkdir $out
gcc -Wall -c $mainName -o $out/$mainName.o
gcc -Wall -c $prefix$mainName -o $out/$mainName.o