I have a class file called GuiRenderGUI in a folder called menuEditor. I've checked the spelling and that the files all exist yet I still cannot build a .h file.
I've tried all permutations of my classpath being ../bin or ../bin/menuEditor and the class being GuiRenderJNI or .menuEditor.GuiRenderJNI, the code below is the one with the "could not find..." error, all other permutations simply say 'No rule to make target `GuiRenderJNI.class'
# Define a variable for classpath
CLASS_PATH = ../bin/menuEditor
# Define a virtual path for .class in the CLASS_PATH directory
vpath %.class $(CLASS_PATH)
# $* matches the target filename without the extension
GuiRenderJNI.h : GuiRenderJNI.class
javah -classpath $(CLASS_PATH) menuEditor.$*
clean :
rm GuiRenderJNI.h GuiRenderJNI.o guirender.dll
What am I doing wrong? I can't find the problem in my code!
EDIT:
I've managed to get javah to generate a header file by making it look for the class inside a .jar file, using the exact same parameters, save for the -classpath which pointed to the .jar, if that helps
So I think the issue here is the difference between how vpath interprets its argument and how javah does (when looking for .class files as opposed to when looking for .jar files).
When you say vpath %.class $(CLASS_PATH) you are telling make that for any prerequisites that match the pattern %.class it should look for them (via the filename it started with) under $(CLASS_PATH).
When you say -classpath $(CLASS_PATH) you are telling java to use $(CLASS_PATH) as the root path for finding .class and .jar files. However the way it uses that root path differs depending on which of those two types of files you are looking for.
When looking for jar files java uses the root path and looks for files named after the package/module/whatever. So javah -classpath /foo menuEditor.GuiRenderJNI will look for /foo/menuEditor.GuiRenderJNI.jar (I believe, I'm not a java person). (So I presume when you got it working you had created a menuEditor.GuiRenderJNI.jar file, or something close to that.)
When looking for class files java uses the root path as the start of a directory hierarchy with components based on the class name components. So javah -classpath /foo menuEditor.GuiRenderJNI will look for /foo/menuEditor/GuiRenderJNI.class.
Putting those together when you have a $(CLASS_PATH) of ../bin/menuEditor you are telling make to look for GuiRenderJNI.class in ../bin/menuEditor/GuiRenderJNI.class which it can find. (This is why the other values for $(CLASS_PATH) gave you "no rule to make target" errors since it couldn't find that class file anymore.)
That same classpath however (combined with that javah call) tells java to look for ../bin/menuEditor/menuEditor/GuiRenderJNI.class which, for obvious reasons, cannot be found.
If javah will let you under-specify the class to operate on you might be able to use javah -classpath $(CLASS_PATH) $(basename $#) (non-compat target-without-suffix, also $(#:.h=) would work).
If javah will not let you do that then you either need to mangle $(CLASS_PATH) for the javah command line (something like $(dir $(CLASS_PATH))).
You could also try (and I don't know that vpath works like this but I believe it does) pulling menuEditor out of $(CLASS_PATH) and putting it in the prereq for that target GuiRenderJNI.h: menuEditor/GuiRenderJNI.class and then leaving $(CLASS_PATH) as-is on the javah line.
Related
I am relatively new to make and don't know how to do one specific thing:
The overall process should look something like this:
the source files are java sources in a directory like src/org/path/to/packages/*.java
I want only to translate a specific java file, but the translation process will automatically translate all dependencies (I say 'translate' because I use j2objc to translate the java files to obj-c files - but that should be of no concern for this question)
The translated files will be put into the build/ directory with a folder structure reflecting the source folder structure (so build/org/path/to/packages/.m+.h)
These *.m and *.h files will then be compiled with j2objcc (a clang wrapper) into *.o files -> this step has to be done per file so every file is compiled with a command like j2objcc -c build/org/path/to/packages/file1.m -o build/org/path/to/package/file1.o
these shall be combined into a static library using ar
My problem is that I know which (one) java file I am starting with, but after step 2 I don't know which *.m and *.h files are generated/translated into the build directory. I'd like to read the contents of the build dir after step 2 with a command like find ./build -name '*.m' at make runtime but I don't know how to use this as a prerequisite in the make target.
I have a Makefile with only project-level definitions: which source files to use, what binary or library to make, etc..
It includes ../../Make.Arch for architecture-specific definitions (such as compiler command).
In turn, Make.Arch is meant to include ../etc/Makefile.Standard for all the boilerplate of actually allowing the make system to work .
But include requires a path relative to where the makefile is actually being run (or maybe where the first Makefile is), not relative to the second... What to do?
Make interprets relative paths from the working directory, the directory in which Make is being run. You haven't specified how you're running Make, so I'll assume your running it in the directory with Makefile.
If you are allowed to modify the makefiles, you can change the paths.
You could change Make.Arch from this:
include ../etc/Makefile.Standard
to this:
include ../../../etc/Makefile.Standard
but that would require that any makefile that uses Make.Arch be two directories down from it. That's clearly not a good idea. But we can use a variable:
include $(ARCH_DIR)/../etc/Makefile.Standard
which is provided by Makefile (or any other makefile that uses Make.Arch):
ARCH_DIR := ../..
include $(ARCH_DIR)/Make.Arch
If you are not allowed to modify the makefiles, then you must cheat. One way is to create a symbolic link to Makefile.Standard.
mkdir ../etc
ln -s ../../../etc/Makefile.Standard ../etc
Now Makefile will work. (It ought to be possible to make a link to etc/, but for some reason I can't get that to work right now.)
I have a problem modifying existing CMake based build-system. All I want to do is add different build rule for some of .c files. For the sake of this problem, I will focus on only one file.
The simplified directories tree looks like this
Project:
./src
- file_of_interest.c
- CmakeFiles.txt
other_files.c
CmakeFiles.txt
So in order to compile file_of_interest.c in a different way I do:
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/file_of_interest.s
COMMAND xt-xcc -S ${CMAKE_CURRENT_SOURCE_DIR}/file_of_interest.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/file.c
COMMENT "Generating file_of_interest.s"
)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/file_of_interest.c.o
COMMAND xt-xcc ${CMAKE_CURRENT_BINARY_DIR}/file_of_interest.s -o file_of_interest.c.o -c
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/file_of_interest.s
COMMENT "Generating file_of_interest.c.o"
)
message(" ${CMAKE_CURRENT_BINARY_DIR} \n ${CMAKE_CURRENT_SOURCE_DIR}")
target_sources(target_name PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/file_of_interest.c.o)
As you can see I used CMake's message() to print paths to be sure all is set up properly. It should work, but it doesn't! I expect CMake to register file_of_interest.c.o as source of target_name (and this is probably working), then "tie" it with my custom command which produces OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/file_of_interest.c.o and then to tie again ${CMAKE_CURRENT_BINARY_DIR}/file_of_interest.c.o with OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/file_of_interest.s and this certainly doesn't happen as CMake shows error message saying CMake Error at CMakeLists.txt:170 (add_executable): Cannot find source file: path/file_of_interest.c.o
The path is OK. So the question is why does CMake cannot recognize recipes for that file?
It seems that you create an executable (call add_executable) in the top-level CMakeLists.txt, but add_custom_command are called from the subdirectory (src/CMakeLists.txt).
This doesn't work: when CMake processes add_executable and searches for the commands generating its sources, it sees only add_custom_commands created in the same CMakeLists.txt.
From the add_custom_command documentation:
A target created in the same directory (CMakeLists.txt file) that specifies any output of the custom command as a source file is given a rule to generate the file using the command at build time.
It is unrelated that target_sources is called from the same directory as add_custom_command: the target is created by add_executable command, and target_sources just modifies its properties.
I am trying to understand a makefile from a project I am working on. It's using automake/autotools and contains this simple rule:
DEPS_SRC = $(shell cd $(srcdir); find . -name '*.ez')
DEPS = $(basename $(DEPS_SRC))
all : $(DEPS)
$(DEPS) : % : %.ez
$(UNZIP) -o $<
Say the directory structure is:
my-app/deps/
build/
When executing make my-app in the build folder the rule will basically unpack *.ez files located in the my-app/deps/ folder into build/my-app/deps/ folder.
I don't know if that's enough information to solve the problem that I am going to explain as I don't know enough about automake/autotools. Please ask if any additional information is needed.
The problem is that I noticed that having the unpacked directory in the source folder prevents make from unpacking the archive in the target folder. For example, given the following structure in the source folder:
my-app/deps/archive1.ez
my-app/deps/archive2.ez
my-app/deps/archive2/
make will only unpack archive1.ez in the build folder:
build/my-app/deps/archive1/
I would like to know if this is a bug in my makefile or a feature of automake. If the later, is there any workaround or setting or variable available to disable it?
This is primarily a GNU make question, not particularly specific to the Autotools. However, since the target system's make is of GNU's flavor (else none of this works), we can assume that the Makefile generated by configure uses GNU make's VPATH feature as part of its support for out-of-source (a.k.a. VPATH) builds such as the one you are performing.
The value of the VPATH variable that configure will have inserted into the Makefile is used as a search path for prerequisites that are not found relative to the build directory. The key point, however, is that it is also used as a search path for rule targets. That makes a certain amount of sense, especially for targets that are prerequisites of other rules.
In your case, however, that leads directly to the behavior you describe:
the default target depends on ./my-app/deps/archive2
resolving that name against the build directory does not produce a valid file name
before attempting to build that target, make looks in the directories listed in the VPATH, which, in your example case, will contain .. or an equivalent
make finds .././my-app/deps/archive2 in this VPATH search, and therefore determines that the specified target already exists, and does not need to be built
Thus, the behavior you observe is normal for GNU make, supposing the Makefile is constructed by Autoconf from an Automake-generated template.
is there any workaround or setting or variable available to disable it?
Do you really need one? If the archive file has already been unpacked in the source tree, then you can expect make to find its contents, too, via the VPATH. At least if the Makefile is well-prepared overall for for out-of-source builds.
But if you want to be certain to get the archive files unpacked in the build directory then you can specify that explicitly. This ought to do it:
DEPS_SRC = $(shell cd $(srcdir); find . -name '*.ez')
DEPS = $(basename $(DEPS_SRC))
LOCAL_DEPS = $(addprefix $(abs_builddir)/,$(DEPS))
all : $(LOCAL_DEPS)
$(LOCAL_DEPS) : $(abs_builddir)/% : %.ez
$(UNZIP) -o $<
That prefixes the name of each dependency with the absolute path to the build directory, and updates the rule for unzipping the archives to accommodate it. Targets with absolute paths such as that cannot be located in the VPATH.
GNU Make 3.8.1
I am working on what is basically a plugin for a software product. The plugin is built in a subdirectory of the main product, so the directory structure looks something like:
product
product/src
product/plugin
product/plugin/myPlugin
where "myPlugin" is the name of the plugin I'm working on. What I would like to do, is be able to build myPlugin as well as another version of myPlugin, call it myPlugin-lite. This plugin would have the same sources as myPlugin, but use different flags and defines in the makefiles. The idea was to create a duplicate of the myPlugin tree structure, containing only myPlugin's makefiles, and have it build using the sources from myPlugin. So the directory structure would look like:
product
product/src
product/plugin
product/plugin/myPlugin
product/plugin/myPlugin-lite
myPlugin would build and create all its targets within its subdirectory, and myPlugin-lite would build and create all its targets within its subdirectory. I found a few solutions here: http://make.mad-scientist.net/papers/multi-architecture-builds/ and out of these options it seems like the symbolic links would be best, but it still doesn't feel like the "right" way to do this.
My question is, is this the best/simplest/most maintainable way to do this? If not what are the alternatives?
If the only thing you need from myPlugin is source files then this is exactly what VPATH and The vpath Directive are for.
4.5.1 VPATH: Search Path for All Prerequisites
The value of the make variable VPATH specifies a list of directories that make should search. Most often, the directories are expected to contain prerequisite files that are not in the current directory; however, make uses VPATH as a search list for both prerequisites and targets of rules.
Thus, if a file that is listed as a target or prerequisite does not exist in the current directory, make searches the directories listed in VPATH for a file with that name. If a file is found in one of them, that file may become the prerequisite (see below). Rules may then specify the names of files in the prerequisite list as if they all existed in the current directory. See Writing Recipes with Directory Search.
In the VPATH variable, directory names are separated by colons or blanks. The order in which directories are listed is the order followed by make in its search. (On MS-DOS and MS-Windows, semi-colons are used as separators of directory names in VPATH, since the colon can be used in the pathname itself, after the drive letter.)
For example,
VPATH = src:../headers
specifies a path containing two directories, src and ../headers, which make searches in that order.
With this value of VPATH, the following rule,
foo.o : foo.c
is interpreted as if it were written like this:
foo.o : src/foo.c
assuming the file foo.c does not exist in the current directory but is found in the directory src.
Also see How Not to Use VPATH from MadScientist for more discussion about what they aren't for. Though that's largely just a build-up for the multi-architecture-builds paper you already read.