Skip to content

Commit fd0b288

Browse files
authored
Merge pull request #5 from allyourcodebase/kah/zig-0.15
feat(zig-0.15): clean up build process and update to Zig 0.15
2 parents 9a14829 + b77d4d8 commit fd0b288

File tree

11 files changed

+237
-199
lines changed

11 files changed

+237
-199
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.zig text eol=lf
2+
*.zon text eol=lf

.github/workflows/build.yml

Lines changed: 0 additions & 43 deletions
This file was deleted.

.github/workflows/ci.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
workflow_dispatch:
11+
12+
jobs:
13+
build:
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
zig-version: [master]
18+
os: [ubuntu-latest, macos-latest, windows-latest]
19+
include:
20+
- zig-version: "0.15.1"
21+
os: ubuntu-latest
22+
runs-on: ${{ matrix.os }}
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
- name: Setup Zig
28+
uses: mlugg/setup-zig@v2
29+
with:
30+
version: ${{ matrix.zig-version }}
31+
32+
- name: Check Formatting
33+
run: zig fmt --ast-check --check .
34+
35+
- name: Build
36+
run: zig build -Dstrip=true -Dzlib=true --summary all

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.zig-cache
2+
zig-cache
23
zig-out

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,44 @@
1+
[![CI](https://github.com/hamptokr/zig-libssh2/actions/workflows/ci.yaml/badge.svg)](https://github.com/hamptokr/zig-libssh2/actions)
2+
13
# libssh2
24

3-
libssh2 packaged with Zig
5+
This is [libssh2](https://github.com/libssh2/libssh2), packaged for [Zig](https://ziglang.org/).
6+
7+
## Installation
8+
9+
First, update your `build.zig.zon`:
10+
11+
```
12+
# Initialize a `zig build` project if you haven't already
13+
zig init
14+
zig fetch --save git+https://github.com/allyourcodebase/libssh2.git#libssh2-1.11.1
15+
```
16+
17+
You can then import `libssh2` in your `build.zig` with:
18+
19+
```zig
20+
const libssh2_dependency = b.dependency("libssh2", .{
21+
.target = target,
22+
.optimize = optimize,
23+
});
24+
your_exe.linkLibrary(libssh2_dependency.artifact("ssh2"));
25+
```
26+
27+
## Build Options
28+
29+
`libssh2` offers a few options which you can control like so:
30+
31+
```zig
32+
const libssh2_dependency = b.dependency("libssh2", .{
33+
.target = target,
34+
.optimize = optimize,
35+
.zlib = true, // links to zlib for payload compression if enabled (default=true)
36+
.strip = true, // Strip debug information (default=false)
37+
.linkage = .static, // Whether to link statically or dynamically (default=static)
38+
.@"crypto-backend" = .auto, // auto will to default to wincng on windows, openssl everywhere else. (default=auto)
39+
});
40+
```
41+
42+
```
43+
44+
```

build.zig

Lines changed: 125 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,141 @@
11
const std = @import("std");
22

3+
const version: std.SemanticVersion = .{ .major = 1, .minor = 11, .patch = 1 };
4+
5+
const CryptoBackend = enum {
6+
auto,
7+
openssl,
8+
mbedtls,
9+
libgcrypt,
10+
wincng,
11+
};
12+
313
pub fn build(b: *std.Build) void {
14+
const upstream = b.dependency("libssh2", .{});
415
const target = b.standardTargetOptions(.{});
516
const optimize = b.standardOptimizeOption(.{});
617

7-
const libssh2_dep = b.dependency("libssh2", .{
8-
.target = target,
9-
.optimize = optimize,
10-
});
18+
const linkage = b.option(std.builtin.LinkMode, "linkage", "Link mode") orelse .static;
19+
const strip = b.option(bool, "strip", "Omit debug information");
20+
const pic = b.option(bool, "pie", "Produce Position Independent Code");
21+
22+
const crypto_choice = b.option(CryptoBackend, "crypto-backend", "Crypto backend: auto|openssl|mbedtls|libgcrypt|wincng") orelse .auto;
23+
const zlib = b.option(bool, "zlib", "Enable SSH payload compression (links zlib)") orelse false;
24+
25+
const is_windows = target.result.os.tag == .windows;
26+
const mbedtls = crypto_choice == .mbedtls;
27+
const openssl = (crypto_choice == .auto and !is_windows) or crypto_choice == .openssl;
28+
const wincng = (crypto_choice == .auto and is_windows) or crypto_choice == .wincng;
29+
const libgcrypt = crypto_choice == .libgcrypt;
1130

12-
const mbedtls_dep = b.dependency("mbedtls", .{
13-
.target = target,
14-
.optimize = optimize,
31+
const config_header = b.addConfigHeader(.{
32+
.style = .{
33+
.cmake = upstream.path("src/libssh2_config_cmake.h.in"),
34+
},
35+
.include_path = "libssh2_config.h",
36+
}, .{
37+
.LIBSSH2_API = switch (target.result.os.tag) {
38+
.windows => "__declspec(dllexport)",
39+
else => "",
40+
},
41+
.LIBSSH2_HAVE_ZLIB = zlib,
42+
.HAVE_SYS_UIO_H = !is_windows,
43+
.HAVE_WRITEV = !is_windows,
44+
.HAVE_SYS_SOCKET_H = !is_windows,
45+
.HAVE_NETINET_IN_H = !is_windows,
46+
.HAVE_ARPA_INET_H = !is_windows,
47+
.HAVE_SYS_TYPES_H = !is_windows,
48+
.HAVE_INTTYPES_H = true,
49+
.HAVE_STDINT_H = true,
1550
});
1651

17-
const lib = b.addStaticLibrary(.{
52+
const ssh2_lib = b.addLibrary(.{
53+
.version = version,
1854
.name = "ssh2",
19-
.target = target,
20-
.optimize = optimize,
21-
.link_libc = true,
55+
.linkage = linkage,
56+
.root_module = b.createModule(.{
57+
.target = target,
58+
.optimize = optimize,
59+
.link_libc = true,
60+
.strip = strip,
61+
.pic = pic,
62+
}),
2263
});
23-
lib.addIncludePath(libssh2_dep.path("include"));
24-
lib.linkLibrary(mbedtls_dep.artifact("mbedtls"));
25-
lib.addCSourceFiles(.{
26-
.root = libssh2_dep.path("src"),
27-
.flags = &.{},
28-
.files = &.{
29-
"channel.c",
30-
"comp.c",
31-
"crypt.c",
32-
"hostkey.c",
33-
"kex.c",
34-
"mac.c",
35-
"misc.c",
36-
"packet.c",
37-
"publickey.c",
38-
"scp.c",
39-
"session.c",
40-
"sftp.c",
41-
"userauth.c",
42-
"transport.c",
43-
"version.c",
44-
"knownhost.c",
45-
"agent.c",
46-
"mbedtls.c",
47-
"pem.c",
48-
"keepalive.c",
49-
"global.c",
50-
"blowfish.c",
51-
"bcrypt_pbkdf.c",
52-
"agent_win.c",
53-
},
54-
});
55-
lib.installHeader(b.path("config/libssh2_config.h"), "libssh2_config.h");
56-
lib.installHeadersDirectory(libssh2_dep.path("include"), ".", .{});
57-
lib.defineCMacro("LIBSSH2_MBEDTLS", null);
64+
b.installArtifact(ssh2_lib);
65+
ssh2_lib.installHeadersDirectory(upstream.path("include"), "", .{});
66+
ssh2_lib.root_module.addConfigHeader(config_header);
67+
ssh2_lib.root_module.addIncludePath(upstream.path("include"));
68+
ssh2_lib.root_module.addCMacro("HAVE_CONFIG_H", "1");
69+
ssh2_lib.root_module.addCSourceFiles(.{ .files = ssh2_src, .root = upstream.path(""), .flags = ssh2_flags });
5870

59-
if (target.result.os.tag == .windows) {
60-
lib.defineCMacro("_CRT_SECURE_NO_DEPRECATE", "1");
61-
lib.defineCMacro("HAVE_LIBCRYPT32", null);
62-
lib.defineCMacro("HAVE_WINSOCK2_H", null);
63-
lib.defineCMacro("HAVE_IOCTLSOCKET", null);
64-
lib.defineCMacro("HAVE_SELECT", null);
65-
lib.defineCMacro("LIBSSH2_DH_GEX_NEW", "1");
71+
if (mbedtls) {
72+
ssh2_lib.root_module.addCSourceFile(.{ .file = upstream.path("src/mbedtls.c"), .flags = ssh2_flags });
73+
ssh2_lib.root_module.addCMacro("LIBSSH2_MBEDTLS", "1");
74+
ssh2_lib.linkSystemLibrary("mbedtls");
75+
ssh2_lib.linkSystemLibrary("mbedcrypto");
76+
ssh2_lib.linkSystemLibrary("mbedx509");
77+
}
6678

67-
if (target.result.isGnu()) {
68-
lib.defineCMacro("HAVE_UNISTD_H", null);
69-
lib.defineCMacro("HAVE_INTTYPES_H", null);
70-
lib.defineCMacro("HAVE_SYS_TIME_H", null);
71-
lib.defineCMacro("HAVE_GETTIMEOFDAY", null);
72-
}
73-
} else {
74-
lib.defineCMacro("HAVE_UNISTD_H", null);
75-
lib.defineCMacro("HAVE_INTTYPES_H", null);
76-
lib.defineCMacro("HAVE_STDLIB_H", null);
77-
lib.defineCMacro("HAVE_SYS_SELECT_H", null);
78-
lib.defineCMacro("HAVE_SYS_UIO_H", null);
79-
lib.defineCMacro("HAVE_SYS_SOCKET_H", null);
80-
lib.defineCMacro("HAVE_SYS_IOCTL_H", null);
81-
lib.defineCMacro("HAVE_SYS_TIME_H", null);
82-
lib.defineCMacro("HAVE_SYS_UN_H", null);
83-
lib.defineCMacro("HAVE_LONGLONG", null);
84-
lib.defineCMacro("HAVE_GETTIMEOFDAY", null);
85-
lib.defineCMacro("HAVE_INET_ADDR", null);
86-
lib.defineCMacro("HAVE_POLL", null);
87-
lib.defineCMacro("HAVE_SELECT", null);
88-
lib.defineCMacro("HAVE_SOCKET", null);
89-
lib.defineCMacro("HAVE_STRTOLL", null);
90-
lib.defineCMacro("HAVE_SNPRINTF", null);
91-
lib.defineCMacro("HAVE_O_NONBLOCK", null);
79+
if (openssl) {
80+
ssh2_lib.root_module.addCSourceFile(.{ .file = upstream.path("src/openssl.c"), .flags = ssh2_flags });
81+
ssh2_lib.root_module.addCMacro("LIBSSH2_OPENSSL", "1");
82+
ssh2_lib.linkSystemLibrary("ssl");
83+
ssh2_lib.linkSystemLibrary("crypto");
84+
}
85+
86+
if (wincng) {
87+
ssh2_lib.root_module.addCSourceFile(.{ .file = upstream.path("src/wincng.c"), .flags = ssh2_flags });
88+
ssh2_lib.root_module.addCMacro("LIBSSH2_WINCNG", "1");
89+
// Windows system libs (zig handles names)
90+
ssh2_lib.linkSystemLibrary("bcrypt");
91+
ssh2_lib.linkSystemLibrary("ncrypt");
92+
}
93+
94+
if (libgcrypt) {
95+
ssh2_lib.root_module.addCSourceFile(.{ .file = upstream.path("src/libgcrypt.c"), .flags = ssh2_flags });
96+
ssh2_lib.root_module.addCMacro("LIBSSH2_LIBGCRYPT", "1");
97+
ssh2_lib.linkSystemLibrary("gcrypt");
9298
}
9399

94-
b.installArtifact(lib);
100+
if (zlib) {
101+
if (b.systemIntegrationOption("zlib", .{})) {
102+
ssh2_lib.root_module.linkSystemLibrary("zlib", .{});
103+
} else if (b.lazyDependency("zlib", .{
104+
.target = target,
105+
.optimize = optimize,
106+
})) |zlib_dependency| {
107+
ssh2_lib.root_module.linkLibrary(zlib_dependency.artifact("z"));
108+
}
109+
}
95110
}
111+
112+
pub const ssh2_src: []const []const u8 = &.{
113+
"src/agent.c",
114+
"src/bcrypt_pbkdf.c",
115+
"src/blowfish.c",
116+
"src/chacha.c",
117+
"src/channel.c",
118+
"src/cipher-chachapoly.c",
119+
"src/comp.c",
120+
"src/crypt.c",
121+
"src/global.c",
122+
"src/hostkey.c",
123+
"src/keepalive.c",
124+
"src/kex.c",
125+
"src/knownhost.c",
126+
"src/mac.c",
127+
"src/misc.c",
128+
"src/packet.c",
129+
"src/pem.c",
130+
"src/poly1305.c",
131+
"src/publickey.c",
132+
"src/scp.c",
133+
"src/session.c",
134+
"src/sftp.c",
135+
"src/transport.c",
136+
"src/userauth.c",
137+
"src/userauth_kbd_packet.c",
138+
"src/version.c",
139+
};
140+
141+
pub const ssh2_flags: []const []const u8 = &.{};

0 commit comments

Comments
 (0)