Skip to content

Commit 13cb353

Browse files
authored
Merge pull request #332 from padelsbach/padelsbach/build-updates
Build script updates
2 parents 194db83 + ed66804 commit 13cb353

9 files changed

Lines changed: 250 additions & 197 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ infer-out/
3838
target/
3939

4040
**/.claude/settings.local.json
41+
42+
# Native dependency files
43+
native/*.d

Makefile

Lines changed: 117 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,138 @@ ifeq ($(LIBDIR),)
1717
LIBDIR=lib
1818
endif
1919

20+
# Native JNI compilation variables
21+
NATIVE_SRC_DIR = native
22+
NATIVE_SRCS = $(wildcard $(NATIVE_SRC_DIR)/*.c)
23+
NATIVE_OBJS = $(NATIVE_SRCS:.c=.o)
24+
NATIVE_DEPS = $(NATIVE_SRCS:.c=.d)
25+
26+
CC ?= gcc
27+
WOLFSSL_INSTALL_DIR ?= $(INSTALL_DIR)
28+
WOLFSSL_LIBNAME ?= wolfssl
29+
30+
# Platform detection
31+
OS := $(shell uname)
32+
ARCH := $(shell uname -m)
33+
34+
# JAVA_HOME detection with platform-aware fallback
35+
JAVA_HOME ?= $(shell \
36+
if [ "$(OS)" = "Darwin" ]; then \
37+
/usr/libexec/java_home 2>/dev/null; \
38+
else \
39+
java_bin=$$(readlink -f $$(which java) 2>/dev/null); \
40+
jh=$$(dirname $$(dirname $$java_bin)); \
41+
if [ ! -d "$$jh/include" ]; then jh=$$(dirname $$jh); fi; \
42+
echo $$jh; \
43+
fi)
44+
45+
# Platform-specific flags
46+
ifeq ($(OS),Darwin)
47+
JNI_INCLUDES = -I$(JAVA_HOME)/include \
48+
-I$(JAVA_HOME)/include/darwin \
49+
-I$(WOLFSSL_INSTALL_DIR)/include
50+
JNI_LIB_FLAGS = -dynamiclib
51+
JNI_LIB_NAME = libwolfssljni.dylib
52+
else ifeq ($(OS),Linux)
53+
JNI_INCLUDES = -I$(JAVA_HOME)/include \
54+
-I$(JAVA_HOME)/include/linux \
55+
-I$(WOLFSSL_INSTALL_DIR)/include
56+
JNI_LIB_FLAGS = -shared
57+
JNI_LIB_NAME = libwolfssljni.so
58+
ifneq ($(filter x86_64 aarch64,$(ARCH)),)
59+
FPIC = -fPIC
60+
endif
61+
else
62+
$(error Unsupported host OS '$(OS)'; supported OSes are Linux and Darwin)
63+
endif
64+
65+
# Optionally enable all patch defines in the native code for testing.
66+
ifeq ($(ENABLE_PATCHES),1)
67+
PATCH_CFLAGS = $(addprefix -D,$(shell ./scripts/find-wolfssl-pr-patch-defines.sh))
68+
ifeq ($(PATCH_CFLAGS),)
69+
$(warning no WOLFSSL_PR*_PATCH_APPLIED defines found; building without patches)
70+
endif
71+
endif
72+
73+
# Verbose mode: set V=1 to see full compiler commands
74+
ifeq ($(V),1)
75+
Q =
76+
else
77+
Q = @
78+
endif
79+
80+
JNI_CFLAGS = -Wall -Wextra -Werror $(FPIC) -MMD -MP $(PATCH_CFLAGS) $(CFLAGS)
81+
JNI_LDFLAGS = -Wall $(JNI_LIB_FLAGS) $(CFLAGS) \
82+
-L$(WOLFSSL_INSTALL_DIR)/lib \
83+
-L$(WOLFSSL_INSTALL_DIR)/lib64
84+
JNI_LDLIBS = -l$(WOLFSSL_LIBNAME)
85+
86+
.PHONY: all build check native clean-native clean install uninstall dist rpm print-config
87+
2088
all: build
2189

22-
.PHONY: build
23-
build: java.sh build.xml
24-
@cflags=""; \
25-
if [ "$(ENABLE_PATCHES)" = "1" ]; then \
26-
if [ -n "$(PATCH_DEFINES)" ]; then \
27-
defines="$(PATCH_DEFINES)"; \
28-
else \
29-
defines="$$(./scripts/find-wolfssl-pr-patch-defines.sh)"; \
30-
fi; \
31-
if [ -z "$$defines" ]; then \
32-
echo "warning: no WOLFSSL_PR*_PATCH_APPLIED defines found; building without patches"; \
33-
else \
34-
for define in $$defines; do \
35-
cflags="$$cflags -D$$define"; \
36-
done; \
37-
fi; \
38-
fi; \
39-
CFLAGS="$$cflags" ./java.sh $(INSTALL_DIR); \
90+
build: build.xml
91+
$(MAKE) native WOLFSSL_INSTALL_DIR="$(WOLFSSL_INSTALL_DIR)" WOLFSSL_LIBNAME="$(WOLFSSL_LIBNAME)"
4092
ant
4193

4294
check: build
4395
ant test
4496

45-
clean:
46-
ant clean cleanjni
97+
# Pattern rule: compile any native/*.c to native/*.o
98+
$(NATIVE_SRC_DIR)/%.o: $(NATIVE_SRC_DIR)/%.c | print-config
99+
@echo " CC $<"
100+
$(Q)$(CC) $(JNI_CFLAGS) -c $< -o $@ $(JNI_INCLUDES)
101+
102+
# Link all .o files into the shared library
103+
lib/$(JNI_LIB_NAME): $(NATIVE_OBJS) | lib
104+
@echo " LD $@"
105+
$(Q)$(CC) $(JNI_LDFLAGS) -o $@ $(NATIVE_OBJS) $(JNI_LDLIBS)
106+
107+
lib:
108+
mkdir -p lib
47109

110+
# Print build configuration, matching the output style of upstream java.sh
111+
print-config:
112+
@echo "Compiling Native JNI library:"
113+
@echo " WOLFSSL_INSTALL_DIR = $(WOLFSSL_INSTALL_DIR)"
114+
@echo " WOLFSSL_LIBNAME = $(WOLFSSL_LIBNAME)"
115+
@if [ -n "$(JAVA_HOME)" ]; then \
116+
echo " JAVA_HOME = $(JAVA_HOME)"; \
117+
else \
118+
echo " JAVA_HOME = <not set>"; \
119+
fi
120+
@if [ -n "$(CFLAGS)" ]; then \
121+
echo " CFLAGS = $(CFLAGS)"; \
122+
else \
123+
echo " CFLAGS = <none>"; \
124+
fi
125+
@echo " Host OS = $(OS) $(ARCH)"
126+
127+
# Convenience target for building just native JNI library
128+
native: lib/$(JNI_LIB_NAME)
129+
@echo " Generated ./lib/$(JNI_LIB_NAME)"
130+
131+
# Clean only native artifacts (.o, .d files and shared lib)
132+
clean-native:
133+
$(Q)rm -f $(NATIVE_SRC_DIR)/*.o $(NATIVE_SRC_DIR)/*.d
134+
$(Q)rm -f lib/$(JNI_LIB_NAME)
135+
136+
# Include auto-generated dependency files (if they exist)
137+
-include $(NATIVE_DEPS)
138+
139+
clean: clean-native
140+
ant clean cleanjni
48141

49142
install:
50143
$(INSTALL) -d $(INSTALL_DIR)/$(LIBDIR)
51-
$(INSTALL) lib/libwolfssljni.so $(INSTALL_DIR)/$(LIBDIR)
144+
$(INSTALL) lib/$(JNI_LIB_NAME) $(INSTALL_DIR)/$(LIBDIR)
52145
$(INSTALL) lib/wolfssl.jar $(INSTALL_DIR)/$(LIBDIR)
53146
$(INSTALL) lib/wolfssl-jsse.jar $(INSTALL_DIR)/$(LIBDIR)
54147

55148
uninstall:
56-
rm -f $(INSTALL_DIR)/$(LIBDIR)/libwolfssljni.so
57-
rm -f $(INSTALL_DIR)/share/java/wolfssl.jar
58-
rm -f $(INSTALL_DIR)/share/java/wolfssl-jsse.jar
149+
rm -f $(INSTALL_DIR)/$(LIBDIR)/$(JNI_LIB_NAME)
150+
rm -f $(INSTALL_DIR)/$(LIBDIR)/wolfssl.jar
151+
rm -f $(INSTALL_DIR)/$(LIBDIR)/wolfssl-jsse.jar
59152

60153
dist:
61154
@mkdir -p "$(NAME)-$(VERSION)"

README.md

Lines changed: 75 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -65,33 +65,65 @@ If building a wolfSSL FIPS or FIPS Ready release bundle, additional
6565
configure options may be required. Reference the wolfSSL Manual and build
6666
documentation for exact build instructions.
6767

68-
## Building with ant
68+
## Building and testing with make/ant
6969

7070
wolfSSL JNI/JSSE's ant build is the most stable and well-tested. Newer support
7171
for building with Maven has also been added. See section below for instructions
7272
on building with Maven.
7373

74-
***Note 1)***
75-
The `java.sh` script uses a common location for the Java install location. If
76-
your Java install location is different, this could lead to an error when
77-
running `java.sh`. In this case, you should modify `java.sh` to match your
78-
environment.
79-
80-
Build targets for ant are :
81-
* **ant build (ant)** (only builds the jar necessary for an app to use)
82-
* **ant test** (builds the jar and tests then runs the tests, requires JUNIT setup)
83-
* **ant examples** (builds the jar and example cases)
84-
* **ant clean** (cleans all Java artifacts)
85-
* **ant cleanjni** (cleans native artifacts)
74+
The `Makefile` compiles the native JNI shared library
75+
(`libwolfssljni.so`/`libwolfssljni.dylib`) and invokes `ant` to build the Java
76+
sources. It will auto-detect `JAVA_HOME` if not already set. To explicitly
77+
specify a Java installation, set `JAVA_HOME` before running `make`.
78+
79+
Make targets:
80+
* **make** / **make build** - Compiles the native JNI library and Java sources (JAR)
81+
* **make check** - Builds and runs JUnit tests (requires `JUNIT_HOME`)
82+
* **make native** - Compiles only the native JNI shared library
83+
* **make clean** - Cleans all Java and native artifacts
84+
* **make clean-native** - Cleans only native artifacts (`.o`, `.d`, shared lib)
85+
* **make install** - Installs shared library and JARs
86+
* **make uninstall** - Removes installed files
87+
88+
Ant-only targets are also available:
89+
* **ant build (ant)** - Only builds the JAR
90+
* **ant test** - Builds and runs tests (requires JUNIT setup)
91+
* **ant examples** - Builds examples
92+
* **ant clean** - Cleans Java artifacts
93+
* **ant cleanjni** - Cleans native artifacts
8694

8795
To build wolfJSSE:
8896

8997
```
9098
$ cd wolfssljni
91-
$ ./java.sh
92-
$ ant
9399
$ export JUNIT_HOME=/path/to/junit/jars
94-
$ ant test
100+
$ make build
101+
$ make check
102+
```
103+
104+
Custom wolfSSL installation directories and library names can be passed to
105+
`make`:
106+
107+
```
108+
$ make WOLFSSL_INSTALL_DIR=/path/to/wolfssl WOLFSSL_LIBNAME=wolfssljsse
109+
```
110+
111+
Set `V=1` to see the full compiler commands:
112+
113+
```
114+
$ make V=1
115+
```
116+
117+
Set `ENABLE_PATCHES=1` to automatically detect and enable JNI code that
118+
depends on wolfSSL pull request patches (`WOLFSSL_PR*_PATCH_APPLIED` defines).
119+
This enables functionality and test coverage for features added since the last
120+
official wolfSSL build.
121+
122+
**Note:** this requires a recent build of wolfSSL with the PR included, often
123+
newer than the latest tagged release.
124+
125+
```
126+
$ make ENABLE_PATCHES=1
95127
```
96128

97129
To compile and run the examples, use the `ant examples` target:
@@ -108,28 +140,20 @@ $ ./examples/provider/ServerJSSE.sh
108140
$ ./examples/provider/ClientJSSE.sh
109141
```
110142

111-
### java.sh Script Options
112-
113-
The `java.sh` script compiles the native JNI sources into a shared library named
114-
either `libwolfssljni.so` (Linux/Unix) or `libwolfssljni.dylib` (MacOS).
115-
Compiling on Linux/Unix and Mac OSX are currently supported.
143+
### java.sh Script
116144

117-
This script will attempt to auto-detect the `JAVA_HOME` location if not set.
118-
To explicitly use a Java home location, set the `JAVA_HOME` environment variable
119-
prior to running this script.
145+
The `java.sh` script is a convenience wrapper around the Makefile that compiles
146+
the native JNI sources into a shared library named either `libwolfssljni.so`
147+
(Linux/Unix) or `libwolfssljni.dylib` (MacOS). It invokes `make clean-native`
148+
followed by `make native`, performing a clean rebuild of the native library each
149+
time.
120150

121-
This script will try to link against a wolfSSL library installed to the
122-
default location of `/usr/local`. This script accepts two arguments on the
123-
command line. The first argument can point to a custom wolfSSL installation
124-
location. A custom install location would match the directory set at wolfSSL
125-
`./configure --prefix=<DIR>`.
151+
The script accepts two optional arguments:
126152

127-
The second argument represents the wolfSSL library name that should be
128-
linked against. This is helpful if a non-standard library name has been
129-
used with wolfSSL, for example the `./configure --with-libsuffix` option
130-
has been used to add a suffix to the wolfSSL library name. Note that to
131-
use this argument, an installation location must be specified via the
132-
first argument.
153+
1. **wolfSSL installation directory** (default: `/usr/local`) - should match
154+
the directory set at wolfSSL `./configure --prefix=<DIR>`.
155+
2. **wolfSSL library name** (default: `wolfssl`) - useful if a non-standard
156+
library name has been used, for example via `./configure --with-libsuffix`.
133157

134158
For example, if wolfSSL was configured with `--with-libsuffix=jsse`, then
135159
this script could be called like so using the default installation
@@ -139,8 +163,7 @@ path of `/usr/local`:
139163
java.sh /usr/local wolfssljsse
140164
```
141165

142-
`java.sh` can use preset `CFLAGS` defines, if set in the environment variable
143-
prior to running the script, for example:
166+
`CFLAGS` can be set in the environment prior to running the script:
144167

145168
```
146169
CFLAGS=-DWOLFJNI_USE_IO_SELECT java.sh
@@ -153,12 +176,11 @@ are already set up to use and consume Maven packages.
153176

154177
wolfJSSE's Maven build configuration is defined in the included `pom.xml`.
155178

156-
First, compile the native JNI shared library (libwolfssljni.so/dylib) same
157-
as above. This will create the native JNI shared library under the `./lib`
158-
directory:
179+
First, compile the native JNI shared library (libwolfssljni.so/dylib). This
180+
will create the native JNI shared library under the `./lib` directory:
159181

160182
```
161-
$ ./java.sh
183+
$ make native
162184
```
163185

164186
Compile the Java sources, where Maven will place the compiled `.class` files
@@ -202,10 +224,10 @@ The local Maven repository installation location will be similar to:
202224
~/.m2/repository/com/wolfssl/wolfssl-jsse/X.X.X-SNAPSHOT/wolfssl-jsse-X.X.X-SNAPSHOT.jar
203225
```
204226

205-
The wolfSSL JNI shared library (`libwolfssljni.so/dylib`) created with the
206-
`java.sh` script will need to be "installed" by being placed on your native
227+
The wolfSSL JNI shared library (`libwolfssljni.so/dylib`) will need to be
228+
"installed" by being placed on your native
207229
library search path. For example, copied into `/usr/local/lib`, `/usr/lib`,
208-
or other location. Alternatively, append the `./libs` directory to your native
230+
or other location. Alternatively, append the `./lib` directory to your native
209231
library search path by exporting `LD_LIBRARY_PATH` (Linux) or
210232
`DYLD_LIBRARY_PATH` (OSX):
211233

@@ -261,15 +283,14 @@ Maven builds support automatic module-info compilation.
261283

262284
```
263285
$ export JAVA_HOME=/path/to/jdk11 # or any JDK 9+
264-
$ ./java.sh
265-
$ ant
286+
$ make build
266287
```
267288

268289
**Using Maven:**
269290

270291
```
271292
$ export JAVA_HOME=/path/to/jdk11 # or any JDK 9+
272-
$ ./java.sh
293+
$ make native
273294
$ mvn package
274295
```
275296

@@ -494,7 +515,8 @@ file descriptors inside Java Socket objects. These native file descriptors
494515
are watched for read and write events with either `select()` or `poll()`.
495516

496517
By default `poll()` will be used, unless `WOLFJNI_USE_IO_SELECT` is defined
497-
or added to CFLAGS when compiling the native JNI sources (see `java.sh`).
518+
or added to CFLAGS when compiling the native JNI sources (e.g.
519+
`make CFLAGS=-DWOLFJNI_USE_IO_SELECT`).
498520
Windows builds will also default to using `select()` since `poll()` is not
499521
available there.
500522

@@ -698,14 +720,14 @@ legacy behavior where SNI is automatically configured from hostname/peer informa
698720
even without explicit SSLParameters configuration. Default value is "false", where
699721
SNI is only set when explicitly configured through SSLParameters.
700722

701-
**wolfssl.skipLibraryLoad (boolean)** - When set to "true", `WolfSSL.loadLibrary()`
723+
**wolfssl.skipLibraryLoad (boolean)** - When set to "true", `wolfSSL.loadLibrary()`
702724
will skip the default `System.loadLibrary()` calls for native wolfSSL and
703725
wolfSSL JNI libraries. This is useful when applications need to load the native
704726
libraries themselves using custom logic, for example when bundling the native
705727
library inside a JAR file and extracting it at runtime. The property must be set
706-
before `WolfSSL.loadLibrary()` is called, either directly or via
728+
before `wolfSSL.loadLibrary()` is called, either directly or via
707729
`WolfSSLProvider()` constructor. Applications can check if library loading was
708-
skipped by calling `WolfSSL.isLibraryLoadSkipped()`.
730+
skipped by calling `wolfSSL.isLibraryLoadSkipped()`.
709731

710732
Setting via command line:
711733

@@ -722,8 +744,8 @@ System.setProperty("wolfssl.skipLibraryLoad", "true");
722744
System.load("/path/to/libwolfssl.so");
723745
System.load("/path/to/libwolfssljni.so");
724746

725-
/* Then use WolfSSL as normal */
726-
WolfSSL.loadLibrary();
747+
/* Then use wolfSSL as normal */
748+
wolfSSL.loadLibrary();
727749
```
728750

729751
If there are other System properties you would like to use with wolfJSSE,

0 commit comments

Comments
 (0)