[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] Integrate javahl into build system

From: Justin Erenkrantz <justin_at_erenkrantz.com>
Date: 2003-12-26 12:24:59 CET

--On Friday, December 26, 2003 9:55 AM +0100 Patrick Mayweg <mayweg@qint.de>
wrote:

> Thanks for the work. I will have a look over the next days. As far as I can
> see this patch only covers building on non Windows systems. Am i right?

Yes. But, someone should be able to add the 'right' stuff to the gen_win.py
and friends to build the MSVC files. I have no knowledge of how to do that
though.

I do have a bunch of fixes to these patches since I last posted (see below).
It now installs correctly. Since it doesn't break the old build system for
javahl and shouldn't be too harmful to the 'core' build system, I'm planning
on checking it into trunk later this weekend after I run some more tests and
cleanups unless anyone has objections to fixing it up in-tree.

Note that the biggest change from the current javahl build system is that the
javahl C/C++ library is now called libsvn_javahl-1 - this is to match the
versioning of the rest of the core SVN libraries which have their major number
as part of the file name. So, keeping with that, SVNClient.java needs to be
changed to match accordingly. -- justin

Index: Makefile.in
===================================================================
--- Makefile.in (revision 8069)
+++ Makefile.in (working copy)
@@ -69,6 +69,10 @@
 swig_javadir = @libdir@/svn-java
 swig_pldir = @libdir@/svn-perl

+javahl_javadir = @libdir@/svn-javahl
+javahl_javahdir = @libdir@/svn-javahl/include
+javahl_libdir = @libdir@
+
 ### should search for these...
 MAKEINFO = @MAKEINFO@
 TEXI2DVI = texi2dvi
@@ -77,6 +81,7 @@

 CC = @CC@
+CXX = @CXX@
 EXEEXT = @EXEEXT@

 SHELL = @SHELL@
@@ -117,6 +122,7 @@
 LDFLAGS = @LDFLAGS@ $(EXTRA_LDFLAGS)

 COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDES)
+COMPILE_CXX = $(CXX) $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS) $(INCLUDES)
 LT_COMPILE = $(LIBTOOL) $(LTFLAGS) --mode=compile $(COMPILE)

 # special compilation for files destined for mod_dav_svn
@@ -127,6 +133,11 @@
 COMPILE_SWIG_JAVA = $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) $(CPPFLAGS)
$(CFLAGS) $(SWIG_JAVA_INCLUDES) $(INCLUDES) -o $@ -c
 COMPILE_SWIG_PL = $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) $(CPPFLAGS)
$(CFLAGS) $(SWIG_PL_INCLUDES) $(INCLUDES) -o $@ -c

+# special compilation for files destined for javahl (i.e. C++)
+COMPILE_JAVAHL_CXX = $(LIBTOOL) $(LTFLAGS) --mode=compile $(COMPILE_CXX)
$(SWIG_JAVA_INCLUDES) -o $@ -c
+COMPILE_JAVAHL_JAVAC = $(JAVAC)
+COMPILE_JAVAHL_JAVAH = $(JAVAH)
+
 LINK = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LT_LDFLAGS) $(CFLAGS)
$(LDFLAGS) -rpath $(libdir)

 # special link rule for mod_dav_svn
@@ -148,6 +159,7 @@
 LINK_JAVA_WRAPPER = $(LIBTOOL) $(LTFLAGS) --mode=link $(SWIG_JAVA_LINK)
$(SWIG_LDFLAGS) -rpath $(swig_javadir) -avoid-version -module
 LINK_PL_WRAPPER = $(LIBTOOL) $(LTFLAGS) --mode=link $(SWIG_PL_LINK)
$(SWIG_LDFLAGS) -rpath $(swig_pldir) -avoid-version -module

+LINK_JAVAHL_CXX = $(LIBTOOL) $(LTFLAGS) --mode=link $(CXX) $(LT_LDFLAGS)
$(CFLAGS) $(LDFLAGS) -rpath $(libdir)

 INSTALL = @INSTALL@
 INSTALL_LIB = $(LIBTOOL) --mode=install $(INSTALL)
@@ -169,6 +181,8 @@
 INSTALL_SWIG_PL = $(INSTALL_LIB)
 INSTALL_SWIG_PL_LIB = $(INSTALL_LIB)

+INSTALL_JAVAHL_LIB = $(INSTALL_LIB)
+
 # additional installation rules for the SWIG wrappers
 INSTALL_EXTRA_SWIG_PY=\
    $(top_srcdir)/build/copy-swig-py.sh "$(PYTHON)" "$(INSTALL_DATA)"
"${SWIG_SRC_DIR}/python" "$(DESTDIR)$(swig_pydir)" ; \
@@ -200,12 +214,17 @@
         $(JAR) cf $(SWIG_JAVA_DIR)/build/svn-api.jar -C $(SWIG_JAVA_DIR)/build org; \
         $(INSTALL_DATA) $(SWIG_JAVA_DIR)/build/svn-api.jar $(DESTDIR)$(swig_javadir);

+INSTALL_EXTRA_JAVAHL_JAVA=\
+ $(JAR) cf subversion/bindings/java/javahl/svn-javahl.jar -C
subversion/bindings/java/javahl/classes org; \
+ $(INSTALL_DATA) subversion/bindings/java/javahl/svn-javahl.jar
$(DESTDIR)$(javahl_javadir);
+
 APXS = @APXS@

 PYTHON = @PYTHON@

 JDK = @JDK@
 JAVAC = @JAVAC@
+JAVAH = @JAVAH@
 JAR = @JAR@

 ECHO_C = @ECHO_C@
Index: build.conf
===================================================================
--- build.conf (revision 8069)
+++ build.conf (working copy)
@@ -338,6 +338,41 @@

 # ----------------------------------------------------------------------------
 #
+# JavaHL targets
+#
+[javahl-java]
+type = java
+path = subversion/bindings/java/javahl/src/org/tigris/subversion/javahl
+sources = *.java
+install = javahl-java
+link-cmd = $(COMPILE_JAVAHL_JAVAC)
+classes = subversion/bindings/java/javahl/classes
+
+[javahl-javah]
+type = javah
+path = subversion/bindings/java/javahl/src/org/tigris/subversion/javahl
+classes = subversion/bindings/java/javahl/classes
+headers = subversion/bindings/java/javahl/include
+package = org.tigris.subversion.javahl
+extra-classes = Notify\$$Action Notify\$$Status Revision\$$DateSpec
Revision\$$Kind Revision\$$Number SVNClient\$$LogLevel Status\$$Kind
+sources = *.java
+install = javahl-javah
+link-cmd = $(COMPILE_JAVAHL_JAVAH)
+
+[libsvnjavahl]
+type = lib
+path = subversion/bindings/java/javahl/native
+#libs = javahl-javah aprutil apriconv apr
+libs = libsvn_client libsvn_wc libsvn_ra libsvn_delta libsvn_subr
+ aprutil apriconv apr neon
+sources = *.cpp *.c
+install = javahl-lib
+# need special build rule to include -I$(JDK)/include/jni.h
+compile-cmd = $(COMPILE_JAVAHL_CXX)
+link-cmd = $(LINK_JAVAHL_CXX)
+
+# ----------------------------------------------------------------------------
+#
 # TESTING TARGETS
 #

Index: configure.in
===================================================================
--- configure.in (revision 8069)
+++ configure.in (working copy)
@@ -509,6 +509,20 @@
 AC_SUBST(SVN_RA_LIB_LINK)

+dnl Possibly compile JavaHL (experimental)
+do_javahl_build=no
+AC_ARG_ENABLE(javahl,
+ AC_HELP_STRING([--enable-javahl],
+ [Enable compilation of Java high-level bindings (requires C++)]),
+ [ if test "$enableval" = "yes" ; then
+ do_javahl_build="yes"
+ fi
+ ])
+
+if test "$do_javahl_build" = "yes"; then
+ AC_PROG_CXX
+fi
+
 dnl Pass some config data ----------------------------

 AC_SUBST(abs_builddir)
Index: build/ac-macros/java.m4
===================================================================
--- build/ac-macros/java.m4 (revision 8069)
+++ build/ac-macros/java.m4 (working copy)
@@ -50,12 +50,30 @@
   fi
   AC_MSG_RESULT([$JDK_SUITABLE])

- JAVAC='$(JDK)/bin/javac'
+ JAVA_BIN='$(JDK)/bin'
+ if test -f "$JDK/include/jni.h"; then
+ JNI_INCLUDES="$JDK/include"
+ fi
+
+ dnl Correct for Darwin's odd JVM layout. Ideally, we should use realpath,
+ dnl but Darwin doesn't have that utility. /usr/bin/java is a symlink into
+ dnl /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Commands
+ os_arch=`uname`
+ if test "$JDK_SUITABLE" = "yes" -a "$JDK" = "/usr" -a "$os_arch" = "Darwin"
-a -d "/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK"; then
+ JDK="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK"
+ JAVA_BIN='$(JDK)/Commands'
+ JNI_INCLUDES="$JDK/Headers"
+ fi
+
+ JAVAC="$JAVA_BIN/javac"
   # TODO: Test for Jikes, which should be preferred (for speed) if available
- JAR='$(JDK)/bin/jar'
+ JAVAH="$JAVA_BIN/javah"
+ JAR="$JAVA_BIN/jar"

   dnl We use JDK in both the swig.m4 macros and the Makefile
   AC_SUBST(JDK)
   AC_SUBST(JAVAC)
+ AC_SUBST(JAVAH)
   AC_SUBST(JAR)
+ AC_SUBST(JNI_INCLUDES)
 ])
Index: build/ac-macros/swig.m4
===================================================================
--- build/ac-macros/swig.m4 (revision 8069)
+++ build/ac-macros/swig.m4 (working copy)
@@ -100,8 +100,8 @@
     fi

     if test "$JDK" != "none" -a "$SWIG_SUITABLE" = "yes"; then
- SWIG_JAVA_INCLUDES='-I$(JDK)/include'
- list="`find "$JDK/include" -type d -print`"
+ SWIG_JAVA_INCLUDES="-I$JNI_INCLUDES"
+ list="`find "$JNI_INCLUDES" -type d -print`"
       for dir in $list; do
         SWIG_JAVA_INCLUDES="$SWIG_JAVA_INCLUDES -I$dir"
       done
Index: build/generator/gen_base.py
===================================================================
--- build/generator/gen_base.py (revision 8069)
+++ build/generator/gen_base.py (working copy)
@@ -132,6 +132,11 @@
               self.graph.add(DT_SWIG_C, sources[0], include_deps[short][0])
         continue

+ if isinstance(sources[0], ObjectFile) or \
+ isinstance(sources[0], HeaderFile):
+ if sources[0].source_generated == 1:
+ continue
+
       hdrs = [ ]
       for short in _find_includes(sources[0].filename, include_deps):
         self.graph.add(DT_OBJECT, objname, include_deps[short][0])
@@ -249,6 +254,7 @@
   def __init__(self, filename, compile_cmd = None):
     DependencyNode.__init__(self, filename)
     self.compile_cmd = compile_cmd
+ self.source_generated = 0

 class SWIGObject(ObjectFile):
   def __init__(self, filename, lang):
@@ -259,6 +265,12 @@
     self.compile_cmd = '$(COMPILE_%s_WRAPPER)' %
string.upper(self.lang_abbrev)
     self.source_generated = 1

+class HeaderFile(DependencyNode):
+ def __init__(self, filename, classname = None, compile_cmd = None):
+ DependencyNode.__init__(self, filename)
+ self.classname = classname
+ self.compile_cmd = compile_cmd
+
 class SourceFile(DependencyNode):
   def __init__(self, filename, reldir):
     DependencyNode.__init__(self, filename)
@@ -337,10 +349,8 @@
     self.install = options.get('install')
     self.compile_cmd = options.get('compile-cmd')
     self.sources = options.get('sources', '*.c')
+ self.link_cmd = options.get('link-cmd', '$(LINK)')

- ### hmm. this is Makefile-specific
- self.link_cmd = '$(LINK)'
-
     self.external_lib = options.get('external-lib')
     self.external_project = options.get('external-project')
     self.msvc_libs = string.split(options.get('msvc-libs', ''))
@@ -358,11 +368,13 @@
     sources.sort()

     for src, reldir in sources:
- if src[-2:] != '.c':
+ if src[-2:] == '.c':
+ objname = src[:-2] + self.objext
+ elif src[-4:] == '.cpp':
+ objname = src[:-4] + self.objext
+ else:
         raise GenError('ERROR: unknown file extension on ' + src)

- objname = src[:-2] + self.objext
-
       ofile = ObjectFile(objname, self.compile_cmd)

       # object depends upon source
@@ -568,6 +580,132 @@
     TargetProject.__init__(self, name, options, cfg, extmap)
     self.lang = options.get('lang')

+class TargetJava(TargetLib):
+ def __init__(self, name, options, cfg, extmap):
+ TargetLib.__init__(self, name, options, cfg, extmap)
+ self.link_cmd = options.get('link-cmd')
+ self.deps = [ ]
+ self.filename = ''
+
+class TargetJavaHeaders(TargetJava):
+ def __init__(self, name, options, cfg, extmap):
+ TargetJava.__init__(self, name, options, cfg, extmap)
+ self.objext = '.class'
+ self.javah_objext = '.h'
+ self.headers = options.get('headers')
+ self.classes = options.get('classes')
+ self.package = options.get('package')
+ self.extra_classes = string.split(options.get('extra-classes'))
+ self.output_dir = self.headers
+
+ def add_dependencies(self, graph, cfg, extmap):
+ sources = _collect_paths(self.sources, self.path)
+
+ for src, reldir in sources:
+ if src[-5:] != '.java':
+ raise GenError('ERROR: unknown file extension on ' + src)
+
+ class_path = os.path.split(src[:-5])
+
+ class_header = os.path.join(self.headers, class_path[1] + '.h')
+ class_pkg_list = string.split(self.package, '.')
+ class_pkg = ''
+ for dir in class_pkg_list:
+ class_pkg = os.path.join(class_pkg, dir)
+ class_file = ObjectFile(os.path.join(self.classes, class_pkg,
+ class_path[1] + self.objext))
+ class_file.source_generated = 1
+ hfile = HeaderFile(class_header, self.package + '.' + class_path[1],
+ self.compile_cmd)
+ hfile.source_generated = 1
+ graph.add(DT_OBJECT, hfile, class_file)
+ self.deps.append(hfile)
+
+ # target (a linked item) depends upon object
+ graph.add(DT_LINK, self.name, hfile)
+
+ for extra in self.extra_classes:
+ hfile = HeaderFile('', self.package + '.' + extra)
+ hfile.source_generated = 1
+ self.deps.append(hfile)
+
+ # collect all the paths where stuff might get built
+ ### we should collect this from the dependency nodes rather than
+ ### the sources. "what dir are you going to put yourself into?"
+ graph.add(DT_LIST, LT_TARGET_DIRS, self.path)
+ graph.add(DT_LIST, LT_TARGET_DIRS, self.classes)
+ graph.add(DT_LIST, LT_TARGET_DIRS, self.headers)
+ for pattern in string.split(self.sources):
+ idx = string.rfind(pattern, '/')
+ if idx != -1:
+ ### hmm. probably shouldn't be os.path.join() right here
+ ### (at this point in the control flow; defer to output)
+ graph.add(DT_LIST, LT_TARGET_DIRS, os.path.join(self.path,
+ pattern[:idx]))
+
+ graph.add(DT_INSTALL, self.name, self)
+
+
+ def get_dep_targets(self, target):
+ return [ self.target ]
+
+class TargetJavaClasses(TargetJava):
+ def __init__(self, name, options, cfg, extmap):
+ TargetJava.__init__(self, name, options, cfg, extmap)
+ self.objext = '.class'
+ self.lang = 'java'
+ self.classes = options.get('classes')
+ self.output_dir = self.classes
+
+ def add_dependencies(self, graph, cfg, extmap):
+ sources = _collect_paths(self.sources, self.path)
+
+ for src, reldir in sources:
+ if src[-5:] == '.java':
+ objname = src[:-5] + self.objext
+ else:
+ raise GenError('ERROR: unknown file extension on ' + src)
+
+ ofile = ObjectFile(objname, self.compile_cmd)
+ sfile = SourceFile(src, reldir)
+
+ # object depends upon source
+ graph.add(DT_OBJECT, ofile, sfile)
+ self.deps.append(sfile)
+
+ # target (a linked item) depends upon object
+ graph.add(DT_LINK, self.name, ofile)
+
+ # collect all the paths where stuff might get built
+ ### we should collect this from the dependency nodes rather than
+ ### the sources. "what dir are you going to put yourself into?"
+ graph.add(DT_LIST, LT_TARGET_DIRS, self.path)
+ graph.add(DT_LIST, LT_TARGET_DIRS, self.classes)
+ for pattern in string.split(self.sources):
+ idx = string.rfind(pattern, '/')
+ if idx != -1:
+ ### hmm. probably shouldn't be os.path.join() right here
+ ### (at this point in the control flow; defer to output)
+ graph.add(DT_LIST, LT_TARGET_DIRS, os.path.join(self.path,
+ pattern[:idx]))
+
+ graph.add(DT_INSTALL, self.name, self)
+
+ class Section(TargetLib.Section):
+ def create_targets(self, graph, name, cfg, extmap):
+ self.targets = { }
+ target = self.target_class(name, self.options, cfg, extmap)
+ target.add_dependencies(graph, cfg, extmap)
+ self.targets = target
+
+ def get_targets(self):
+ return self.targets.values()
+
+ def get_dep_targets(self, target):
+ target = self.targets
+ return target and [target] or [ ]
+
+
 _build_types = {
   'exe' : TargetExe,
   'script' : TargetScript,
@@ -580,6 +718,8 @@
   'swig_project' : TargetSWIGProject,
   'ra-module': TargetRaModule,
   'apache-mod': TargetApacheMod,
+ 'javah' : TargetJavaHeaders,
+ 'java' : TargetJavaClasses,
   }

Index: build/generator/gen_make.py
===================================================================
--- build/generator/gen_make.py (revision 8069)
+++ build/generator/gen_make.py (working copy)
@@ -60,6 +60,9 @@
         elif isinstance(source, gen_base.ObjectFile):
           # link in the object file
           objects.append(source.filename)
+ elif isinstance(source, gen_base.HeaderFile):
+ # skip the header files.
+ pass
         else:
           ### we don't know what this is, so we don't know what to do with it
           raise UnknownDependency
@@ -67,21 +70,42 @@
       targ_varname = string.replace(target, '-', '_')
       objnames = string.join(gen_base._strip_path(path, objects))

- self.ofile.write(
- '%s_DEPS = %s %s\n'
- '%s_OBJECTS = %s\n'
- '%s: $(%s_DEPS)\n'
- '\tcd %s && %s -o %s $(%s_OBJECTS) %s $(LIBS)\n\n'
- % (targ_varname, target_ob.add_deps, string.join(objects + deps),
+ if isinstance(target_ob, gen_base.TargetJava):
+ self.ofile.write(
+ '%s_DEPS = %s %s\n'
+ '%s: $(%s_DEPS)\n'
+ '\t%s -d %s '
+ % (targ_varname, target_ob.add_deps, string.join(objects + deps),

- targ_varname, objnames,
+ target_ob.name, targ_varname,
+ target_ob.link_cmd, target_ob.output_dir))
+ if isinstance(target_ob, gen_base.TargetJavaHeaders):
+ self.ofile.write('-classpath %s ' % target_ob.classes);
+ for dep in target_ob.deps:
+ if isinstance(dep, gen_base.SourceFile):
+ self.ofile.write('%s ' % os.path.join('$(abs_srcdir)',
dep.filename))
+ elif isinstance(dep, gen_base.HeaderFile):
+ self.ofile.write('%s ' % dep.classname)
+ else:
+ print type(dep)
+ raise UnknownDependency
+ self.ofile.write('\n\n')
+ else:
+ self.ofile.write(
+ '%s_DEPS = %s %s\n'
+ '%s_OBJECTS = %s\n'
+ '%s: $(%s_DEPS)\n'
+ '\tcd %s && %s -o %s $(%s_OBJECTS) %s $(LIBS)\n\n'
+ % (targ_varname, target_ob.add_deps, string.join(objects + deps),

- target_ob.filename, targ_varname,
+ targ_varname, objnames,

- path, target_ob.link_cmd, os.path.basename(target_ob.filename),
- targ_varname, string.join(gen_base.unique(libs)))
- )
+ target_ob.filename, targ_varname,

+ path, target_ob.link_cmd, os.path.basename(target_ob.filename),
+ targ_varname, string.join(gen_base.unique(libs)))
+ )
+
     # for each install group, write a rule to install its outputs
     for itype, i_targets in self.graph.get_deps(gen_base.DT_INSTALL):
       outputs = [ ]
@@ -161,6 +185,8 @@
                          '\t$(MKDIR) $(DESTDIR)$(%sdir)\n'
                          % (area, string.join(files), area_var))
         for file in files:
+ if file == '':
+ continue
           # cd to dirname before install to work around libtool 1.4.2 bug.
           dirname, fname = os.path.split(file)
           self.ofile.write('\tcd %s ; $(INSTALL_%s) %s $(DESTDIR)%s\n'
@@ -169,7 +195,8 @@
                               fname,
                               os.path.join('$(%sdir)' % area_var, fname)))
         ### we should turn AREA into an object, then test it instead of this
- if area[:5] == 'swig-' and area[-4:] != '-lib':
+ if area[:5] == 'swig-' and area[-4:] != '-lib' or \
+ area[:7] == 'javahl-':
           self.ofile.write('\t$(INSTALL_EXTRA_%s)\n' % upper_var)
         self.ofile.write('\n')

@@ -185,7 +212,8 @@

     self.ofile.write('\n# handy shortcut targets\n')
     for target in self.graph.get_all_sources(gen_base.DT_INSTALL):
- if not isinstance(target, gen_base.TargetScript):
+ if not isinstance(target, gen_base.TargetScript) and \
+ not isinstance(target, gen_base.TargetJava):
         self.ofile.write('%s: %s\n' % (target.name, target.filename))
     self.ofile.write('\n')

Index:
subversion/bindings/java/javahl/src/org/tigris/subversion/javahl/SVNClient.java
===================================================================
---
subversion/bindings/java/javahl/src/org/tigris/subversion/javahl/SVNClient.jav
a (revision 8069)
+++
subversion/bindings/java/javahl/src/org/tigris/subversion/javahl/SVNClient.jav
a (working copy)
@@ -31,7 +31,7 @@
      */
     static
     {
- System.loadLibrary("svnjavahl");
+ System.loadLibrary("svnjavahl-1");
     }

     /**

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Dec 26 12:25:35 2003

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.