Travis Shirk writes:
> Hello All,
>
> This post does not have anything to do with Linux, but some of you
> may be able to help since you're Unix users.
>
> ---------------
>
> I'm having some problems using CVS with a pretty large Java API. The problem
> is pretty basic, I want my CVS repository to contain only java source files.
> This is necessary because (1) I don't want CVS to try and merge .class
> files and (2) people working with the repository should need to do a cvs add
> on only the source file and not the new .class file. My problem is
> with dependencies. Many of the classes depend on other classes that
> may not have been created yet in the 'make all' build process. I've played
> around with javac -depend but I don't think it likes how I organize
> my source environment. I have all .java files under a src directory
> in each subpackage directory. So if I have a package called foo.bar
> the directory hierarchy would look like this:
Your problem is not with CVS. It is with understanding Makefiles,
packages and the various development tools.
You clearly want just the .java source files under CVS source control.
This is eminently reasonable.
You also do not want to use the default behavior of having source
files and class files in the same directory. This is also reasonable.
How you implement your makefiles to realize your packaging structure,
of course, depends on your design.
I won't solve your problem, but I will illustrate how I solved a
similar problem.
Let's say I have an app named App1 which I want to release as
`com.pajato.App1' with source App1.java which uses two subpackages:
com.pajato.util and com.pajato.database.
I choose to put my class files in a separate directory tree from the
sources. Let's say I use a directory hierarchy of:
.../App1
/classes
/com/pajato
/com/pajato/util
/com/pajato/database
/sources
/com/pajato
/com/pajato/util
/com/pajato/database
where I do my build's in the App1 directory. My makefile will look something like:
ROOT_CLASSDIR = classes
ROOT_SOURCEDIR = sources
APP1_SOURCES = App1.java Class1.java Class2.java ... ClassN.java
APP1_CLASSES = $(ASC_SOURCES:.java=.class)
APP1_PACKAGEDIR = com/pajato
APP1_SOURCEDIR = $(ROOT_SOURCEDIR)/$(APP1_PACKAGEDIR)
APP1_CLASSDIR = $(ROOT_CLASSDIR)/$(APP1_PACKAGEDIR)
UTIL_SOURCES = Util.java Util1.java Util2.java ... UtilN.java
UTIL_CLASSES = $(UTIL_SOURCES:.java=.class)
UTIL_PACKAGEDIR = com/pajato/util
UTIL_SOURCEDIR = $(ROOT_SOURCEDIR)/$(UTIL_PACKAGEDIR)
UTIL_CLASSDIR = $(ROOT_CLASSDIR)/$(UTIL_PACKAGEDIR)
DATABASE_SOURCES = Database.java Database1.java Database2.java ... DatabaseN.java
DATABASE_CLASSES = $(DATABASE_SOURCES:.java=.class)
DATABASE_PACKAGEDIR = com/pajato/database
DATABASE_SOURCEDIR = $(ROOT_SOURCEDIR)/$(DATABASE_PACKAGEDIR)
DATABASE_CLASSDIR = $(ROOT_CLASSDIR)/$(DATABASE_PACKAGEDIR)
SOURCEDIRS = $(APP1_SOURCEDIR):$(UTIL_SOURCEDIR):$(DATABASE_SOURCEDIR)
CLASSDIRS = $(APP1_CLASSDIR):$(UTIL_CLASSDIR):$(DATABASE_CLASSDIR)
VPATH = $(SOURCEDIRS):$(CLASSDIRS)
%.class: %.java
javac -d $(ROOT_CLASSDIR) -classpath $(ROOT_CLASSDIR):$(CLASSPATH) $<
all: $(APP1_CLASSES) $(UTIL_CLASSES) $(DATABASE_CLASSES)
App1.jar: all
cd classes;jar cf ../$@ com
clean:
rm -rf classes App1.jar
EOF
> foo/bar contains the .class files
> and foo/bar/src contains the .java files
You can construct a makefile to achieve this design once you
understand the basics. Of course you may not want to, ...
> I refuse to mix the .java and .class files and think it is ridiculous how
> java tools expect this.
The default behavior may not be your cup of tea, but it is hardly ridiculous.
The java tools quite nicely provide what you want to do.
> Dependencies are not a problem once all the .class files are around, but
> when a user checks out a new repository I don't want them to get any .class
> files. Basically, the first thing that should be done after checking out the
> repository is a 'make all' so that all the .class files are built.
>
> Has anyone ever solved this problem. This is the first time I've really
> wished for header files, because C/C++ does not have this problem during
> compile time.
Lots of people have solved this problem in lots of different ways.
I promise you that you neither need nor want header files.
Somehow, though, I think your real question is: How can I do what I
want to do without investing a lot of my time and energy in learning
the fundamental capabilities of the tools involved? A common
question. You're in good company. Many resort to using a GUI based
solution and never learn the fundamentals of what the GUI/IDE is
doing. Your choice.
CVS, make, jar, javac (jikes), and most especially Emacs are simply
wonderful and INCREDIBLY powerful tools with which to develop elegant
Java programs should you choose to learn how to use them, IMHO.
Enjoy,
-pmr