diff --git a/CMakeLists.txt b/CMakeLists.txt index 61b53853..1792aa58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,6 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_compile_options(-Wall -Wextra -Werror -Wpedantic -Wuninitialized) - # Project information. project(nsb VERSION 0.1.0 @@ -72,15 +71,53 @@ message(STATUS "▸ Source: ${CMAKE_SOURCE_DIR}") message(STATUS "▸ Protobuf: ${Protobuf_INCLUDE_DIRS}") message(STATUS "▸ YAML: ${YAML_CPP_INCLUDE_DIR}") -# Set up library. +message(STATUS "Protoc Executable: ${Protobuf_PROTOC_EXECUTABLE}") + +# Generate C++ protobuf files directly via protoc. +add_custom_command( + OUTPUT ${CPP_PROTO_DIR}/nsb.pb.h ${CPP_PROTO_DIR}/nsb.pb.cc + COMMAND ${Protobuf_PROTOC_EXECUTABLE} + --cpp_out=${CPP_PROTO_DIR} + --proto_path=${PROTO_DIR} + ${PROTO_DIR}/nsb.proto + DEPENDS ${PROTO_DIR}/nsb.proto + COMMENT "Running cpp protocol buffer compiler on nsb.proto" +) + +# Generate Python protobuf files directly via protoc. +add_custom_command( + OUTPUT ${PYTHON_DIR}/proto/nsb_pb2.py + COMMAND ${Protobuf_PROTOC_EXECUTABLE} + --python_out=${PYTHON_DIR}/proto + --proto_path=${PROTO_DIR} + ${PROTO_DIR}/nsb.proto + DEPENDS ${PROTO_DIR}/nsb.proto + COMMENT "Running python protocol buffer compiler on nsb.proto" +) + +# Custom target that depends on all generated proto files. +add_custom_target(nsb_proto_gen ALL + DEPENDS + ${CPP_PROTO_DIR}/nsb.pb.h + ${CPP_PROTO_DIR}/nsb.pb.cc + ${PYTHON_DIR}/proto/nsb_pb2.py +) + +# Set up library (include generated nsb.pb.cc as an explicit source). add_library(nsb SHARED ${CPP_SRC_DIR}/nsb.cc ${CPP_SRC_DIR}/nsb_client.cc + ${CPP_PROTO_DIR}/nsb.pb.cc ) + +# Ensure proto files are generated before compiling nsb. +add_dependencies(nsb nsb_proto_gen) + # Link libraries. target_link_libraries(nsb PUBLIC ${link_targets} ) + # Include directories. target_include_directories(nsb PUBLIC ${CPP_INCLUDE_DIR} @@ -89,23 +126,6 @@ target_include_directories(nsb PUBLIC ${YAML_CPP_INCLUDE_DIR} ) -message(STATUS "Protoc Executable: ${Protobuf_PROTOC_EXECUTABLE}") -# Generate C++ protobuf files. -protobuf_generate( - TARGET nsb - LANGUAGE cpp - IMPORT_DIRS ${PROTO_DIR} - PROTOC_OUT_DIR ${CPP_DIR}/proto - PROTOS ${PROTO_DIR}/nsb.proto -) -# Generate Python protobuf file. -protobuf_generate( - TARGET nsb - LANGUAGE python - IMPORT_DIRS ${PROTO_DIR} - PROTOC_OUT_DIR ${PYTHON_DIR}/proto - PROTOS ${PROTO_DIR}/nsb.proto -) # Cleaning up. set_target_properties(nsb PROPERTIES ADDITIONAL_CLEAN_FILES "${CPP_DIR}/proto/*;${PYTHON_DIR}/proto/*;${PYTHON_DIR}/__pycache__/*" diff --git a/README.md b/README.md index 97e351c2..0c7338dc 100644 --- a/README.md +++ b/README.md @@ -324,7 +324,7 @@ your code. Once this is complete, we recommend taking these steps in order: 1. **Start the Redis server.** Specify or take note of the port number that the server is running on and make sure your configuration file points to the address and port. -```redis-server -p 5050``` +```redis-server --port 5050``` 2. **Start the NSB Daemon.** If you followed the build instructions in above, then you can start the NSB Daemon executable from either the _build_ directory diff --git a/arch_nsb_install.sh b/arch_nsb_install.sh new file mode 100755 index 00000000..53f9fc13 --- /dev/null +++ b/arch_nsb_install.sh @@ -0,0 +1,132 @@ +#!/bin/bash +set -e # Exit immediately on error + +# If running as root, make sudo a no-op (added for testing on docker) +if [ "$(id -u)" -eq 0 ]; then + sudo() { "$@"; } + export -f sudo +fi + +echo "=== NSB Installation Script (Arch Linux) ===" + +# ── 1. System Packages ────────────────────────────────────────────────────── +echo "[1/7] Installing system packages..." +sudo pacman -Syu --noconfirm \ + base-devel \ + cmake \ + pkgconf \ + sqlite \ + yaml-cpp \ + hiredis \ + python \ + python-pip \ + redis \ + git \ + wget + +pip install protobuf --break-system-packages + +# ── 2. Abseil ──────────────────────────────────────────────────────────────── +echo "[2/7] Building & installing Abseil..." +cd ~ +if [ ! -d "abseil-cpp" ]; then + git clone --depth 1 --branch 20240116.0 https://github.com/abseil/abseil-cpp.git +fi +cd abseil-cpp +mkdir -p build +cd build +cmake .. \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_BUILD_TYPE=Release \ + -DABSL_ENABLE_INSTALL=ON \ + -DBUILD_TESTING=OFF +cmake --build . -j2 +sudo cmake --install . +sudo ldconfig + +echo "Sanity check - Abseil:" +ls /usr/local/lib/libabsl_log* /usr/local/lib/libabsl_base* 2>/dev/null + +# ── 3. Protobuf ────────────────────────────────────────────────────────────── +echo "[3/7] Building & installing Protobuf v27.5..." +cd ~ +if [ ! -f "protobuf-27.5.tar.gz" ]; then + wget https://github.com/protocolbuffers/protobuf/releases/download/v27.5/protobuf-27.5.tar.gz +fi +if [ ! -d "protobuf-27.5" ]; then + tar -xvf protobuf-27.5.tar.gz +fi +cd protobuf-27.5 +mkdir -p build +cd build +cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -Dprotobuf_BUILD_SHARED_LIBS=ON \ + -Dprotobuf_BUILD_TESTS=OFF \ + -Dprotobuf_ABSL_PROVIDER=package \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_INSTALL_PREFIX=/usr/local +cmake --build . -j2 +sudo cmake --install . +sudo ldconfig + +echo "Sanity check - Protobuf:" +which protoc +protoc --version +ls /usr/local/lib/libprotobuf.so* + +# ── 4. Clone NSB ───────────────────────────────────────────────────────────── +echo "[4/7] Cloning NSB..." +cd ~ +if [ ! -d "nsb" ]; then + git clone https://github.com/nsb-ucsc/nsb.git nsb +fi +cd nsb + +# ── 5. Build NSB ───────────────────────────────────────────────────────────── +echo "[5/7] Building NSB..." +rm -rf build +mkdir build +cd build +cmake -DProtobuf_PROTOC_EXECUTABLE=/usr/local/bin/protoc .. +cmake --build . -j2 + +# ── 6. Install NSB ─────────────────────────────────────────────────────────── +echo "[6/7] Installing NSB..." +sudo cmake --install . +sudo ldconfig + +# ── 7. PYTHONPATH ──────────────────────────────────────────────────────────── +# Detect shell rc file +case "$SHELL" in +*/zsh) RC_FILE="$HOME/.zshrc" ;; +*/bash) RC_FILE="$HOME/.bashrc" ;; +*) RC_FILE="$HOME/.profile" ;; # universal fallback +esac + +echo "[7/7] Setting PYTHONPATH..." +touch "$RC_FILE" +PROTO_PATH="$HOME/nsb/python" +if ! grep -q "nsb/python" "$RC_FILE"; then + echo "export PYTHONPATH=$PROTO_PATH:\$PYTHONPATH" >>"$RC_FILE" +fi +export PYTHONPATH=$PROTO_PATH:$PYTHONPATH + +# ── 8. Redis ───────────────────────────────────────────────────────────────── +echo "Starting Redis on port 5050..." +redis-server --port 5050 --daemonize yes +redis-cli -p 5050 ping + +# ── Final Test ─────────────────────────────────────────────────────────────── +echo "Testing Python proto import..." +python3 - <<'EOF' +import proto.nsb_pb2 as nsb_pb2 +print("NSB Python proto loaded from:", nsb_pb2.__file__) +EOF + +echo "" +echo "=== Installation complete! ===" +echo "To run the daemon: cd ~/nsb/build && ./nsb_daemon ../config.yaml" +echo "Remember to run: source $RC_FILE" diff --git a/linux-setup-guide.md b/linux-setup-guide.md new file mode 100644 index 00000000..52b1b696 --- /dev/null +++ b/linux-setup-guide.md @@ -0,0 +1,32 @@ +# Linux Installation + +## Prerequisites +Make sure you have a supported Linux distribution (using apt or pacman). + +## Steps + +1. **Download the install script** for your distribution: + - Arch Linux: `arch_nsb_install.sh` + - Ubuntu: `ubuntu_nsb_install.sh` + +2. **Open a terminal** and navigate to the directory the script downloaded to: + ```bash + cd ~/Downloads/ + ``` + +3. **Make the script executable:** + ```bash + chmod +x _nsb_install.sh + ``` + +4. **Run the script:** + ```bash + ./_nsb_install.sh + ``` + +5. **Follow any on-screen instructions** that appear during installation. + +6. **Reload your shell** after installation completes: + ```bash + source ~/.bashrc + ``` diff --git a/ubuntu_nsb_install.sh b/ubuntu_nsb_install.sh new file mode 100644 index 00000000..ab48b5b1 --- /dev/null +++ b/ubuntu_nsb_install.sh @@ -0,0 +1,135 @@ +#!/bin/bash +set -e # Exit immediately on error + +# If running as root (e.g. Docker), make sudo a no-op +if [ "$(id -u)" -eq 0 ]; then + sudo() { "$@"; } + export -f sudo +fi + +echo "=== NSB Installation Script (Ubuntu) ===" + +# ── 1. System Packages ────────────────────────────────────────────────────── +echo "[1/7] Installing system packages..." +sudo apt update +sudo apt install -y \ + build-essential \ + cmake \ + pkg-config \ + libsqlite3-dev \ + libyaml-cpp-dev \ + libhiredis-dev \ + python3 \ + python3-pip \ + redis-server \ + git \ + wget + +pip install protobuf --break-system-packages + +# ── 2. Abseil ──────────────────────────────────────────────────────────────── +echo "[2/7] Building & installing Abseil..." +cd ~ +if [ ! -d "abseil-cpp" ]; then + git clone --depth 1 --branch 20240116.0 https://github.com/abseil/abseil-cpp.git +fi +cd abseil-cpp +mkdir -p build +cd build +cmake .. \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_BUILD_TYPE=Release \ + -DABSL_ENABLE_INSTALL=ON \ + -DBUILD_TESTING=OFF +cmake --build . -j2 +sudo cmake --install . +sudo ldconfig + +echo "Sanity check - Abseil:" +ls /usr/local/lib/libabsl_log* /usr/local/lib/libabsl_base* 2>/dev/null + +# ── 3. Protobuf ────────────────────────────────────────────────────────────── +echo "[3/7] Building & installing Protobuf v27.5..." +cd ~ +if [ ! -f "protobuf-27.5.tar.gz" ]; then + wget https://github.com/protocolbuffers/protobuf/releases/download/v27.5/protobuf-27.5.tar.gz +fi +if [ ! -d "protobuf-27.5" ]; then + tar -xvf protobuf-27.5.tar.gz +fi +cd protobuf-27.5 +mkdir -p build +cd build +cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -Dprotobuf_BUILD_SHARED_LIBS=ON \ + -Dprotobuf_BUILD_TESTS=OFF \ + -Dprotobuf_ABSL_PROVIDER=package \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_INSTALL_PREFIX=/usr/local +cmake --build . -j2 +sudo cmake --install . +sudo ldconfig + +echo "Sanity check - Protobuf:" +which protoc +protoc --version +ls /usr/local/lib/libprotobuf.so* + +# ── 4. Clone NSB ───────────────────────────────────────────────────────────── +echo "[4/7] Cloning NSB..." +cd ~ +if [ ! -d "nsb" ]; then + git clone https://github.com/nsb-ucsc/nsb.git nsb +fi +cd nsb + +# ── 5. Build NSB ───────────────────────────────────────────────────────────── +echo "[5/7] Building NSB..." +rm -rf build +mkdir build +cd build +cmake -DProtobuf_PROTOC_EXECUTABLE=/usr/local/bin/protoc .. +cmake --build . -j2 + +# ── 6. Install NSB ─────────────────────────────────────────────────────────── +echo "[6/7] Installing NSB..." +sudo cmake --install . +sudo ldconfig + +# ── 7. PYTHONPATH ──────────────────────────────────────────────────────────── +# Detect shell rc file +case "$SHELL" in +*/zsh) RC_FILE="$HOME/.zshrc" ;; +*/bash) RC_FILE="$HOME/.bashrc" ;; +*) RC_FILE="$HOME/.profile" ;; +esac + +echo "[7/7] Setting PYTHONPATH..." +touch "$RC_FILE" +PROTO_PATH="$HOME/nsb/python" +if ! grep -q "nsb/python" "$RC_FILE"; then + echo "export PYTHONPATH=$PROTO_PATH:\$PYTHONPATH" >>"$RC_FILE" +fi +export PYTHONPATH=$PROTO_PATH:$PYTHONPATH + +source $RC_FILE + +# ── 8. Redis ───────────────────────────────────────────────────────────────── +echo "Starting Redis on port 5050..." +redis-server --port 5050 --daemonize yes +redis-cli -p 5050 ping + +# ── Final Test ─────────────────────────────────────────────────────────────── +echo "Testing Python proto import..." +python3 - <<'EOF' +import proto.nsb_pb2 as nsb_pb2 +print("NSB Python proto loaded from:", nsb_pb2.__file__) +EOF + +echo "" +echo "=== Installation complete! ===" +echo "To run the daemon: cd ~/nsb/build && ./nsb_daemon ../config.yaml" +echo "Remember to run: source $RC_FILE"