Skip to content

Commit 3ed79be

Browse files
authored
Merge pull request #105 from monkbroc/windows-build
Windows build
2 parents 136f8e2 + ccfa1fe commit 3ed79be

File tree

14 files changed

+302
-50
lines changed

14 files changed

+302
-50
lines changed

.github/workflows/build.yml

Lines changed: 122 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,141 @@ on:
55
push:
66

77
jobs:
8-
build:
8+
build-linux:
99
strategy:
1010
fail-fast: false
1111
matrix:
12-
os: [ ubuntu-24.04, ubuntu-22.04, macos-latest ]
13-
runs-on: ${{ matrix.os }}
14-
12+
include:
13+
- { arch: x64, os: 24, runner: ubuntu-24.04 }
14+
- { arch: arm64, os: 24, runner: ubuntu-24.04-arm }
15+
- { arch: x64, os: 22, runner: ubuntu-22.04 }
16+
- { arch: arm64, os: 22, runner: ubuntu-22.04-arm }
17+
runs-on: ${{ matrix.runner }}
1518
steps:
1619
- name: Checkout
1720
uses: actions/checkout@v4
1821

19-
- name: Dependencies (Ubuntu)
20-
if: runner.os == 'Linux'
22+
- name: Dependencies
2123
run: |
2224
sudo apt-get update
2325
sudo apt-get install -y libxml2-dev libusb-1.0-0-dev
2426
25-
- name: Dependencies (macOS)
26-
if: runner.os == 'macOS'
27+
- name: Build
28+
run: make
29+
30+
- name: Package
31+
run: |
32+
mkdir dist
33+
cp `pkg-config --variable=libdir libusb-1.0`/libusb-1.0.so.0 dist
34+
chmod 0644 dist/*
35+
cp qdl dist
36+
patchelf --set-rpath '$ORIGIN' dist/qdl
37+
38+
- name: Upload artifact
39+
uses: actions/upload-artifact@v4
40+
with:
41+
name: qdl-binary-ubuntu-${{matrix.os}}-${{ matrix.arch }}
42+
path: dist/*
43+
44+
45+
build-mac:
46+
strategy:
47+
fail-fast: false
48+
matrix:
49+
include:
50+
- { sys: macos-14, arch: arm64 }
51+
- { sys: macos-13, arch: intel }
52+
runs-on: ${{ matrix.sys }}
53+
54+
steps:
55+
- name: Checkout
56+
uses: actions/checkout@v4
57+
58+
- name: Dependencies
2759
run: |
2860
brew install libxml2
29-
brew install libusb
3061
3162
- name: Build
3263
run: make
64+
65+
- name: Package
66+
run: |
67+
set -x
68+
mkdir dist
69+
cp `pkg-config --variable=libdir libusb-1.0`/libusb-1.0.0.dylib dist
70+
cp `pkg-config --variable=libdir liblzma`/liblzma.5.dylib dist
71+
chmod 0644 dist/*
72+
cp qdl dist
73+
74+
if uname -a | grep -q arm64; then
75+
LIBUSB_DIR=/opt/homebrew/opt/libusb/lib
76+
LIBLZMA_DIR=/usr/lib
77+
else
78+
LIBUSB_DIR=/usr/local/opt/libusb/lib
79+
LIBLZMA_DIR=/usr/local/opt/xz/lib
80+
fi
81+
82+
install_name_tool -add_rpath @executable_path dist/qdl
83+
install_name_tool -change $LIBUSB_DIR/libusb-1.0.0.dylib @rpath/libusb-1.0.0.dylib dist/qdl
84+
install_name_tool -change $LIBLZMA_DIR/liblzma.5.dylib @rpath/liblzma.5.dylib dist/qdl
85+
otool -L dist/qdl
86+
dist/qdl || true
87+
88+
- name: Upload artifact
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: qdl-binary-macos-${{ matrix.arch }}
92+
path: dist/*
93+
94+
build-windows:
95+
strategy:
96+
fail-fast: false
97+
matrix:
98+
include:
99+
- { sys: windows-latest, arch: x64 }
100+
- { sys: windows-11-arm, arch: arm64 }
101+
runs-on: ${{ matrix.sys }}
102+
103+
steps:
104+
- name: Checkout
105+
uses: actions/checkout@v4
106+
107+
- name: Setup MSYS2
108+
id: msys2
109+
uses: msys2/setup-msys2@v2
110+
with:
111+
msystem: MINGW64
112+
install: >
113+
mingw-w64-x86_64-gcc
114+
mingw-w64-x86_64-make
115+
mingw-w64-x86_64-cmake
116+
mingw-w64-x86_64-pkg-config
117+
mingw-w64-x86_64-libxml2
118+
mingw-w64-x86_64-libusb
119+
120+
- name: Build
121+
run: mingw32-make
122+
shell: msys2 {0}
123+
124+
- name: Package
125+
shell: pwsh
126+
run: |
127+
$MSYS2_LOCATION = "${{ steps.msys2.outputs.msys2-location }}"
128+
$BIN_DIR = Join-Path $MSYS2_LOCATION "mingw64\bin"
129+
$DistDir = "dist"
130+
New-Item -ItemType Directory -Path $DistDir | Out-Null
131+
132+
Copy-Item (Join-Path $BIN_DIR "zlib1.dll") $DistDir
133+
Copy-Item (Join-Path $BIN_DIR "libxml2-2.dll") $DistDir
134+
Copy-Item (Join-Path $BIN_DIR "libusb-1.0.dll") $DistDir
135+
Copy-Item (Join-Path $BIN_DIR "liblzma-5.dll") $DistDir
136+
Copy-Item (Join-Path $BIN_DIR "libiconv-2.dll") $DistDir
137+
138+
Copy-Item "qdl.exe" $DistDir
139+
140+
- name: Upload artifact
141+
uses: actions/upload-artifact@v4
142+
with:
143+
name: qdl-binary-windows-${{ matrix.arch }}
144+
path: dist/*
145+

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
qdl
33
qdl-ramdump
44
ks
5+
*.exe
56
compile_commands.json
67
.cache
78
.version.h

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ CFLAGS += -O2 -Wall -g `pkg-config --cflags libxml-2.0 libusb-1.0`
66
LDFLAGS += `pkg-config --libs libxml-2.0 libusb-1.0`
77
prefix := /usr/local
88

9-
QDL_SRCS := firehose.c qdl.c sahara.c util.c patch.c program.c read.c ufs.c usb.c ux.c
9+
QDL_SRCS := firehose.c qdl.c sahara.c util.c patch.c program.c read.c ufs.c usb.c ux.c oscompat.c
1010
QDL_OBJS := $(QDL_SRCS:.c=.o)
1111

12-
RAMDUMP_SRCS := ramdump.c sahara.c usb.c util.c ux.c
12+
RAMDUMP_SRCS := ramdump.c sahara.c usb.c util.c ux.c oscompat.c
1313
RAMDUMP_OBJS := $(RAMDUMP_SRCS:.c=.o)
1414

1515
KS_OUT := ks
16-
KS_SRCS := ks.c sahara.c util.c ux.c
16+
KS_SRCS := ks.c sahara.c util.c ux.c oscompat.c
1717
KS_OBJS := $(KS_SRCS:.c=.o)
1818

1919
default: $(QDL) $(RAMDUMP) $(KS_OUT)

firehose.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,20 @@
3636
#include <assert.h>
3737
#include <ctype.h>
3838
#include <dirent.h>
39-
#include <err.h>
4039
#include <errno.h>
4140
#include <fcntl.h>
42-
#include <poll.h>
4341
#include <stdbool.h>
4442
#include <stdint.h>
4543
#include <stdio.h>
4644
#include <stdlib.h>
4745
#include <string.h>
48-
#include <termios.h>
4946
#include <time.h>
5047
#include <unistd.h>
5148
#include <libxml/parser.h>
5249
#include <libxml/tree.h>
5350
#include "qdl.h"
5451
#include "ufs.h"
52+
#include "oscompat.h"
5553

5654
enum {
5755
FIREHOSE_ACK = 0,
@@ -150,7 +148,7 @@ static int firehose_read(struct qdl_device *qdl, int timeout_ms,
150148

151149
do {
152150
n = qdl_read(qdl, buf, sizeof(buf), 100);
153-
if (n < 0) {
151+
if (n <= 0) {
154152
gettimeofday(&now, NULL);
155153
if (timercmp(&now, &timeout, <))
156154
continue;
@@ -448,11 +446,11 @@ static int firehose_program(struct qdl_device *qdl, struct program *program, int
448446
if (ret) {
449447
ux_err("flashing of %s failed\n", program->label);
450448
} else if (t) {
451-
ux_err("flashed \"%s\" successfully at %lukB/s\n",
449+
ux_info("flashed \"%s\" successfully at %lukB/s\n",
452450
program->label,
453451
(unsigned long)program->sector_size * num_sectors / t / 1024);
454452
} else {
455-
ux_err("flashed \"%s\" successfully\n",
453+
ux_info("flashed \"%s\" successfully\n",
456454
program->label);
457455
}
458456

@@ -534,7 +532,10 @@ static int firehose_read_op(struct qdl_device *qdl, struct read_op *read_op, int
534532
}
535533

536534
left -= chunk_size;
535+
#ifndef _WIN32
536+
// on mac/linux, every other response is empty
537537
expect_empty = true;
538+
#endif
538539
}
539540

540541
ret = firehose_read(qdl, 10000, firehose_generic_parser, NULL);
@@ -546,11 +547,11 @@ static int firehose_read_op(struct qdl_device *qdl, struct read_op *read_op, int
546547
t = time(NULL) - t0;
547548

548549
if (t) {
549-
ux_err("read \"%s\" successfully at %ldkB/s\n",
550+
ux_info("read \"%s\" successfully at %ldkB/s\n",
550551
read_op->filename,
551552
(unsigned long)read_op->sector_size * read_op->num_sectors / t / 1024);
552553
} else {
553-
ux_err("read \"%s\" successfully\n",
554+
ux_info("read \"%s\" successfully\n",
554555
read_op->filename);
555556
}
556557

ks.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@
22
#include <assert.h>
33
#include <ctype.h>
44
#include <dirent.h>
5-
#include <err.h>
65
#include <errno.h>
76
#include <fcntl.h>
87
#include <getopt.h>
9-
#include <poll.h>
108
#include <stdbool.h>
119
#include <stdint.h>
1210
#include <stdio.h>
1311
#include <stdlib.h>
1412
#include <string.h>
15-
#include <termios.h>
1613
#include <unistd.h>
1714

1815
#include "qdl.h"
16+
#include "oscompat.h"
17+
18+
#ifdef _WIN32
19+
const char *__progname = "ks";
20+
#endif
1921

2022
static struct qdl_device qdl;
2123

oscompat.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#ifdef _WIN32
2+
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <stdarg.h>
6+
#include <string.h>
7+
#include "oscompat.h"
8+
9+
extern const char *__progname;
10+
11+
void timeradd(const struct timeval *a, const struct timeval *b, struct timeval *result) {
12+
result->tv_sec = a->tv_sec + b->tv_sec;
13+
result->tv_usec = a->tv_usec + b->tv_usec;
14+
if (result->tv_usec >= 1000000) {
15+
result->tv_sec += 1;
16+
result->tv_usec -= 1000000;
17+
}
18+
}
19+
20+
void err(int eval, const char *fmt, ...) {
21+
va_list ap;
22+
va_start(ap, fmt);
23+
fprintf(stderr, "%s: ", __progname);
24+
if (fmt) {
25+
vfprintf(stderr, fmt, ap);
26+
fprintf(stderr, ": ");
27+
}
28+
fprintf(stderr, "%s\n", strerror(errno));
29+
va_end(ap);
30+
exit(eval);
31+
}
32+
33+
void errx(int eval, const char *fmt, ...) {
34+
va_list ap;
35+
va_start(ap, fmt);
36+
fprintf(stderr, "%s: ", __progname);
37+
if (fmt)
38+
vfprintf(stderr, fmt, ap);
39+
fprintf(stderr, "\n");
40+
va_end(ap);
41+
exit(eval);
42+
}
43+
44+
void warn(const char *fmt, ...) {
45+
va_list ap;
46+
va_start(ap, fmt);
47+
fprintf(stderr, "%s: ", __progname);
48+
if (fmt) {
49+
vfprintf(stderr, fmt, ap);
50+
fprintf(stderr, ": ");
51+
}
52+
fprintf(stderr, "%s\n", strerror(errno));
53+
va_end(ap);
54+
}
55+
56+
void warnx(const char *fmt, ...) {
57+
va_list ap;
58+
va_start(ap, fmt);
59+
fprintf(stderr, "%s: ", __progname);
60+
if (fmt)
61+
vfprintf(stderr, fmt, ap);
62+
fprintf(stderr, "\n");
63+
va_end(ap);
64+
}
65+
66+
#endif // _WIN32

oscompat.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef __OSCOMPAT_H__
2+
#define __OSCOMPAT_H__
3+
4+
#ifndef _WIN32
5+
6+
#include <err.h>
7+
8+
#define O_BINARY 0
9+
10+
#else // _WIN32
11+
12+
#include <sys/time.h>
13+
#include <stdbool.h>
14+
15+
void timeradd(const struct timeval *a, const struct timeval *b, struct timeval *result);
16+
17+
void err(int eval, const char *fmt, ...);
18+
void errx(int eval, const char *fmt, ...);
19+
void warn(const char *fmt, ...);
20+
void warnx(const char *fmt, ...);
21+
22+
#endif
23+
24+
#endif

program.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2929
* POSSIBILITY OF SUCH DAMAGE.
3030
*/
31+
#define _FILE_OFFSET_BITS 64
3132
#include <errno.h>
3233
#include <fcntl.h>
3334
#include <string.h>
@@ -38,6 +39,7 @@
3839

3940
#include "program.h"
4041
#include "qdl.h"
42+
#include "oscompat.h"
4143

4244
static struct program *programes;
4345
static struct program *programes_last;
@@ -179,7 +181,7 @@ int program_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl,
179181
filename = tmp;
180182
}
181183

182-
fd = open(filename, O_RDONLY);
184+
fd = open(filename, O_RDONLY | O_BINARY);
183185

184186
if (fd < 0) {
185187
ux_info("unable to open %s", program->filename);

0 commit comments

Comments
 (0)