create-ccan-tree 4.6 KB

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