Building from Source¶
This guide covers building pgraft from source for development and contributing.
Prerequisites¶
Ensure you have all required dependencies:
- PostgreSQL 17+: With development headers
- Go 1.21+: For Raft implementation
- GCC: C compiler
- Make: Build system
See Installation for system-specific installation instructions.
Build Process¶
1. Clone Repository¶
2. Build¶
The build process:
- Compiles C sources (
src/*.c
) to object files - Builds Go library (
src/pgraft_go.go
) to shared library - Links everything into final
pgraft.dylib
(or.so
on Linux) - Creates extension SQL from
pgraft--1.0.sql
3. Install¶
# Find PostgreSQL paths
PG_LIB=$(pg_config --libdir)
PG_SHARE=$(pg_config --sharedir)
# Install files
cp pgraft.dylib $PG_LIB/
cp src/pgraft_go.dylib $PG_LIB/
cp pgraft.control $PG_SHARE/extension/
cp pgraft--1.0.sql $PG_SHARE/extension/
Build Targets¶
Clean Build¶
Install After Build¶
Build with Debugging¶
This builds with: - -g
: Debug symbols - -O0
: No optimization
Verifying Build¶
Check for Errors¶
# Should have no errors
make 2>&1 | grep -i error
# Should have no warnings
make 2>&1 | grep -i warning
Check Binary¶
# macOS
otool -L pgraft.dylib
# Linux
ldd pgraft.so
# Should show dependencies on libpq, PostgreSQL, etc.
Test Extension¶
# Start PostgreSQL with extension
psql -c "CREATE EXTENSION pgraft;"
psql -c "SELECT pgraft_test();"
Development Workflow¶
Edit-Compile-Test Cycle¶
# 1. Edit source files
vim src/pgraft_core.c
# 2. Rebuild
make clean && make
# 3. Reinstall
make install
# 4. Restart PostgreSQL
pg_ctl restart -D /path/to/data
# 5. Test
psql -c "SELECT pgraft_test();"
Incremental Builds¶
For faster development, you can rebuild only changed files:
# Rebuild only C files (if Go unchanged)
make pgraft.dylib
# Rebuild only Go (if C unchanged)
cd src
go build -buildmode=c-shared -o pgraft_go.dylib pgraft_go.go
Code Organization¶
C Source Files (src/
)¶
File | Purpose |
---|---|
pgraft.c | Main extension entry point, background worker |
pgraft_core.c | Core Raft interface to Go layer |
pgraft_sql.c | SQL function implementations |
pgraft_guc.c | GUC (configuration) parameters |
pgraft_state.c | State management, shared memory |
pgraft_log.c | Log replication functions |
pgraft_kv.c | Key-value store implementation |
pgraft_kv_sql.c | KV SQL interface |
pgraft_util.c | Utility functions |
pgraft_go.c | CGO wrapper for Go library |
Header Files (include/
)¶
File | Purpose |
---|---|
pgraft_core.h | Core function declarations |
pgraft_go.h | Go library interface |
pgraft_guc.h | GUC declarations |
pgraft_sql.h | SQL function declarations |
pgraft_state.h | State structures |
pgraft_log.h | Log function declarations |
pgraft_kv.h | KV store declarations |
Go Implementation¶
src/pgraft_go.go
- Complete Raft implementation (2900+ lines)
Coding Standards¶
pgraft follows PostgreSQL C coding standards:
C89/C90 Compliance¶
/* Correct: Variables at function start */
void my_function(void)
{
int result;
char *message;
result = 0;
message = "Hello";
/* ... function code ... */
}
/* Wrong: Variables declared in middle */
void bad_function(void)
{
int result = 0;
/* some code */
char *message = "Hello"; /* NOT at start */
}
Comments¶
/* Correct: C-style comments */
/* This is a proper comment */
// Wrong: C++ style comments
// This is not allowed
Indentation¶
- Tabs only (not spaces)
- Tab width: 4 spaces
- Opening brace on same line:
Testing¶
Unit Tests¶
Manual Testing¶
-- Test basic functionality
SELECT pgraft_test();
SELECT pgraft_init();
SELECT pgraft_is_leader();
-- Test cluster operations
SELECT pgraft_add_node(2, '127.0.0.1', 7002);
SELECT * FROM pgraft_get_cluster_status();
Debugging¶
Enable Debug Output¶
Check Logs¶
Use GDB¶
# Start PostgreSQL with gdb
gdb --args postgres -D /path/to/data
# Set breakpoints
(gdb) break pgraft_init
(gdb) run
# When breakpoint hit
(gdb) backtrace
(gdb) print variable_name
Common Debug Points¶
/* Add logging in C code */
elog(LOG, "pgraft: Debug point reached, value=%d", value);
/* Add error logging */
elog(ERROR, "pgraft: Error occurred: %s", error_message);
Contributing¶
See Contributing for guidelines on: - Code style - Pull request process - Testing requirements - Documentation
Performance Profiling¶
CPU Profiling¶
# Use perf on Linux
perf record -g postgres
perf report
# Use Instruments on macOS
instruments -t "Time Profiler" postgres
Memory Profiling¶
# Valgrind
valgrind --leak-check=full postgres -D /path/to/data
# macOS Instruments
instruments -t "Leaks" postgres
Troubleshooting Build Issues¶
PostgreSQL Headers Not Found¶
Go Build Fails¶
Link Errors¶
# Check library paths
export DYLD_LIBRARY_PATH=/usr/local/pgsql/lib # macOS
export LD_LIBRARY_PATH=/usr/local/pgsql/lib # Linux
Build System Details¶
The Makefile
uses PostgreSQL's PGXS build system:
This automatically handles: - Finding PostgreSQL headers - Setting correct compiler flags - Linking with PostgreSQL libraries - Installing to correct directories