take: add labels when CCAN_TAKE_DEBUG set, return in taken_any().
[ccan] / tools / create-ccan-tree
1 #!/bin/bash
2
3 progname=$(basename $0)
4
5 usage() {
6         cat >&2 <<EOF
7 Usage: $progname [options] <outdir> <depends>...
8
9 options:
10   -a, --copy-all         copy all files in module tree (not just sources
11                          required for build)
12   -b, --build-type=TYPE  generate build infrastructure of TYPE
13                          (one of 'make', 'make+config', 'automake', 'waf')
14 EOF
15 }
16
17 # parse options, setting the following flags
18 build_type=
19
20 opts=$(getopt -o ab: --long copy-all,build-type: -n $progname -- "$@")
21
22 if [ $? != 0 ]
23 then
24         usage
25         exit 1
26 fi
27
28 eval set -- "$opts"
29 MODFILES_ARGS="--no-tests --no-other"
30
31 while :
32 do
33         case "$1" in
34                 -a|--copy-all)
35                         MODFILES_ARGS=""
36                         shift
37                         ;;
38                 -b|--build-type)
39                         build_type="$2"
40                         shift 2
41                         ;;
42                 --)
43                         shift
44                         break
45                         ;;
46                 *)
47                         echo "Internal error!">&2
48                         exit 1
49                         ;;
50         esac
51 done
52
53 # we need at least two non-option arguments: outdir and a list of ccan
54 # modules
55 if [ $# -lt 2 ]
56 then
57         usage
58         exit 1
59 fi
60
61 # check --build-type argument sanity
62 case "$build_type" in
63         ''|'make'|'make+config'|'automake'|'waf')
64                 ;;
65         *)
66                 echo "Invalid build type '$build_type'" >&2
67                 exit 1
68 esac
69
70 srcdir=$(dirname $0)/../
71 outdir="$1"
72 shift
73 modules="$@"
74
75 if [ -e "$outdir" ]
76 then
77         echo "Output directory '$outdir' already exists" >&2
78         exit 1
79 fi
80
81 tmpdir="$(mktemp -d)"
82 # sanity check, we don't want to be overwriting stuff in arbitrary dirs
83 [ $? -eq 0 -a -d "${tmpdir}" ] || exit 1
84
85 # We'll need the ccan_depends tool, but also a clean source tree. Build
86 # tools/ccan_depends, and store it in $tmpdir for later use
87
88 echo "Building ccan_depends, modfiles"
89 ccan_depends="$tmpdir/ccan_depends"
90 modfiles="$tmpdir/modfiles"
91 make -s -C "$srcdir" tools/ccan_depends tools/modfiles
92 [ $? -eq 0 ] || exit 1
93 cp "$srcdir/tools/ccan_depends" "$ccan_depends"
94 cp "$srcdir/tools/modfiles" "$modfiles"
95
96 echo "Cleaning source tree"
97 make -s -C "$srcdir" clean
98 [ $? -eq 0 ] || exit 1
99
100 # clean up on error
101 trap 'rm -rf $tmpdir' EXIT
102
103 copy_ccan_module() {
104         module_dir="$1"
105         module_srcdir="$srcdir/$module_dir"
106         module_destdir="$tmpdir/$module_dir"
107
108         mkdir -p "$module_destdir"
109         # Copy license
110         license="$module_srcdir/LICENSE"
111         [ -e "$license" ] && cp -a "$license" "$module_destdir"
112         for f in $("$modfiles" $MODULES_ARGS --no-license --git-only "$module_dir"); do
113             mkdir -p $(dirname "$module_destdir"/"$f")
114             cp "$module_srcdir"/$f "$module_destdir"/$f
115         done
116 }
117
118 # generate list of directories to copy
119 for module in $modules
120 do
121         # ccan_depends takes a directory name
122         module_dir="$srcdir/ccan/$module"
123
124         # we need the module itself...
125         echo "ccan/$module"
126
127         # .. plus dependencies
128         "$ccan_depends" "$module_dir"
129
130         if [ $? -ne 0 ]
131         then
132                 echo "Invalid ccan module '$module'?" >&2
133                 exit 1
134         fi
135 done |
136 sort -u |
137 while read dir
138 do
139         echo "Adding $dir"
140         copy_ccan_module $dir
141 done
142
143 # we're done with the dependency-tracking, remove the tool from our
144 # temporary directory
145 rm "$ccan_depends" "$modfiles"
146
147 echo "Adding licenses"
148 license_dir="$tmpdir/licenses"
149 mkdir "$license_dir"
150
151 find "$tmpdir" -type l -name LICENSE |
152 while read license
153 do
154         license_link=$(readlink "$license")
155         licence_file=$(basename "$license_link")
156         license_src="$srcdir/licenses/$licence_file"
157         license_dest="$license_dir/$license_file"
158         cp "$license_src" "$license_dest"
159 done
160
161 echo "Adding build infrastructure"
162
163 # generate automake Makefile.am
164 automakefile="$tmpdir/Makefile.am"
165 if [ "$build_type" = "automake" ]
166 then
167         (
168                 echo "noinst_LIBRARIES = libccan.a"
169                 echo "libccan_a_SOURCES = \\"
170                 cd "$tmpdir"
171                 find ccan -maxdepth 2 -name '*.[ch]' |
172                         sed -e 's,^,\t,;$!s,$, \\,'
173         ) > "$automakefile"
174 fi
175
176 makefile="$tmpdir/Makefile"
177 if [ "$build_type" = "make" -o "$build_type" = "make+config" ]
178 then
179         # add ccan Makefile
180         cp "$srcdir/Makefile-ccan" "$tmpdir/"
181
182         # add top-level Makefile
183         cat > "$makefile" << EOF
184 all: libccan.a
185
186 include Makefile-ccan
187 EOF
188 fi
189
190 # optionally add configurator, and relevant parts to top-level Makefile
191 if [ "$build_type" = "make+config" ]
192 then
193         echo "Adding configurator"
194         mkdir -p "$tmpdir/tools/configurator"
195         cp -a "$srcdir/tools/configurator" "$tmpdir/tools/"
196
197         cat >> "$makefile" <<EOF
198 tools/configurator/configurator: tools/configurator/configurator.c
199
200 config.h: tools/configurator/configurator Makefile Makefile-ccan
201         tools/configurator/configurator \$(CC) \$(CCAN_CFLAGS) > \$@ \\
202                 || rm -f \$@
203
204 objs = \$(patsubst %.c, %.o, \$(wildcard ccan/*/*.c))
205 \$(objs): config.h
206
207 EOF
208 fi
209
210 if [ "$build_type" = "waf" ]
211 then
212         echo "Adding waf wscript"
213         cat > "$tmpdir/wscript" << EOF
214 def build(ctx):
215     ctx(features     = 'c cstlib',
216         source       = ctx.path.ant_glob('**/*.c'),
217         target       = 'ccan',
218         includes     = '.')
219 EOF
220 fi
221
222 mv "$tmpdir" "$outdir"
223 echo "Done. ccan source tree built in $outdir"
224
225 trap - EXIT