]> git.ozlabs.org Git - ccan/blob - tools/create-ccan-tree
ccanlint: don't remove HAVE_STRUCT_TIMESPEC when testing without features.
[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 copy_all=
19 build_type=
20
21 opts=$(getopt -o ab: --long copy-all,build-type: -n $progname -- "$@")
22
23 if [ $? != 0 ]
24 then
25         usage
26         exit 1
27 fi
28
29 eval set -- "$opts"
30
31 while :
32 do
33         case "$1" in
34                 -a|--copy-all)
35                         copy_all=1
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"
89 ccan_depends="$tmpdir/ccan_depends"
90 make -s -C "$srcdir" tools/ccan_depends
91 [ $? -eq 0 ] || exit 1
92 cp "$srcdir/tools/ccan_depends" "$ccan_depends"
93
94 echo "Cleaning source tree"
95 make -s -C "$srcdir" clean
96 [ $? -eq 0 ] || exit 1
97
98 # clean up on error
99 trap 'rm -rf $tmpdir' EXIT
100
101 copy_ccan_module() {
102         module_dir="$1"
103         module_srcdir="$srcdir/$module_dir"
104         module_destdir="$tmpdir/$module_dir"
105
106         if [ -n "$copy_all" ]
107         then
108                 # bulk copy
109                 mkdir -p "$(dirname "$module_destdir")"
110                 cp -a "$module_srcdir" "$module_destdir"
111         else
112                 mkdir -p "$module_destdir"
113                 # only copy sources & license
114                 license="$module_srcdir/LICENSE"
115                 cp -a "$module_srcdir"/*.[ch] "$module_destdir"
116                 [ -e "$license" ] && cp -a "$license" "$module_destdir"
117         fi
118 }
119
120 # generate list of directories to copy
121 for module in $modules
122 do
123         # ccan_depends takes a directory name
124         module_dir="$srcdir/ccan/$module"
125
126         # we need the module itself...
127         echo "ccan/$module"
128
129         # .. plus dependencies
130         "$ccan_depends" "$module_dir"
131
132         if [ $? -ne 0 ]
133         then
134                 echo "Invalid ccan module '$module'?" >&2
135                 exit 1
136         fi
137 done |
138 sort -u |
139 while read dir
140 do
141         echo "Adding $dir"
142         copy_ccan_module $dir
143 done
144
145 # we're done with the dependency-tracking, remove the tool from our
146 # temporary directory
147 rm "$ccan_depends"
148
149 echo "Adding licenses"
150 license_dir="$tmpdir/licenses"
151 mkdir "$license_dir"
152
153 find "$tmpdir" -type l -name LICENSE |
154 while read license
155 do
156         license_link=$(readlink "$license")
157         licence_file=$(basename "$license_link")
158         license_src="$srcdir/licenses/$licence_file"
159         license_dest="$license_dir/$license_file"
160         cp "$license_src" "$license_dest"
161 done
162
163 echo "Adding build infrastructure"
164
165 # generate automake Makefile.am
166 automakefile="$tmpdir/Makefile.am"
167 if [ "$build_type" = "automake" ]
168 then
169         (
170                 echo "noinst_LIBRARIES = libccan.a"
171                 echo "libccan_a_SOURCES = \\"
172                 cd "$tmpdir"
173                 find ccan -maxdepth 2 -name '*.[ch]' |
174                         sed -e 's,^,\t,;$!s,$, \\,'
175         ) > "$automakefile"
176 fi
177
178 makefile="$tmpdir/Makefile"
179 if [ "$build_type" = "make" -o "$build_type" = "make+config" ]
180 then
181         # add ccan Makefile
182         cp "$srcdir/Makefile-ccan" "$tmpdir/"
183
184         # add top-level Makefile
185         cat > "$makefile" << EOF
186 all: libccan.a
187
188 include Makefile-ccan
189 EOF
190 fi
191
192 # optionally add configurator, and relevant parts to top-level Makefile
193 if [ "$build_type" = "make+config" ]
194 then
195         echo "Adding configurator"
196         mkdir -p "$tmpdir/tools/configurator"
197         cp -a "$srcdir/tools/configurator" "$tmpdir/tools/"
198
199         cat >> "$makefile" <<EOF
200 tools/configurator/configurator: tools/configurator/configurator.c
201
202 config.h: tools/configurator/configurator Makefile Makefile-ccan
203         tools/configurator/configurator \$(CC) \$(CCAN_CFLAGS) > \$@ \\
204                 || rm -f \$@
205
206 objs = \$(patsubst %.c, %.o, \$(wildcard ccan/*/*.c))
207 \$(objs): config.h
208
209 EOF
210 fi
211
212 if [ "$build_type" = "waf" ]
213 then
214         echo "Adding waf wscript"
215         cat > "$tmpdir/wscript" << EOF
216 def build(ctx):
217     ctx(features     = 'c cstlib',
218         source       = ctx.path.ant_glob('**/*.c'),
219         target       = 'ccan',
220         includes     = '.')
221 EOF
222 fi
223
224 mv "$tmpdir" "$outdir"
225 echo "Done. ccan source tree built in $outdir"
226
227 trap - EXIT