Reputation: 23
For some reason I never get the hang of modern programming methods. As a 68k assembly programmer, I'm trying to quit using a single tree file to link everything for final file, and rather follow a more typical "build/link objects" scheme. However, I have spent 4 days trying to find a logical explanation and fix to this issue.
I'm trying to auto-detect and build every file from certain folder, whose objects get packed into a specifically defined object, that gets linked together other specifically defined objects.
This is the makefile: https://pastebin.com/H6QE29fj
CUR = $(SRC)\lib
VPATH = $(OBJ) $(CUR)
INPUT = $(notdir $(wildcard $(CUR:\=/)/*))
$(OBJ)\library.md.o: $(INPUT:.asm=.o)
$(VLINK) -r -o $@ $(addprefix $(OBJ)\,$(notdir $^))
The issue lies above. Days ago, I used this same code snippet to generate $(OBJ)\ints.md.o, from the folder $(SRC)\ints. No issues with it at all, I even manually added a filename just before using $(INPUT) variable, so it gets assembled in at the beginning of a SECTION (engine shenanigans).
If said code "works", why doesn't it work for the library?
make: *** No rule to make target `loadtilemap.o', needed by `.\src\__obj\library.md.o'. Stop.
Shouldn't it be enough with %.o: %.asm rule?
Upvotes: 1
Views: 646
Reputation: 101081
First I recommend you always use forward-slash, not backslash, when working with paths in makefiles. Almost all Windows commands will accept either style in paths. If you need to invoke a command that won't accept forward-slash as a path separator, convert them inside the recipe where it is needed. make
is a UNIX/POSIX tool and as such it generally uses forward-slashes for directory separators and backslashes as escape sequences. When compiled for Windows some effort is made to DTRT with respect to backslashes but it may not work everywhere. Just use forward slashes and move on to other things.
Here's a hint from your makefile:
%.o: %.asm
$(V68k) $(BUILDARGS) -L $(LST)\$(notdir $(basename $@)).txt -o $(OBJ)\$@ $<
It is (almost) never correct for a target to create a file other than $@
. This is my Second Rule of Makefiles. Any time you see a rule that constructs a file that is not just plain $@
you know there's a problem. Make wants to build a target. It knows what target it wants to build, and it puts the path to that target in the $@
variable. If you, in your recipe, feel the need to create a file that is not exactly $@
then you know that you and make disagree on something fundamental, and disagreeing with make will not give you the results you want :).
If you want to create a file in a directory that is not the same one as the source then the directory must be included in the rule:
$(OBJ)/%.o: %.asm
$(V68k) $(BUILDARGS) -L $(LST)\$(notdir $(basename $@)).txt -o $@ $<
This also means your link recipe:
$(OBJ)\library.md.o: $(INPUT:.asm=.o)
$(VLINK) -r -o $@ $(addprefix $(OBJ)\,$(notdir $^))
won't work. Why? Because the prerequisites don't include the directory. You need to change this to:
$(OBJ)\library.md.o: $(INPUT:%.asm=$(OBJ)/%.o)
$(VLINK) -r -o $@ $^
You may think that adding $(OBJ)
to VPATH
will help solve this, but it won't. That's not how VPATH
is designed to work; VPATH
can only be used to search for source files, never generated files like object files. The reasons are complex but if you want the details there is a detailed explanation here.
Upvotes: 3