This document outlines the steps needed to compile SourceMinder on a fresh macOS installation.
Homebrew is required for installing dependencies on macOS.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"After installation, follow the instructions to add Homebrew to your PATH (typically adding to ~/.zshrc):
# For Apple Silicon Macs
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc
source ~/.zshrc
# For Intel Macs
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zshrc
source ~/.zshrc# Install tree-sitter library (for parsing)
brew install tree-sitter
# Install sqlite (for database support, including development headers)
brew install sqlite
# Optional: Install tree-sitter CLI tool (if you need to regenerate parsers)
brew install tree-sitter-cliThe project requires tree-sitter grammar repositories for each supported language. These should be cloned in the project root directory:
cd /path/to/SourceMinder
# Clone required grammar repositories
git clone https://github.com/tree-sitter/tree-sitter-c.git
git clone https://github.com/tree-sitter/tree-sitter-go.git
git clone https://github.com/tree-sitter-perl/tree-sitter-perl.git
git clone https://github.com/tree-sitter/tree-sitter-php.git
git clone https://github.com/tree-sitter/tree-sitter-python.git
git clone https://github.com/tree-sitter/tree-sitter-typescript.gitAfter cloning, your directory should look like:
SourceMinder/
├── tree-sitter-c/
│ └── src/parser.c
├── tree-sitter-go/
│ └── src/parser.c
├── tree-sitter-perl/
│ └── src/parser.c
│ └── src/scanner.c
├── tree-sitter-php/
│ └── php/src/parser.c
│ └── php/src/scanner.c
└── tree-sitter-typescript/
└── typescript/src/parser.c
└── typescript/src/scanner.c
First, run the configure script to select which languages to build:
./configure --enable-all # All languages
./configure --enable-c --enable-typescript --enable-php # Specific languages
./configure --enable-all --disable-php # All but PHP
CC=clang ./configure --enable-c # Custom compilerNote: All languages are disabled by default. You must enable at least one language before building.
What configure does:
- Generates
config.hwith enabled language flags - Extracts grammar versions from tree-sitter
package.jsonfiles - Creates
<language>/grammar_version.hheaders automatically (cross-platform) - Generates the
Makefilewith appropriate targets
makeThis will:
- Compile the selected language indexers
- Build the query-index tool (qi)
- Create convenience symlinks in the project root
Binaries are created in the build/ directory:
build/index-ts- TypeScript indexer (if enabled)build/index-c- C indexer (if enabled)build/index-perl- Perl indexer (if enabled)build/index-php- PHP indexer (if enabled)build/index-go- Go indexer (if enabled)build/index-python- Python indexer (if enabled)build/qi- Query tool (always built)
Symlinks in the project root (for enabled languages):
index-ts→build/index-tsindex-c→build/index-cindex-perl→build/index-perlindex-php→build/index-phpindex-go→build/index-goindex-python→build/index-pythonqi→build/qi
To clean and rebuild from scratch:
make clean
./configure --enable-all # Or your preferred language selection
makeThe indexers can be installed globally on the system, making them available from any directory.
sudo make installThis will:
-
Install binaries to
/usr/local/bin/:qi(always)index-c(if enabled)index-ts(if enabled)index-php(if enabled)index-go(if enabled)index-python(if enabled)
-
Install config files to
/usr/local/share/sourceminder/:shared/config/- Shared filter configuration (stopwords, exclusion patterns)c/config/- C language configuration (if enabled)typescript/config/- TypeScript language configuration (if enabled)php/config/- PHP language configuration (if enabled)go/config/- Go language configuration (if enabled)python/config/- Python language configuration (if enabled)
The indexers use a smart path resolution system with the following search order:
- Current directory (development mode): Looks for
./c/config,./shared/config, etc. - System installation (macOS):
/usr/local/share/sourceminder/ - System installation (Linux):
/usr/share/sourceminder/
This means:
- Development: Run from the project directory without installation
- Global installation: Run from anywhere after
sudo make install
After installation, you can use the indexers from any directory:
# Index any project
cd ~/my-project
index-c ./src
# Query the index
qi "function_name" --limit 10To remove globally installed files:
sudo make uninstallThis removes:
- All binaries from
/usr/local/bin/ - All config files from
/usr/local/share/sourceminder/
The file watcher has been implemented using kqueue for BSD/macOS compatibility (instead of Linux's inotify). This provides:
- Native BSD/macOS support
- Portability to FreeBSD, OpenBSD, NetBSD, DragonFly BSD
- Daemon mode for monitoring file changes
The implementation watches individual files rather than directories, which is the recommended approach for kqueue.
The Makefile automatically detects Homebrew installation:
- Apple Silicon (M1/M2/M3/M4):
/opt/homebrew - Intel Macs:
/usr/local
Library paths are automatically configured for:
- tree-sitter headers and libraries
- SQLite headers and libraries (from Homebrew's keg-only installation)
- Tree-sitter grammar source directories
The project uses clang on macOS (aliased as gcc). Key compatibility fixes:
- Added
#include <strings.h>forstrcasecmp/strncasecmpfunctions (POSIX functions require explicit include on macOS) - Refactored X-macro patterns to avoid embedding
#includedirectives in function arguments (clang strictly enforces this) - Disabled
-Wembedded-directivewarnings for clang
Some warnings are expected and harmless on macOS:
-fprefetch-loop-arraysnot supported: This is a GCC-specific optimization flag not available in clang_Static_assertincompatible with C standards before C11: These are false warnings; the code uses C11implicit conversionwarnings: Code uses-Weverythingfor thorough checking
./qi --help# Index the project's source files
./index-c ./shared
# Or use any of the language-specific indexers
./index-ts ./typescript
./index-php ./php
./index-go ./go# Basic search
./qi "file_watcher" --limit 5
# Search with wildcards
./qi "%watcher%" --limit 10
# Exclude noise (comments and strings)
./qi "cursor" -x noise
# Search specific context types
./qi "FileWatcher" -i type
# Search for function calls
./qi "kevent" -i callIf you see errors about missing tree_sitter/parser.h:
- Verify tree-sitter grammar repos are cloned in the project root
- Check that the grammar directories contain
src/parser.cfiles - Ensure directory names match exactly (case-sensitive)
If you see errors about missing libraries:
- Verify Homebrew packages are installed:
brew list tree-sitter sqlite - Check Homebrew prefix:
brew --prefix(should be/opt/homebrewon Apple Silicon) - Ensure Homebrew is in your PATH
The warning about -fprefetch-loop-arrays is expected on macOS (clang doesn't support this GCC-specific flag). This is harmless and can be ignored.
If you see this warning during make clean, it means Homebrew isn't in the PATH for the make shell. This is harmless - the Makefile automatically falls back to detecting Homebrew directories by checking standard locations.
SourceMinder/
├── tree-sitter-c/ # C grammar (external repo)
├── tree-sitter-go/ # Go grammar (external repo)
├── tree-sitter-perl/ # Perl grammar (external repo)
├── tree-sitter-php/ # PHP grammar (external repo)
├── tree-sitter-typescript/ # TypeScript grammar (external repo)
├── c/ # C indexer code
│ ├── c_language.c # Language-specific implementation
│ ├── index-c.c # Main entry point
│ └── data/ # Config files (extensions, keywords, etc.)
├── go/ # Go indexer code
├── php/ # PHP indexer code
├── typescript/ # TypeScript indexer code
├── shared/ # Shared code (database, filters, etc.)
│ ├── file_watcher.c # File watching (kqueue on BSD/macOS)
│ ├── database.c # SQLite database layer
│ ├── filter.c # Symbol filtering
│ └── ...
├── build/ # Compiled binaries
├── Makefile # Build configuration
├── query-index.c # Query tool source
└── MACOS_SETUP.md # This file
Fresh macOS installation steps:
-
Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -
Install dependencies
brew install tree-sitter sqlite
-
Clone tree-sitter grammar repositories
cd /path/to/SourceMinder git clone https://github.com/tree-sitter/tree-sitter-c.git git clone https://github.com/tree-sitter/tree-sitter-go.git git clone https://github.com/tree-sitter-perl/tree-sitter-perl.git git clone https://github.com/tree-sitter/tree-sitter-php.git git clone https://github.com/tree-sitter/tree-sitter-python.git git clone https://github.com/tree-sitter/tree-sitter-typescript.git -
Configure and compile
./configure --enable-all make
-
Test
./qi --help ./index-c ./shared ./qi "file_watcher" --limit 5
- No file copying needed: The Makefile references tree-sitter grammar repositories directly from their external directories
- parser.c files are in .gitignore: These files are large and come from external repos, so they're not checked into version control
- grammar_version.h files are auto-generated: The configure script extracts versions from tree-sitter
package.jsonfiles using grep/sed (cross-platform compatible) - File watching uses kqueue: BSD/macOS implementation differs from Linux's inotify, but provides the same functionality
- Compiler warnings are normal: The project uses
-Weverythingfor comprehensive checking; most warnings are informational - Grammar updates: To update grammars, just
git pullin the respective tree-sitter-* directories, run./configureagain, and recompile
- File watching API: Uses kqueue (BSD) instead of inotify (Linux)
- Library paths: Homebrew locations differ from standard Linux paths
- Compiler: Uses clang (as
gcc) instead of actual GCC - POSIX functions: Require explicit
#include <strings.h>on macOS - X-macro handling: Stricter enforcement in clang required code refactoring
- Homebrew documentation: https://brew.sh
- Tree-sitter: https://tree-sitter.github.io/tree-sitter/
- kqueue manual:
man kqueueorman 2 kqueue - Project README: See
README.mdfor usage instructions and examples