create-ccan-tree 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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
  8. sources required for build)
  9. -c, --exclude-configurator exclude configurator. config.h must be
  10. supplied by another method (eg, autotools)
  11. EOF
  12. }
  13. # parse options, setting the following flags
  14. copy_all=
  15. exclude_configurator=
  16. opts=$(getopt -o ac --long copy-all,exclude-configurator -n $progname -- "$@")
  17. if [ $? != 0 ]
  18. then
  19. usage
  20. exit 1
  21. fi
  22. eval set -- "$opts"
  23. while :
  24. do
  25. case "$1" in
  26. -a|--copy-all)
  27. copy_all=1
  28. shift
  29. ;;
  30. -c|--exclude-configurator)
  31. exclude_configurator=1
  32. shift
  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. srcdir=$(dirname $0)/../
  52. outdir="$1"
  53. shift
  54. modules="$@"
  55. if [ -e "$outdir" ]
  56. then
  57. echo "Output directory '$outdir' already exists" >&2
  58. exit 1
  59. fi
  60. tmpdir="$(mktemp -d)"
  61. # sanity check, we don't want to be overwriting stuff in arbitrary dirs
  62. [ $? -eq 0 -a -d "${tmpdir}" ] || exit 1
  63. # We'll need the ccan_depends tool, but also a clean source tree. Build
  64. # tools/ccan_depends, and store it in $tmpdir for later use
  65. echo "Building ccan_depends"
  66. ccan_depends="$tmpdir/ccan_depends"
  67. make -s -C "$srcdir" tools/ccan_depends
  68. [ $? -eq 0 ] || exit 1
  69. cp "$srcdir/tools/ccan_depends" "$ccan_depends"
  70. echo "Cleaning source tree"
  71. make -s -C "$srcdir" clean
  72. [ $? -eq 0 ] || exit 1
  73. # clean up on error
  74. trap 'rm -rf $tmpdir' EXIT
  75. copy_ccan_module() {
  76. module_dir="$1"
  77. module_srcdir="$srcdir/$module_dir"
  78. module_destdir="$tmpdir/$module_dir"
  79. if [ -n "$copy_all" ]
  80. then
  81. # bulk copy
  82. mkdir -p "$(dirname "$module_destdir")"
  83. cp -a "$module_srcdir" "$module_destdir"
  84. else
  85. mkdir -p "$module_destdir"
  86. # only copy sources & license
  87. license="$module_srcdir/LICENSE"
  88. cp -a "$module_srcdir"/*.[ch] "$module_destdir"
  89. [ -e "$license" ] && cp -a "$license" "$module_destdir"
  90. fi
  91. }
  92. # generate list of directories to copy
  93. for module in $modules
  94. do
  95. # ccan_depends takes a directory name
  96. module_dir="$srcdir/ccan/$module"
  97. # we need the module itself...
  98. echo "ccan/$module"
  99. # .. plus dependencies
  100. "$ccan_depends" "$module_dir"
  101. if [ $? -ne 0 ]
  102. then
  103. echo "Invalid ccan module '$module'?" >&2
  104. exit 1
  105. fi
  106. done |
  107. sort -u |
  108. while read dir
  109. do
  110. echo "Adding $dir"
  111. copy_ccan_module $dir
  112. done
  113. # we're done with the dependency-tracking, remove the tool from our
  114. # temporary directory
  115. rm "$ccan_depends"
  116. echo "Adding licenses"
  117. license_dir="$tmpdir/licenses"
  118. mkdir "$license_dir"
  119. find "$tmpdir" -type l -name LICENSE |
  120. while read license
  121. do
  122. license_link=$(readlink "$license")
  123. licence_file=$(basename "$license_link")
  124. license_src="$srcdir/licenses/$licence_file"
  125. license_dest="$license_dir/$license_file"
  126. cp "$license_src" "$license_dest"
  127. done
  128. # add ccan Makefile
  129. echo "Adding build infrastructure"
  130. cp "$srcdir/Makefile-ccan" "$tmpdir/"
  131. # add top-level Makefile
  132. top_makefile="$tmpdir/Makefile"
  133. cat > "$top_makefile" << EOF
  134. all: libccan.a
  135. include Makefile-ccan
  136. EOF
  137. # optionally add configurator, and relevant parts to top-level Makefile
  138. if [ -z "$exclude_configurator" ]
  139. then
  140. echo "Adding configurator"
  141. mkdir -p "$tmpdir/tools/configurator"
  142. cp -a "$srcdir/tools/configurator" "$tmpdir/tools/"
  143. cat >> "$top_makefile" <<EOF
  144. tools/configurator/configurator: tools/configurator/configurator.c
  145. config.h: tools/configurator/configurator Makefile Makefile-ccan
  146. tools/configurator/configurator \$(CC) \$(CCAN_CFLAGS) > \$@ \\
  147. || rm -f \$@
  148. objs = \$(patsubst %.c, %.o, \$(wildcard ccan/*/*.c))
  149. \$(objs): config.h
  150. EOF
  151. fi
  152. mv "$tmpdir" "$outdir"
  153. echo "Done. ccan source tree built in $outdir"
  154. trap - EXIT