Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Convert OpenSlide-Java Makefile to Autotools #14

Merged
merged 11 commits into from
Nov 1, 2011
19 changes: 17 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
/aclocal.m4
/autom4te.cache
/bin
/build-aux
/configure
/config.h
/config.h.in
/config.log
/config.status
/libtool
/stamp-h1

.deps
.libs
Makefile
Makefile.in
*.jar
*.so
*.dll
*.la
*.lo
19 changes: 0 additions & 19 deletions Makefile

This file was deleted.

60 changes: 60 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
ACLOCAL_AMFLAGS = -I m4

AM_CFLAGS = -Wall $(JNI_CFLAGS) $(OPENSLIDE_CFLAGS)
AM_CFLAGS += -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
AM_LDFLAGS = -avoid-version -no-undefined -module $(OPENSLIDE_LIBS)

if DLL
# JNI uses stdcall without @
AM_LDFLAGS += -Wl,--kill-at
JNI_LA = openslide-jni.la
JNI_SO = openslide-jni.dll
else
JNI_LA = libopenslide-jni.la
JNI_SO = libopenslide-jni.so
endif

if EMBED_PATH
JNI_EMBED_PATH = $(pkglibdir)/$(JNI_SO)
endif

export JAVA_HOME
export ANT_HOME

pkglib_LTLIBRARIES = $(JNI_LA)
libopenslide_jni_la_SOURCES = openslide-jni.c

pkglib_DATA = openslide.jar
JAVA_SRC = build.xml \
src/edu/cmu/cs/openslide/AssociatedImageMap.java \
src/edu/cmu/cs/openslide/OpenSlideDisposedException.java \
src/edu/cmu/cs/openslide/OpenSlide.java \
src/edu/cmu/cs/openslide/OpenSlideJNI.java \
src/edu/cmu/cs/openslide/TestCLI.java \
src/edu/cmu/cs/openslide/gui/Annotation.java \
src/edu/cmu/cs/openslide/gui/DefaultAnnotation.java \
src/edu/cmu/cs/openslide/gui/DefaultSelectionListModel.java \
src/edu/cmu/cs/openslide/gui/Demo.java \
src/edu/cmu/cs/openslide/gui/OpenSlideView.java \
src/edu/cmu/cs/openslide/gui/SelectionListModel.java \
src/org/openslide/dzi/DeepZoomGenerator.java

openslide.jar: $(JAVA_SRC) config.h
@$(ANT) -f $(srcdir)/build.xml -Dbuilddir=$(abs_builddir) \
-Dopenslide.jni.path=$(JNI_EMBED_PATH)

mostlyclean-local:
@$(ANT) -f $(srcdir)/build.xml -Dbuilddir=$(abs_builddir) clean

install-exec-hook:
chmod -x $(DESTDIR)$(pkglibdir)/$(JNI_SO)
rm -f $(DESTDIR)$(pkglibdir)/$(JNI_LA) \
$(DESTDIR)$(pkglibdir)/$(JNI_SO).a

EXTRA_DIST = \
CHANGELOG.txt \
LICENSE.txt \
README.txt \
TODO.txt \
lgpl-2.1.txt \
$(JAVA_SRC)
45 changes: 45 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
Build requirements
------------------

- JDK
- Apache Ant
- OpenSlide

Building on Linux
-----------------

./configure
make
make install

Cross-compiling for Windows with mingw32
----------------------------------------

You will need the GNU Classpath version of jni.h installed. (On Fedora
this is in the libgcj-devel package.)

PKG_CONFIG=pkg-config \
PKG_CONFIG_PATH=/path/to/cross/compiled/openslide/lib/pkgconfig \
./configure --host=i686-pc-mingw32 --build=$(build-aux/config.guess)
make
make install

Building on Windows
-------------------

Install a JDK, Apache Ant, MinGW, and MSYS. Edit the MSYS fstab file
(e.g. C:\MinGW\msys\1.0\etc\fstab) to mount your JDK and Apache Ant
installations within the MSYS directory tree:

C:\Progra~1\Java\jdk1.6.0_29 /java
C:\ant /ant

You must use 8.3 short file names for path elements that contain spaces.

Then:

./configure --prefix=/path/to/install/dir JAVA_HOME=/java \
ANT_HOME=/ant OPENSLIDE_CFLAGS=-I/path/to/openslide/include \
OPENSLIDE_LIBS="-L/path/to/openslide/lib -lopenslide"
make
make install
33 changes: 33 additions & 0 deletions acinclude.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# FIND_FILE([OUTPUT], [FILE_NAME], [SEARCH_PATHS])
# The paths in SEARCH_PATHS are searched to determine whether they contain
# the file FILE_NAME. If so, OUTPUT is set to the directory containing
# the file. Otherwise, an error is produced.
# ------------------------------------------------------------------------
AC_DEFUN([FIND_FILE], [
AC_MSG_CHECKING([for $2])
$1=
for ac__path in $3
do
if test -r $ac__path/$2 ; then
AC_MSG_RESULT([$ac__path])
$1=$ac__path
break
fi
done
if test z$$1 = z ; then
AC_MSG_RESULT([not found])
AC_MSG_ERROR([cannot find $2 in $3])
fi
])


# JOIN_EACH([OUTPUT], [PATHS], [SUBDIR])
# Append SUBDIR to each of the PATHS and put the result in OUTPUT.
# ----------------------------------------------------------------
AC_DEFUN([JOIN_EACH], [
$1=
for dir in $2
do
$1="$$1 $dir/$3"
done
])
19 changes: 12 additions & 7 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.5"/>
<property name="source" value="1.5"/>
<property name="builddir" value="."/>
<property name="openslide.jni.path" value=""/>
<path id="openslide java.classpath">
<pathelement location="bin"/>
<pathelement location="${builddir}/bin"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<mkdir dir="${builddir}/bin/resources"/>
<copy includeemptydirs="false" todir="${builddir}/bin">
<fileset dir="src" excludes="**/*.launch, **/*.java"/>
</copy>
</target>
<target name="clean">
<delete dir="bin"/>
<delete file="openslide.jar" />
<delete dir="${builddir}/bin"/>
<delete file="${builddir}/openslide.jar" />
</target>
<target depends="clean" name="cleanall"/>
<target depends="build" name="jar">
<jar destfile="openslide.jar" basedir="bin">
<jar destfile="${builddir}/openslide.jar" basedir="${builddir}/bin">
<manifest>
<attribute name="Main-Class" value="edu.cmu.cs.openslide.gui.Demo"/>
</manifest>
Expand All @@ -30,10 +32,13 @@
<target name="build-subprojects"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
<javac debug="true" debuglevel="${debuglevel}" destdir="${builddir}/bin" source="${source}" target="${target}" includeAntRuntime="false">
<src path="src"/>
<classpath refid="openslide java.classpath"/>
</javac>
<propertyfile file="${builddir}/bin/resources/openslide.properties">
<entry key="openslide.jni.path" value="${openslide.jni.path}"/>
</propertyfile>
</target>
<target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects"/>
</project>
106 changes: 106 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.66])
AC_INIT([OpenSlide Java], [0.9.2], [[email protected]])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([openslide-jni.c])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign dist-xz])
AM_SILENT_RULES([yes])
LT_INIT([win32-dll disable-static])

# Checks for programs.

PKG_PROG_PKG_CONFIG()
AC_PROG_CC

# For distribution-packaged Ant, $ANT may not be $ANT_HOME/bin/ant.
# Use and pass through ANT_HOME if we receive it; otherwise, focus on ANT.
AC_ARG_VAR([ANT], [path to ant program])
AC_ARG_VAR([ANT_HOME], [path to ant installation directory])
if test z$ANT = z -a z$ANT_HOME != z ; then
ANT=$ANT_HOME/bin/ant
fi
AC_PATH_PROG([ANT], [ant])
if test z$ANT = z ; then
AC_MSG_ERROR([ant not found])
fi

# Checks for libraries.

PKG_CHECK_MODULES([OPENSLIDE], [openslide])

# Checks for header files.

AC_ARG_VAR([JAVA_HOME], [path to JDK])
AC_ARG_WITH([java], [AS_HELP_STRING([--with-java], [path to JDK])], [],
[with_java="$JAVA_HOME /usr/lib/jvm/java"])
if test $host = $build; then
# Find jni.h
JOIN_EACH([include_paths], [$with_java], [include])
FIND_FILE([jni_h_dir], [jni.h], [$include_paths])
JAVA_HOME=$(dirname $jni_h_dir)
# Find jni_md.h
AS_CASE([$host],
[*-*-linux-gnu], [include_subdir=linux],
[*-*-mingw32], [include_subdir=win32],
[include_subdir=]
)
JOIN_EACH([platform_include_paths], [$include_paths], [$include_subdir])
FIND_FILE([jni_md_h_dir], [jni_md.h],
[$platform_include_paths $include_paths])
JNI_CFLAGS="-I$jni_h_dir -I$jni_md_h_dir"
else
# For cross builds, we don't have the OpenJDK jni_md.h for the target
# platform, so use the GNU Classpath JNI headers in the build system's
# gcj include directory instead. Autoconf doesn't give us a variable
# for the build compiler, which is okay because anything other than
# GCC probably won't support this syntax.
#
# Don't set JAVA_HOME unless it was specified on the command line.
#
# This is terrible.
JNI_CFLAGS=
AC_MSG_CHECKING([for cross jni.h and jni_md.h])
for word in $(gcc - -v -E < /dev/null 2>&1)
do
if test -r "$word/jni.h" -a -r "$word/jni_md.h" ; then
AC_MSG_RESULT([$word])
JNI_CFLAGS="-I$word"
break
fi
done
if test x$JNI_CFLAGS = x ; then
AC_MSG_RESULT([not found])
AC_MSG_ERROR([cannot find JNI headers])
fi
fi
AC_SUBST([JNI_CFLAGS])

# Checks for typedefs, structures, and compiler characteristics.

AC_TYPE_INT64_T
AC_TYPE_UINT32_T

AC_MSG_CHECKING([JNI library name])
if test x$shrext_cmds = x.dll ; then
AC_MSG_RESULT([openslide-jni.dll])
else
AC_MSG_RESULT([libopenslide-jni.so])
fi
AM_CONDITIONAL([DLL], [test x$shrext_cmds = x.dll])

AC_MSG_CHECKING([whether to embed library path in JAR])
if test x$shrext_cmds = x.dll ; then
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([yes])
fi
AM_CONDITIONAL([EMBED_PATH], [test x$shrext_cmds != x.dll])

# Checks for library functions.

AC_CONFIG_FILES([Makefile])
AC_OUTPUT
1 change: 1 addition & 0 deletions m4/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
5 changes: 0 additions & 5 deletions mingw32-cheatsheet.txt

This file was deleted.

29 changes: 28 additions & 1 deletion src/edu/cmu/cs/openslide/OpenSlideJNI.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,39 @@

package edu.cmu.cs.openslide;

import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;

class OpenSlideJNI {
private OpenSlideJNI() {
}

static {
System.loadLibrary("openslide-jni");
String libraryPath = null;

try {
InputStream is = OpenSlideJNI.class.getClassLoader().
getResourceAsStream("resources/openslide.properties");
if (is != null) {
Properties p = new Properties();
p.load(is);
libraryPath = p.getProperty("openslide.jni.path");
if (libraryPath.equals("")) {
libraryPath = null;
}
}
} catch (SecurityException e1) {
e1.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}

if (libraryPath != null) {
System.load(libraryPath);
} else {
System.loadLibrary("openslide-jni");
}
}

native static boolean openslide_can_open(String file);
Expand Down