* 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:
parent
08de98f8b6
commit
0920fe3038
|
@ -1,3 +1,4 @@
|
|||
[ (import ./trivial)
|
||||
(import ./simple-header)
|
||||
(import ./not-so-simple-header)
|
||||
]
|
1
examples/not-so-simple-header/bar/hello.h
Normal file
1
examples/not-so-simple-header/bar/hello.h
Normal file
|
@ -0,0 +1 @@
|
|||
#define WHAT "World"
|
14
examples/not-so-simple-header/default.nix
Normal file
14
examples/not-so-simple-header/default.nix
Normal 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];
|
||||
}
|
3
examples/not-so-simple-header/foo/fnord/indirect.h
Normal file
3
examples/not-so-simple-header/foo/fnord/indirect.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#define HELLO "Hello"
|
||||
|
||||
#include "../../bar/hello.h"
|
9
examples/not-so-simple-header/foo/hello.c
Normal file
9
examples/not-so-simple-header/foo/hello.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "fnord/indirect.h"
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
printf(HELLO " " WHAT "\n");
|
||||
return 0;
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue