#!/bin/bash # RSSuper Linux Build Script # Native Linux build using meson/ninja with GTK4 set -e # Configuration SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" LINUX_PROJECT_DIR="$PROJECT_ROOT/native-route/linux" # Default values BUILD_TYPE="${1:-debug}" ACTION="${2:-build}" # Show help show_help() { echo "RSSuper Linux Build Script" echo "" echo "Usage: $0 [BUILD_TYPE] [ACTION]" echo "" echo "Arguments:" echo " BUILD_TYPE Build type (debug|release) [Default: debug]" echo " ACTION Action (build|install|test|clean|setup) [Default: build]" echo "" echo "Examples:" echo " $0 # Build debug" echo " $0 release # Build release" echo " $0 debug setup # Setup build environment" echo " $0 debug test # Run tests" echo " $0 clean # Clean build" } # Check prerequisites check_prerequisites() { local MISSING_DEPS=() # Check for required tools for cmd in meson ninja pkg-config; do if ! command -v $cmd &> /dev/null; then MISSING_DEPS+=("$cmd") fi done if [ ${#MISSING_DEPS[@]} -gt 0 ]; then echo "Error: Missing build tools: ${MISSING_DEPS[*]}" echo "" echo "On Ubuntu/Debian:" echo " sudo apt install meson ninja-build pkg-config" echo "" echo "On Fedora:" echo " sudo dnf install meson ninja-build pkgconf-pkg-config" echo "" echo "On Arch:" echo " sudo pacman -S meson ninja pkgconf" exit 1 fi echo "Build tools check passed" } # Install development dependencies install_dependencies() { echo "Installing Linux development dependencies..." local DISTRO=$(lsb_release -i -s 2>/dev/null || echo "unknown") case "$DISTRO" in Ubuntu|Debian) sudo apt-get update sudo apt-get install -y \ build-essential \ meson \ ninja-build \ pkg-config \ libgtk-4-dev \ libadwaita-1-dev \ libsqlite3-dev \ libxml2-dev \ libcurl4-openssl-dev \ libsoup-3-dev \ valac ;; Fedora) sudo dnf install -y \ gcc \ gcc-c++ \ meson \ ninja-build \ pkgconf-pkg-config \ gtk4-devel \ libadwaita-1-devel \ sqlite-devel \ libxml2-devel \ libcurl-devel \ libsoup3-devel \ vala ;; arch) sudo pacman -S --noconfirm \ base-devel \ meson \ ninja \ pkgconf \ gtk4 \ libadwaita \ sqlite \ libxml2 \ curl \ libsoup3 \ vala ;; *) echo "Warning: Unknown distribution ($DISTRO). Please install dependencies manually:" echo " - meson, ninja-build, pkg-config" echo " - GTK4 development files" echo " - SQLite3 development files" echo " - libxml2 development files" echo " - curl development files" ;; esac echo "Dependencies installation complete" } # Create Linux project structure create_linux_project() { echo "Creating Linux project structure..." mkdir -p "$LINUX_PROJECT_DIR/src/main" mkdir -p "$LINUX_PROJECT_DIR/src/models" mkdir -p "$LINUX_PROJECT_DIR/src/services" mkdir -p "$LINUX_PROJECT_DIR/src/ui" mkdir -p "$LINUX_PROJECT_DIR/data" mkdir -p "$LINUX_PROJECT_DIR/build" # meson.build (root) cat > "$LINUX_PROJECT_DIR/meson.build" << 'EOF' project('rssuper', 'c', 'vala', version: '1.0.0', meson_version: '>= 1.0.0', license: 'MIT', default_options: [ 'warning_level=1', 'werror=false' ] ) # Dependencies gtk4 = dependency('gtk4', version: '>= 4.0') adwaita = dependency('libadwaita-1', version: '>= 1.0') sqlite = dependency('sqlite3') xml2 = dependency('libxml-2.0') curl = dependency('libcurl') soup = dependency('libsoup-3.0') glib = dependency('glib-2.0', version: '>= 2.70') gobject = dependency('gobject-2.0') # Common compiler and linker arguments c_args = ['-D_GLIBCXX_USE_C99=1'] l_args = [] # Sources main_sources = files( 'src/main/rssuper.c', 'src/main/window.c', ) model_sources = files( 'src/models/feed.vala', 'src/models/item.vala', 'src/models/database.vala', ) service_sources = files( 'src/services/rss-parser.vala', 'src/services/feed-fetcher.vala', ) ui_sources = files( 'src/ui/feed-list.vala', 'src/ui/item-list.vala', 'src/ui/item-view.vala', ) # Executable rssuper_exe = executable( 'rssuper', main_sources, model_sources, service_sources, ui_sources, dependencies: [ gtk4, adwaita, sqlite, xml2, curl, soup, glib, gobject, ], c_args: c_args, link_args: l_args, install: true, ) # Data files install_data( 'data/rssuper.desktop', install_dir: get_option('datadir') + '/share/applications' ) install_data( 'data/rssuper.svg', install_dir: get_option('datadir') + '/share/icons/hicolor/scalable/apps' ) # Configuration configure_file( input: 'config.h.in', output: 'config.h', configuration: meson.current_source_dir() / 'config.cfg' ) EOF # Main C file cat > "$LINUX_PROJECT_DIR/src/main/rssuper.c" << 'EOF' #include #include #include "config.h" static GtkApplication *app; static void activate(GtkApplication *application) { AdwWindow *window; window = g_object_new(ADW_TYPE_WINDOW, "title", "RSSuper", "default-width", 1200, "default-height", 800, "show-mnemonic-label", false, NULL); gtk_application_add_window(GTK_APPLICATION(application), GTK_WINDOW(window)); gtk_widget_realize(GTK_WIDGET(window)); gtk_widget_show(GTK_WIDGET(window)); } int main(int argc, char **argv) { app = gtk_application_new("com.mikefreno.RSSuper", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; } EOF # Desktop file cat > "$LINUX_PROJECT_DIR/data/rssuper.desktop" << 'EOF' [Desktop Entry] Name=RSSuper Comment=A native RSS reader for Linux Exec=rssuper Terminal=false Type=Application Icon=rssuper Categories=Network;Reader; Keywords=rss;feed;reader; EOF # SVG Icon placeholder cat > "$LINUX_PROJECT_DIR/data/rssuper.svg" << 'EOF' R EOF # Config template cat > "$LINUX_PROJECT_DIR/config.h.in" << 'EOF' #ifndef CONFIG_H #define CONFIG_H #define RSSUPER_VERSION "@PROJECT_VERSION@" #define RSSUPER_APP_ID "com.mikefreno.RSSuper" #endif /* CONFIG_H */ EOF echo "Linux project structure created!" } # Setup build directory setup_build() { echo "Setting up build directory..." cd "$LINUX_PROJECT_DIR" local BUILD_DIR="build" local BUILD_TYPE_FLAG="" if [ "$BUILD_TYPE" = "release" ]; then BUILD_TYPE_FLAG="--buildtype=release" else BUILD_TYPE_FLAG="--buildtype=debug" fi # Clean existing build directory if [ -d "$BUILD_DIR" ]; then rm -rf "$BUILD_DIR" fi meson setup "$BUILD_DIR" $BUILD_TYPE_FLAG echo "Build directory setup complete" } # Build the project build_project() { echo "Building Linux $BUILD_TYPE..." cd "$LINUX_PROJECT_DIR" # Check if build directory exists if [ ! -d "build" ]; then echo "Build directory not found. Running setup first..." setup_build fi meson compile -C build echo "Build complete! Executable: $LINUX_PROJECT_DIR/build/rssuper" } # Install the application install_app() { echo "Installing RSSuper..." cd "$LINUX_PROJECT_DIR" if [ ! -d "build" ]; then echo "Error: Build directory not found. Run build first." exit 1 fi sudo meson install -C build echo "Installation complete!" } # Run tests run_tests() { echo "Running Linux tests..." cd "$LINUX_PROJECT_DIR" if [ ! -d "build" ]; then echo "Build directory not found. Running setup first..." setup_build fi meson test -C build } # Clean build clean_build() { echo "Cleaning Linux build..." cd "$LINUX_PROJECT_DIR" if [ -d "build" ]; then rm -rf build echo "Build directory removed" fi } # Run the application run_app() { echo "Running RSSuper..." cd "$LINUX_PROJECT_DIR" if [ ! -f "build/rssuper" ]; then echo "Executable not found. Building first..." build_project fi ./build/rssuper } # Main case "$ACTION" in setup) check_prerequisites if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then create_linux_project fi setup_build ;; install-deps) install_dependencies ;; clean) clean_build ;; test) check_prerequisites if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then create_linux_project fi setup_build run_tests ;; run) check_prerequisites if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then create_linux_project fi setup_build build_project run_app ;; install) check_prerequisites build_project install_app ;; build|*) check_prerequisites if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then create_linux_project fi setup_build build_project ;; esac