Skip to content

Commit f4e1e47

Browse files
committed
Loading of native libraries
1 parent 74ce715 commit f4e1e47

7 files changed

Lines changed: 271 additions & 49 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,6 @@ local.properties
5757

5858
# Package Files #
5959
*.jar
60+
*.mf
6061
*.war
6162
*.ear

JavaGUI/jni/makefile

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,55 @@ INC = "$(JAVA_HOME)/include" "$(JAVA_HOME)/include/win32"
88

99
# Detect library extension depending on OS
1010
ifeq ($(OS),Windows_NT)
11-
EXT = .dll
11+
EXT=.dll
12+
OSNAME = WINDOWS
13+
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
14+
ARCHNAME = X64
15+
endif
16+
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
17+
ARCHNAME = X86
18+
endif
1219
else
13-
UNAME_S := $(shell uname -s)
14-
ifeq ($(UNAME_S),Linux)
15-
EXT = .so
16-
endif
20+
UNAME_S := $(shell uname -s)
21+
ifeq ($(UNAME_S),Linux)
22+
EXT=.so
23+
OSNAME = LINUX
24+
endif
25+
ifeq ($(UNAME_S),Darwin)
26+
EXT=.a
27+
OSNAME = OSX
28+
endif
29+
UNAME_P := $(shell uname -p)
30+
ifeq ($(UNAME_P),x86_64)
31+
ARCHNAME = X64
32+
endif
33+
ifneq ($(filter %86,$(UNAME_P)),)
34+
ARCHNAME = X86
35+
endif
36+
ifneq ($(filter arm%,$(UNAME_P)),)
37+
ARCHNAME = ARM
38+
endif
1739
endif
1840

41+
# The folder that will contain the libraries
42+
OUTPUTFOLDER=../lib/$(OSNAME)/$(ARCHNAME)
43+
1944
# We want to build the library
20-
all : ../TSDRLibraryNDK$(EXT)
45+
all : $(OUTPUTFOLDER)/TSDRLibraryNDK$(EXT)
2146

2247
# Linking
23-
../TSDRLibraryNDK$(EXT) : TSDRLibraryNDK.o rebuildtempestsdr
24-
gcc -L../../TempestSDR/bin/ -lTSDRLibrary -Wl,--add-stdcall-alias -shared -o $@ $<
48+
$(OUTPUTFOLDER)/TSDRLibraryNDK$(EXT) : TSDRLibraryNDK.o rebuildtempestsdr $(OUTPUTFOLDER)
49+
gcc -L../../TempestSDR/bin/$(OSNAME)/$(ARCHNAME)/ -lTSDRLibrary -Wl,--add-stdcall-alias -shared -o $@ $<
50+
51+
# Create output dir
52+
$(OUTPUTFOLDER) :
53+
mkdir -p $(OUTPUTFOLDER)
2554

2655
# Rebuild the main library so that we have the most up-to-date version
2756
# The main library is assumed to be two levels below this jni folder
28-
rebuildtempestsdr :
29-
@$(MAKE) -C ../../TempestSDR bin/TSDRLibrary$(EXT)
30-
@cp -f ../../TempestSDR/bin/TSDRLibrary$(EXT) ../TSDRLibrary$(EXT)
57+
rebuildtempestsdr : $(OUTPUTFOLDER)
58+
@$(MAKE) -C ../../TempestSDR all
59+
@cp -f ../../TempestSDR/bin/$(OSNAME)/$(ARCHNAME)/TSDRLibrary$(EXT) $(OUTPUTFOLDER)/TSDRLibrary$(EXT)
3160

3261
# Compile the sources to obj files
3362
TSDRLibraryNDK.o : TSDRLibraryNDK.c TSDRLibraryNDK.h include/TSDRLibrary.h

JavaGUI/makefile

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,39 @@ CLASSFILES:=$(patsubst %,bin/%,$(addsuffix .class,$(basename $(foreach jfile,$(J
1919

2020
# Detect shared library extension based on OS
2121
ifeq ($(OS),Windows_NT)
22-
EXT = .dll
22+
EXT=.dll
23+
OSNAME = WINDOWS
24+
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
25+
ARCHNAME = X64
26+
endif
27+
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
28+
ARCHNAME = X86
29+
endif
2330
else
2431
UNAME_S := $(shell uname -s)
2532
ifeq ($(UNAME_S),Linux)
26-
EXT = .so
33+
EXT=.so
34+
OSNAME = LINUX
35+
endif
36+
ifeq ($(UNAME_S),Darwin)
37+
EXT=.a
38+
OSNAME = OSX
39+
endif
40+
UNAME_P := $(shell uname -p)
41+
ifeq ($(UNAME_P),x86_64)
42+
ARCHNAME = X64
43+
endif
44+
ifneq ($(filter %86,$(UNAME_P)),)
45+
ARCHNAME = X86
46+
endif
47+
ifneq ($(filter arm%,$(UNAME_P)),)
48+
ARCHNAME = ARM
2749
endif
2850
endif
2951

52+
# The folder that will contain the libraries
53+
OUTPUTFOLDER=lib/$(OSNAME)/$(ARCHNAME)
54+
3055
# Build the file names of the plugin files
3156
PLUGINS_FILES=$(addsuffix $(EXT),$(PLUGINS))
3257

@@ -35,7 +60,11 @@ PLUGINS_DIRS=$(addprefix ../,$(addsuffix /,$(PLUGINS)))
3560

3661
# When compiling from command line with all
3762
# make sure we compile both jni and java files
38-
all : jnilib java
63+
all : jnilib jar
64+
65+
# Package compiled files into a runnable jar
66+
jar : java
67+
jar cvfe JTempestSDR.jar martin.tempest.Main lib -C bin .
3968

4069
# The compilation of the java classes from command line
4170
# depends on the class files (we want to produce them)
@@ -52,9 +81,13 @@ jnilib : plugins
5281
@$(MAKE) -C jni/ all JAVA_HOME=$(JAVA_HOME)
5382

5483
# Recompile each plugin and copy its shared library over to the java directory
55-
plugins :
56-
$(foreach pdir, $(PLUGINS_DIRS), $(MAKE) -C $(pdir) all; cp -f $(pdir)/bin/*$(EXT) .;)
84+
plugins : $(OUTPUTFOLDER)
85+
$(foreach pdir, $(PLUGINS_DIRS), $(MAKE) -C $(pdir) all; cp -f $(pdir)/bin/$(OSNAME)/$(ARCHNAME)/*$(EXT) $(OUTPUTFOLDER)/;)
5786

87+
# Create output dir
88+
$(OUTPUTFOLDER) :
89+
mkdir -p $(OUTPUTFOLDER)
90+
5891
# Clean the jni stuff
5992
cleanjni: cleanplugins
6093
@$(MAKE) -C jni/ clean
@@ -65,4 +98,4 @@ cleanplugins:
6598

6699
# Clean the java classes as well
67100
clean : cleanjni
68-
rm -rf bin/
101+
rm -rf bin/ JTempestSDR.jar

JavaGUI/src/martin/tempest/Main.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
public class Main {
66

77
public static void main(String[] args) {
8-
TSDRLibrary sdrlib = new TSDRLibrary();
9-
sdrlib.test();
8+
try {
9+
TSDRLibrary sdrlib = new TSDRLibrary();
10+
sdrlib.test();
11+
} catch(Exception e) {
12+
System.out.println("Cannot load! Reason: "+e.getLocalizedMessage());
13+
}
1014
}
1115

1216
}
Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,116 @@
11
package martin.tempest.core;
22

3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.io.FileNotFoundException;
6+
import java.io.FileOutputStream;
7+
import java.io.IOException;
8+
import java.io.InputStream;
9+
10+
/**
11+
* This is a Java wrapper library for TSDRLibrary
12+
*
13+
* @author Martin
14+
*
15+
*/
316
public class TSDRLibrary {
417

18+
// If the binaries weren't loaded, this will go off
19+
private static Exception m_e = null;
20+
21+
/**
22+
* Extracts a library to a temporary path and prays for the OS to delete it after the app closes.
23+
* @param name
24+
* @return
25+
* @throws IOException
26+
*/
27+
static final File extractLibrary(final String name) throws IOException {
28+
final String rawOSNAME = System.getProperty("os.name").toLowerCase();
29+
final String rawARCHNAME = System.getProperty("os.arch").toLowerCase();
30+
31+
String OSNAME = null, EXT = null, ARCHNAME = null;
32+
33+
if (rawOSNAME.contains("win")) {
34+
OSNAME = "WINDOWS";
35+
EXT = ".dll";
36+
} else if (rawOSNAME.contains("nix") || rawOSNAME.contains("nux") || rawOSNAME.contains("aix")) {
37+
OSNAME = "LINUX";
38+
EXT = ".so";
39+
} else if (rawOSNAME.contains("mac")) {
40+
OSNAME = "MAC";
41+
EXT = ".a";
42+
}
43+
44+
if (rawARCHNAME.contains("arm"))
45+
ARCHNAME = "ARM";
46+
else if (rawARCHNAME.contains("64"))
47+
ARCHNAME = "X64";
48+
else
49+
ARCHNAME = "X86";
50+
51+
if (OSNAME == null || EXT == null || ARCHNAME == null)
52+
throw new RuntimeException("Your OS or CPU is not yet supported, sorry.");
53+
54+
final String relative_path = "lib/"+OSNAME+"/"+ARCHNAME+"/"+name+EXT;
55+
56+
InputStream in = TSDRLibrary.class.getClassLoader().getResourceAsStream(relative_path);
57+
58+
if (in == null)
59+
try {
60+
in = new FileInputStream(relative_path);
61+
} catch (FileNotFoundException e) {}
62+
63+
if (in == null) throw new RuntimeException("The library has not been compiled for your OS/Architecture yet ("+OSNAME+"/"+ARCHNAME+").");
64+
65+
66+
byte[] buffer = new byte[in.available()];
67+
68+
int read = -1;
69+
final File temp = new File(System.getProperty("java.io.tmpdir"), name+EXT);
70+
temp.deleteOnExit();
71+
final FileOutputStream fos = new FileOutputStream(temp);
72+
73+
while((read = in.read(buffer)) != -1) {
74+
fos.write(buffer, 0, read);
75+
}
76+
fos.close();
77+
in.close();
78+
79+
return temp;
80+
}
81+
82+
/**
83+
* Loads a dll library on the fly based on OS and ARCH. Do not supply extension.
84+
* @param name
85+
* @throws IOException
86+
*/
87+
static final void loadLibrary(final String name) throws IOException {
88+
try {
89+
// try traditional method
90+
System.loadLibrary(name);
91+
} catch (Throwable t) {
92+
final File library = extractLibrary(name);
93+
System.load(library.getAbsolutePath());
94+
library.delete();
95+
}
96+
}
97+
98+
/**
99+
* Load the libraries statically and detect errors
100+
*/
5101
static {
6-
System.loadLibrary("TSDRLibraryNDK");
102+
try {
103+
loadLibrary("TSDRLibrary");
104+
loadLibrary("TSDRLibraryNDK");
105+
extractLibrary("TSDRPlugin_RawFile");
106+
} catch (IOException e) {
107+
m_e = e;
108+
}
7109
}
8110

111+
public TSDRLibrary() throws Exception {
112+
if (m_e != null) throw m_e;
113+
}
114+
9115
public native void test();
10116
}

TSDRPlugin_RawFile/makefile

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,47 @@ DEPS=TSDRPlugin.h
1111
# Where the TSDRPlugin.h of the TempestSDR library resides (so it will be copied over)
1212
HEADLOCATION=../TempestSDR/src/include/
1313

14-
# If you need a different directory structure. Don't change that unless you really want to.
15-
SOURCEFOLDER=src
16-
OUTPUTFOLDER=bin
17-
OBJFOLDER=bin/obj
18-
19-
# Calculate the path to dependencies
20-
_OBJS = $(patsubst %,$(OBJFOLDER)/%,$(OBJS))
21-
_DEPS = $(patsubst %,$(SOURCEFOLDER)/%,$(DEPS))
22-
2314
# Discover the library extension for each OS
2415
ifeq ($(OS),Windows_NT)
25-
EXT = .dll
16+
EXT=.dll
17+
OSNAME = WINDOWS
18+
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
19+
ARCHNAME = X64
20+
endif
21+
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
22+
ARCHNAME = X86
23+
endif
2624
else
2725
UNAME_S := $(shell uname -s)
2826
ifeq ($(UNAME_S),Linux)
29-
EXT = .so
27+
EXT=.so
28+
OSNAME = LINUX
29+
endif
30+
ifeq ($(UNAME_S),Darwin)
31+
EXT=.a
32+
OSNAME = OSX
33+
endif
34+
UNAME_P := $(shell uname -p)
35+
ifeq ($(UNAME_P),x86_64)
36+
ARCHNAME = X64
37+
endif
38+
ifneq ($(filter %86,$(UNAME_P)),)
39+
ARCHNAME = X86
40+
endif
41+
ifneq ($(filter arm%,$(UNAME_P)),)
42+
ARCHNAME = ARM
3043
endif
3144
endif
3245

46+
# If you need a different directory structure. Don't change that unless you really want to.
47+
SOURCEFOLDER=src
48+
OUTPUTFOLDER=bin/$(OSNAME)/$(ARCHNAME)
49+
OBJFOLDER=obj
50+
51+
# Calculate the path to dependencies
52+
_OBJS = $(patsubst %,$(OBJFOLDER)/%,$(OBJS))
53+
_DEPS = $(patsubst %,$(SOURCEFOLDER)/%,$(DEPS))
54+
3355
# Generate the library
3456
all : $(OUTPUTFOLDER)/$(PLUGNAME)$(EXT)
3557

@@ -51,4 +73,4 @@ $(OBJFOLDER)/%.o : $(SOURCEFOLDER)/%.c $(_DEPS)
5173

5274
# Clean artifacts
5375
clean :
54-
rm -f $(OBJFOLDER)/*.o $(OUTPUTFOLDER)/$(PLUGNAME)$(EXT)
76+
rm -f $(OBJFOLDER)/*.o $(OUTPUTFOLDER)/*.*

0 commit comments

Comments
 (0)