librclone/ctest: add Windows support and fix memory management

Make ctest build and run on Windows in addition to Linux/macOS:

- Add OS detection in Makefile using ifeq ($(OS),Windows_NT)
- Use .lib extension and .exe suffix on Windows
- Link Windows system libraries (winmm, ws2_32, ole32)
- Remove unused dlfcn.h include that prevented compilation on Windows

Fix memory management to use RcloneFreeString instead of free for
strings returned by RcloneRPC, as documented in the librclone README.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
BizaNator
2026-03-31 10:51:15 +01:00
committed by Nick Craig-Wood
co-authored by Claude Opus 4.6
parent 434edba275
commit ffdd043b95
2 changed files with 19 additions and 11 deletions
+16 -7
View File
@@ -1,17 +1,26 @@
CFLAGS = -g -Wall CFLAGS = -g -Wall
LDFLAGS = -L. -lrclone -lpthread -ldl
ctest: ctest.o librclone.a ifeq ($(OS),Windows_NT)
EXE = .exe
LIB = librclone.lib
LDFLAGS = -L. -lrclone -lwinmm -lws2_32 -lole32
else
EXE =
LIB = librclone.a
LDFLAGS = -L. -lrclone -lpthread -ldl
endif
ctest$(EXE): ctest.o $(LIB)
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
ctest.o: ctest.c librclone.h ctest.o: ctest.c librclone.h
$(CC) $(CFLAGS) -c $^ $(LDFLAGS) $(CC) $(CFLAGS) -c $^ $(LDFLAGS)
librclone.a librclone.h: $(LIB) librclone.h:
go build --buildmode=c-archive -o librclone.a github.com/rclone/rclone/librclone go build --buildmode=c-archive -o $(LIB) github.com/rclone/rclone/librclone
test: ctest test: ctest$(EXE)
./ctest ./ctest$(EXE)
clean: clean:
rm -f tmp ctest *.o *.a *.h *.gch rm -f tmp ctest ctest.exe *.o *.a *.lib *.h *.gch
+3 -4
View File
@@ -4,14 +4,13 @@ This is a very simple test/demo program for librclone's C interface
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <dlfcn.h>
#include "librclone.h" #include "librclone.h"
void testRPC(char *method, char *in) { void testRPC(char *method, char *in) {
struct RcloneRPCResult out = RcloneRPC(method, in); struct RcloneRPCResult out = RcloneRPC(method, in);
printf("status: %d\n", out.Status); printf("status: %d\n", out.Status);
printf("output: %s\n", out.Output); printf("output: %s\n", out.Output);
free(out.Output); RcloneFreeString(out.Output);
} }
// noop command // noop command
@@ -44,7 +43,7 @@ void testNoOp() {
fprintf(stderr, "Wrong status: want: %d: got: %d\n", 200, out.Status); fprintf(stderr, "Wrong status: want: %d: got: %d\n", 200, out.Status);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
free(out.Output); RcloneFreeString(out.Output);
} }
// error command // error command
@@ -83,7 +82,7 @@ void testError() {
fprintf(stderr, "Wrong status: want: %d: got: %d\n", 500, out.Status); fprintf(stderr, "Wrong status: want: %d: got: %d\n", 500, out.Status);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
free(out.Output); RcloneFreeString(out.Output);
} }
// copy file using "operations/copyfile" command // copy file using "operations/copyfile" command