This tutorial will guide you through the steps of creating a minimal Zig program that integrates with C++, Qt, and SQLite to create a simple application with a button that interacts with a local SQLite database.
First, initialize your Zig project:
mkdir simple_hello cd simple_hello zig init
This will create a basic project structure for you.
Ensure your project structure looks like this:
simple_hello/ ├── build.zig ├── src/ │ ├── main.zig │ ├── main.cpp │ ├── main.h │ ├── database.cpp │ └── database.h
main.zig
Create the main.zig
file with the following content:
const std = @import("std"); extern fn cppHelloWorld() void; extern fn initDatabase() void; extern fn insertData(data: [*]const u8) void; pub fn main() void { // Initialize the database initDatabase(); // Insert initial data const data = "Sample Data"; insertData(data); // Call the C++ function cppHelloWorld(); }
main.cpp
Create the main.cpp
file with the following content:
#include <QApplication> #include <QPushButton> #include <QMessageBox> #include <iostream> #include <sqlite3.h> #include "main.h" #include "database.h" void onButtonClick() { QMessageBox::information(nullptr, "Info", "Button clicked!"); } void cppHelloWorld() { int argc = 0; char *argv[] = { nullptr }; QApplication app(argc, argv); QPushButton button("Hello, World!"); QObject::connect(&button, &QPushButton::clicked, onButtonClick); button.resize(200, 100); button.show(); app.exec(); }
main.h
Create the main.h
file with the following content:
#ifndef MAIN_H #define MAIN_H #ifdef __cplusplus extern "C" { #endif void cppHelloWorld(); #ifdef __cplusplus } #endif #include "database.h" #endif // MAIN_H
database.cpp
Create the database.cpp
file with the following content:
#include <iostream> #include <sqlite3.h> #include "database.h" sqlite3 *db; void initDatabase() { int rc = sqlite3_open("world_builder.db", &db); if (rc) { std::cerr << "Can't open database: " << sqlite3_errmsg(db) << std::endl; return; } char *errMsg = 0; const char *sql = "CREATE TABLE IF NOT EXISTS World (ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL);"; rc = sqlite3_exec(db, sql, 0, 0, &errMsg); if (rc != SQLITE_OK) { std::cerr << "SQL error: " << errMsg << std::endl; sqlite3_free(errMsg); } else { std::cout << "Table created successfully" << std::endl; } } void insertData(const char *data) { char *errMsg = 0; std::string sql = "INSERT INTO World (Name) VALUES ('" + std::string(data) + "');"; int rc = sqlite3_exec(db, sql.c_str(), 0, 0, &errMsg); if (rc != SQLITE_OK) { std::cerr << "SQL error: " << errMsg << std::endl; sqlite3_free(errMsg); } else { std::cout << "Data inserted successfully" << std::endl; } }
database.h
Create the database.h
file with the following content:
#ifndef DATABASE_H #define DATABASE_H #ifdef __cplusplus extern "C" { #endif void initDatabase(); void insertData(const char *data); #ifdef __cplusplus } #endif #endif // DATABASE_H
build.zig
Update the build.zig
file with the following content:
const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const exe = b.addExecutable(.{ .name = "simple_hello", .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }); exe.addCSourceFile(.{ .file = b.path("src/main.cpp"), .flags = &[_][]const u8{ "-I.", "-fPIC", }, }); exe.addCSourceFile(.{ .file = b.path("src/database.cpp"), .flags = &[_][]const u8{ "-I.", "-fPIC", }, }); exe.addIncludePath(b.path("src")); // Add include path for headers exe.linkSystemLibrary("stdc++"); exe.linkSystemLibrary("Qt5Core"); exe.linkSystemLibrary("Qt5Widgets"); exe.linkSystemLibrary("sqlite3"); b.installArtifact(exe); const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(b.getInstallStep()); if (b.args) |args| { run_cmd.addArgs(args); } const run_step = b.step("run", "Run the app"); run_step.dependOn(&run_cmd.step); }
Make sure SQLite and Qt development libraries are installed:
sudo apt-get install libsqlite3-dev qtbase5-dev
cd /path/to/simple_hello
zig build
zig-out/bin/simple_hello
This setup should compile and run, displaying a window with a button that says "Hello, World!" and initialize an SQLite database, inserting sample data into it.