about summary refs log tree commit diff
path: root/nixpkgs/pkgs/development/interpreters/octave/wrap.sh
blob: a5969fca2a96e8740c82ba85ed3369d6a1b6f77e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Unlinks a directory (given as the first argument), and re-creates that
# directory as an actual directory. Then descends into the directory of
# the same name in the origin (arg_2/arg_3) and symlinks the contents of
# that directory into the passed end-location.
unlinkDirReSymlinkContents() {
    local dirToUnlink="$1"
    local origin="$2"
    local contentsLocation="$3"

    unlink $dirToUnlink/$contentsLocation
    mkdir -p $dirToUnlink/$contentsLocation
    for f in $origin/$contentsLocation/*; do
        ln -s -t "$dirToUnlink/$contentsLocation" "$f"
    done
}

# Using unlinkDirReSymlinkContents, un-symlinks directories down to
# $out/share/octave, and then creates the octave_packages directory.
createOctavePackagesPath() {
    local desiredOut=$1
    local origin=$2

    if [ -L "$out/share" ]; then
        unlinkDirReSymlinkContents "$desiredOut" "$origin" "share"
    fi

    if [ -L "$out/share/octave" ]; then
        unlinkDirReSymlinkContents "$desiredOut" "$origin" "share/octave"
    fi

    # Now that octave_packages has a path rather than symlinks, create the
    # octave_packages directory for installed packages.
    mkdir -p "$desiredOut/share/octave/octave_packages"
}

# First, descends down to $out/share/octave/site/m/startup/octaverc, and
# copies that start-up file. Once done, it performs a `chmod` to allow
# writing. Lastly, it `echo`s the location of the locally installed packages
# to the startup file, allowing octave to discover installed packages.
addPkgLocalList() {
    local desiredOut=$1
    local origin=$2
    local octaveSite="share/octave/site"
    local octaveSiteM="$octaveSite/m"
    local octaveSiteStartup="$octaveSiteM/startup"
    local siteOctavercStartup="$octaveSiteStartup/octaverc"

    unlinkDirReSymlinkContents "$desiredOut" "$origin" "$octaveSite"
    unlinkDirReSymlinkContents "$desiredOut" "$origin" "$octaveSiteM"
    unlinkDirReSymlinkContents "$desiredOut" "$origin" "$octaveSiteStartup"

    unlink "$out/$siteOctavercStartup"
    cp "$origin/$siteOctavercStartup" "$desiredOut/$siteOctavercStartup"
    chmod u+w "$desiredOut/$siteOctavercStartup"
    echo "pkg local_list $out/.octave_packages" >> "$desiredOut/$siteOctavercStartup"
}

# Wrapper function for wrapOctaveProgramsIn. Takes one argument, a
# space-delimited string of packages' paths that will be installed.
wrapOctavePrograms() {
    wrapOctaveProgramsIn "$out/bin" "$out" "$@"
}

# Wraps all octave programs in $out/bin with all the propagated inputs that
# a particular package requires. $1 is the directory to look for binaries in
# to wrap. $2 is the path to the octave ENVIRONMENT. $3 is the space-delimited
# string of packages.
wrapOctaveProgramsIn() {
    local dir="$1"
    local octavePath="$2"
    local pkgs="$3"
    local f

    buildOctavePath "$octavePath" "$pkgs"

    # Find all regular files in the output directory that are executable.
    if [ -d "$dir" ]; then
        find "$dir" -type f -perm -0100 -print0 | while read -d "" f; do
            echo "wrapping \`$f'..."
            local -a wrap_args=("$f"
                --prefix PATH ':' "$program_PATH"
                   )
            local -a wrapProgramArgs=("${wrap_args[@]}")
            wrapProgram "${wrapProgramArgs[@]}"
    done
    fi
}

# Build the PATH environment variable by walking through the closure of
# dependencies. Starts by constructing the `program_PATH` variable with the
# environment's path, then adding the original octave's location, and marking
# them in `octavePathsSeen`.
buildOctavePath() {
    local octavePath="$1"
    local packages="$2"

    local pathsToSearch="$octavePath $packages"

    # Create an empty table of Octave paths.
    declare -A octavePathsSeen=()
    program_PATH=
    octavePathsSeen["$out"]=1
    octavePathsSeen["@octave@"]=1
    addToSearchPath program_PATH "$out/bin"
    addToSearchPath program_PATH "@octave@/bin"
    echo "program_PATH to change to is: $program_PATH"
    for path in $pathsToSearch; do
    echo "Recurse to propagated-build-input: $path"
    _addToOctavePath $path
    done
}

# Adds the bin directories to the program_PATH variable.
# Recurses on any paths declared in `propagated-build-inputs`, while avoiding
# duplicating paths by flagging the directires it has seen in `octavePathsSeen`.
_addToOctavePath() {
    local dir="$1"
    # Stop if we've already visited this path.
    if [ -n "${octavePathsSeen[$dir]}" ]; then return; fi
    octavePathsSeen[$dir]=1
    # addToSearchPath is defined in stdenv/generic/setup.sh. It has the effect
    # of calling `export X=$dir/...:$X`.
    addToSearchPath program_PATH $dir/bin

    # Inspect the propagated inputs (if they exist) and recur on them.
    local prop="$dir/nix-support/propagated-build-inputs"
    if [ -e $prop ]; then
    for new_path in $(cat $prop); do
        _addToOctavePath $new_path
    done
    fi
}