build.sh 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #!/usr/bin/env bash
  2. # NGS build helper
  3. # Usage: ./build.sh [command] [args...]
  4. set -euo pipefail
  5. ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  6. cd "$ROOT"
  7. BUILD_DIR="${BUILD_DIR:-build}"
  8. JOBS="${JOBS:-$(nproc 2>/dev/null || echo 4)}"
  9. BIN="$BUILD_DIR/ngs"
  10. # apt packages required to compile NGS (ylib / HPSocket are not packaged here)
  11. APT_DEPS=(
  12. build-essential
  13. cmake
  14. pkg-config
  15. libpcre3-dev
  16. zlib1g-dev
  17. libssl-dev
  18. libsqlite3-dev
  19. libleveldb-dev
  20. libmysqlcppconn-dev
  21. libmysqlclient-dev
  22. curl
  23. tar
  24. )
  25. die() { echo "error: $*" >&2; exit 1; }
  26. info() { echo "==> $*"; }
  27. have_cmd() { command -v "$1" >/dev/null 2>&1; }
  28. find_lib() {
  29. local name="$1"
  30. ldconfig -p 2>/dev/null | grep -q "lib${name}\\.so" && return 0
  31. [[ -f "/usr/local/lib/lib${name}.a" || -f "/usr/local/lib/lib${name}.so" ]] && return 0
  32. [[ -f "/usr/lib/x86_64-linux-gnu/lib${name}.a" || -f "/usr/lib/x86_64-linux-gnu/lib${name}.so" ]] && return 0
  33. [[ -f "/usr/lib/lib${name}.a" || -f "/usr/lib/lib${name}.so" ]] && return 0
  34. return 1
  35. }
  36. cmd_help() {
  37. cat <<EOF
  38. NGS build script
  39. Usage:
  40. ./build.sh Configure + build
  41. ./build.sh build Same as above
  42. ./build.sh rebuild Clean then build
  43. ./build.sh clean Remove build directory
  44. ./build.sh deps Install apt build dependencies
  45. ./build.sh check Verify toolchain and libraries
  46. ./build.sh run [args...] Build if needed, then run ngs
  47. ./build.sh install cmake --install into /usr/local (needs sudo)
  48. ./build.sh help Show this help
  49. Env:
  50. BUILD_DIR Build directory (default: build)
  51. JOBS Parallel jobs (default: nproc)
  52. Notes:
  53. - Preinstall ylib headers/libs under /usr/local (libylib.a + headers).
  54. - Preinstall HPSocket (libhpsocket + /usr/local/include/HPSocket).
  55. - MySQL Connector/C++ (libmysqlcppconn) is required because ylib links it.
  56. EOF
  57. }
  58. cmd_deps() {
  59. have_cmd apt-get || die "apt-get not found (Debian/Ubuntu required for deps)"
  60. info "Installing apt packages: ${APT_DEPS[*]}"
  61. sudo apt-get update
  62. sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${APT_DEPS[@]}"
  63. info "Done. Ensure ylib and HPSocket are installed under /usr/local."
  64. }
  65. cmd_check() {
  66. local ok=1
  67. echo "Checking build prerequisites..."
  68. for c in g++ cmake make; do
  69. if have_cmd "$c"; then
  70. echo " [OK] command: $c ($(command -v "$c"))"
  71. else
  72. echo " [MISS] command: $c"
  73. ok=0
  74. fi
  75. done
  76. if [[ -d /usr/local/include/net && -d /usr/local/include/util ]]; then
  77. echo " [OK] ylib headers: /usr/local/include/{net,util,...}"
  78. else
  79. echo " [MISS] ylib headers under /usr/local/include (net/, util/, ...)"
  80. ok=0
  81. fi
  82. if find_lib ylib; then
  83. echo " [OK] library: ylib"
  84. else
  85. echo " [MISS] library: ylib (expect /usr/local/lib/libylib.a)"
  86. ok=0
  87. fi
  88. if [[ -d /usr/local/include/HPSocket || -d /usr/include/HPSocket ]]; then
  89. echo " [OK] HPSocket headers"
  90. else
  91. echo " [MISS] HPSocket headers"
  92. ok=0
  93. fi
  94. if find_lib hpsocket; then
  95. echo " [OK] library: hpsocket"
  96. else
  97. echo " [MISS] library: hpsocket"
  98. ok=0
  99. fi
  100. for lib in mysqlcppconn mysqlclient sqlite3 leveldb ssl crypto z; do
  101. if find_lib "$lib"; then
  102. echo " [OK] library: $lib"
  103. else
  104. echo " [MISS] library: $lib (try: ./build.sh deps)"
  105. ok=0
  106. fi
  107. done
  108. if [[ -f /usr/include/cppconn/driver.h ]]; then
  109. echo " [OK] header: cppconn/driver.h"
  110. else
  111. echo " [MISS] header: cppconn/driver.h (libmysqlcppconn-dev)"
  112. ok=0
  113. fi
  114. if [[ "$ok" -eq 1 ]]; then
  115. info "All checks passed"
  116. return 0
  117. fi
  118. die "prerequisite check failed"
  119. }
  120. cmd_clean() {
  121. info "Removing $BUILD_DIR"
  122. rm -rf "$BUILD_DIR"
  123. }
  124. cmd_build() {
  125. cmd_check
  126. info "Configuring ($BUILD_DIR)"
  127. cmake -S . -B "$BUILD_DIR"
  128. info "Building with -j$JOBS"
  129. cmake --build "$BUILD_DIR" -j"$JOBS"
  130. info "Binary: $BIN"
  131. }
  132. cmd_rebuild() {
  133. cmd_clean
  134. cmd_build
  135. }
  136. cmd_run() {
  137. if [[ ! -x "$BIN" ]]; then
  138. cmd_build
  139. fi
  140. info "Running $BIN $*"
  141. exec "$BIN" "$@"
  142. }
  143. cmd_install() {
  144. [[ -x "$BIN" ]] || cmd_build
  145. info "Installing to system prefix (sudo)"
  146. sudo cmake --install "$BUILD_DIR"
  147. }
  148. main() {
  149. local cmd="${1:-build}"
  150. if [[ $# -gt 0 ]]; then
  151. shift
  152. fi
  153. case "$cmd" in
  154. build) cmd_build ;;
  155. rebuild) cmd_rebuild ;;
  156. clean) cmd_clean ;;
  157. deps) cmd_deps ;;
  158. check) cmd_check ;;
  159. run) cmd_run "$@" ;;
  160. install) cmd_install ;;
  161. help|-h|--help) cmd_help ;;
  162. *)
  163. # Unknown first arg: treat as ngs runtime args (compat with old br.sh)
  164. cmd_run "$cmd" "$@"
  165. ;;
  166. esac
  167. }
  168. main "$@"