Initial Version
This commit is contained in:
parent
bdee369830
commit
d10f36746d
87
README.md
Normal file
87
README.md
Normal file
@ -0,0 +1,87 @@
|
||||
# build-zig-cpp
|
||||
|
||||
An Example build.zig for a pure C++ project
|
||||
|
||||
Simply: `git clone <this_repo> && zig build`
|
||||
|
||||
Result is in `zig-out/bin`
|
||||
|
||||
## Details
|
||||
|
||||
1. All the magic happens in build.zig
|
||||
2. I provide a win.cpp and main.cpp to showcase different OS capabilities built into zig
|
||||
3. Most of this is not well documented yet, as of 0.13/0.14 zig era, places to get information:
|
||||
1. https://ziglang.org/learn/build-system/ (less than helpful for C++ specific users like us)
|
||||
2. https://ziglang.org/documentation/master/std/#std.Build (std.Build is the namespace where all the functions and types live - the meat of the discussion)
|
||||
|
||||
## build.zig Explanation
|
||||
|
||||
First, refer to [build.zig](./build.zig) in this repo.
|
||||
|
||||
Now, we first #include the zig standard library in this build.zig:
|
||||
|
||||
```zig
|
||||
const std = @import("std");
|
||||
```
|
||||
|
||||
Then we write what is main() for `zig build`:
|
||||
|
||||
```zig
|
||||
pub fn build(b: *std.Build) void {
|
||||
}
|
||||
```
|
||||
|
||||
Then we set up default `.{}` target and optimization levels for my OS/build command. I.e. The system we're on.
|
||||
You can modify what you are targeting with your `zig build` command and this is where that magic is respected.
|
||||
|
||||
```zig
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
```
|
||||
|
||||
`target` is documented [here](https://ziglang.org/documentation/master/std/#std.Build.standardTargetOptions), by clicking on [ResolvedTarget](https://ziglang.org/documentation/master/std/#std.Build.ResolvedTarget)
|
||||
You can then follow the chain down to how I found the string `.windows` for this if statement:
|
||||
|
||||
```zig
|
||||
if (target.result.os.tag == .windows) {
|
||||
}
|
||||
```
|
||||
|
||||
Below is Self-explanatory: We're declaring an executable with a name of "win", using the earlier target and optimization options. Nothing is added to this empty executable yet.
|
||||
|
||||
```zig
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "win",
|
||||
.target = target,
|
||||
.optimize = optimize
|
||||
});
|
||||
```
|
||||
|
||||
Now we add our single source file:
|
||||
|
||||
```zig
|
||||
exe.addCSourceFile(.{ .file = b.path("win.cpp") });
|
||||
```
|
||||
|
||||
Followed by actually linking against libc and libcpp, which is required to have `<iostream>` `<string>`, etc:
|
||||
|
||||
```zig
|
||||
exe.linkLibC();
|
||||
exe.linkLibCpp();
|
||||
```
|
||||
|
||||
Note by default this is a dynamic link. To change to static link, set it up in the target options:
|
||||
|
||||
```zig
|
||||
const target = b.standardTargetOptions(.{
|
||||
.libc_static = true, // Enable libc static linking
|
||||
});
|
||||
```
|
||||
|
||||
Finally, we tell it to install/create this executable:
|
||||
|
||||
```zig
|
||||
b.installArtifact(exe);
|
||||
```
|
||||
|
||||
|
34
build.zig
Normal file
34
build.zig
Normal file
@ -0,0 +1,34 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
if (target.result.os.tag == .windows) {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "win",
|
||||
.target = target,
|
||||
.optimize = optimize
|
||||
});
|
||||
|
||||
exe.addCSourceFile(.{ .file = b.path("win.cpp") });
|
||||
|
||||
exe.linkLibC();
|
||||
exe.linkLibCpp();
|
||||
|
||||
b.installArtifact(exe);
|
||||
} else {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "exe",
|
||||
.target = target,
|
||||
.optimize = optimize
|
||||
});
|
||||
|
||||
exe.addCSourceFile(.{ .file = b.path("main.cpp") });
|
||||
|
||||
exe.linkLibC();
|
||||
exe.linkLibCpp();
|
||||
|
||||
b.installArtifact(exe);
|
||||
}
|
||||
}
|
5
main.cpp
Normal file
5
main.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include <iostream>
|
||||
int main() {
|
||||
std::cout << "Hello, World!" << std::endl;
|
||||
return 0;
|
||||
}
|
66
win.cpp
Normal file
66
win.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <tchar.h>
|
||||
|
||||
static TCHAR szWindowClass[] = _T("DesktopApp");
|
||||
static TCHAR szTitle[] = _T("Hello, Windows!");
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = WndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = szWindowClass;
|
||||
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
|
||||
|
||||
if (!RegisterClassEx(&wcex)) {
|
||||
MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Test app"), NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1200, 900, NULL, NULL, hInstance, NULL);
|
||||
if (!hWnd) {
|
||||
MessageBox(NULL,
|
||||
_T("Call to CreateWindow failed!"),
|
||||
_T("Test app"),
|
||||
NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user