Makefile, how to make it react to any content included?

You can talk about almost anything that you want to on this board.

Moderator: Moderators

User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Makefile, how to make it react to any content included?

Post by Banshaku »

@Jarhmander

I will look at your example and see how I can reuse in my code, thanks! In my makeFile, I couldn't use cl65 because I had special case with flags specific for C files and other for s files (like incbin for asm file only etc)

I updated my message since you do it with the include for deps so I figured out how it works for including deps. Forget about dependency thing from previous message ^^;;

@everyone

Should I paste my makefile inside a post instead? I didn't want to be rude and paste it as-is since it is a little big long but it seems if not pasted, people don't really check the content :lol: Comment about the makeFile I made would be quite appreciated since I will learn about what could be bad practices at the same time.

edit:

I missed one part of Jarhmander's makeFile, my answer didn't make sense.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Makefile, how to make it react to any content included?

Post by Banshaku »

Sorry for the double post. I don't like to push thing and be rude but it seems people don't like to download files, which means nobody will really see the content of the makeFile.

Regarding deps, I will test it myself once I fix scroll bug in IRQ (deps doesn't affect that so lower priority). Even though I don't want to be a makeFile guru, I would love to have some feedback on that file since it's good to know what you did right or were you did something you shouln't have (I guess I did many of those :lol:).

Here's the makeFile. Sorry again for the length m(_ _)m :

Code: Select all

#
# Basic makefile that compile the runtime and project files in src folder
# Author: Banshaku
# Version 0.9.4 (20180907)
#
# TODO: 
#  - Flag for add debug info or not?
# 
# Include neslib and famitone in a folder inside lib and crt0 in any folder inside src.
# [Example]
# libs/neslib
#  - neslib.s
#  - neslib.h
# libs/famitone
#  - famitone2.s
# src/crt
#  - crt0.s
#
# Note:
# - The files from data can be moved to src folder without issue
# - To compile runtime.lib (C runtime), you need to have a cloned version of cc65 which is available
#   at https://github.com/cc65/cc65. The version from your linux distribution or homebrew (for mac osx)
#   usually does not contain the libsrc/runtime folder.
# - If for some reason you cannot or do not want to get the version from github, the included
#   libsrc folder inside runtime contain all the V2.17 files from version libsrc/runtime and libsrc/common
# - Only the files from runtime/runtime.lst are added to runtime.lib. If you need a specific file,
#   you need to add it manually to this list
# - The path of all folders are added to the incluepath automatically. The advantage is that you do not need
#   to include the path of the file while including file either in c of assembler. There is one compromise: 
#   files cannot have the same name since the compiler will uses the first file it finds. If you do need to 
#   have the same name, you will have to write the relative/absolute path to the file (tested and working).
#
# About the libs folder:
# - For now, the libs folder is for libraries that requires to be included in another source file to work
#   properly. This is the case for famitune and neslib (to some degree). This mean not files are are
#   compiled from this folder: it is only used in include path so it can be included in the proper
#   module/bank etc.


##################
# Target related 
APP_NAME = revival
TARGET = $(APP_NAME).nes

##################
# CC65 related
AS := ca65
CC := cc65
LD := ld65
AR := ar65

##################
# Folders related
BUILD_DIR = build
RUNTIME_DIR = runtime
# Use the files downloaded from github
#LIBSRC_DIR = /path_for_cc65_here/libsrc
# Use provided runtime files instead
LIBSRC_DIR = $(RUNTIME_DIR)/libsrc
LIB_DIR = libs
DATA_DIR = data
SRC_DIR = src
RUNTIME_BUILD_DIR = build_runtime

##################
# List of dir, mostly used for include path
SRC_DIR_LIST  := $(SRC_DIR) $(sort $(dir $(wildcard $(SRC_DIR)/**/*/)))
LIB_DIR_LIST  := $(LIB_DIR) $(sort $(dir $(wildcard $(LIB_DIR)/**/*/)))
DATA_DIR_LIST := $(DATA_DIR) $(sort $(dir $(wildcard $(DATA_DIR)/**/*/)))

##################
# Target files related 
C_FILES := $(wildcard $(SRC_DIR)/*.c) $(wildcard $(SRC_DIR)/**/*.c)
S_FILES := $(wildcard $(SRC_DIR)/*.s) $(wildcard $(SRC_DIR)/**/*.s)
C_OBJ_FILES := $(addprefix $(BUILD_DIR)/, $(C_FILES:.c=.o))
S_OBJ_FILES := $(addprefix $(BUILD_DIR)/, $(S_FILES:.s=.o))
OBJ_FILES := $(C_OBJ_FILES) $(S_OBJ_FILES)
CONFIG_FILE := config/mmc3_CHR-ROM.cfg

###########################
# Runtime related
RUNTIME_FILES_LIST := $(shell cat ${RUNTIME_DIR}/runtime.lst)
RUNTIME_OBJ_FILES = $(patsubst %.s, $(RUNTIME_BUILD_DIR)/%.o, $(RUNTIME_FILES_LIST))
RUNTIME_LIB := $(RUNTIME_DIR)/runtime.lib

###################
# Specific compilation flags
FT_DEFINES  = -D FT_DPCM_ENABLE=0    # no dpcm
FT_DEFINES += -D FT_SFX_ENABLE=1     # with sound fx
FT_DEFINES += -D FT_THREAD=1         # calls soundfx in a different thread
FT_DEFINES += -D FT_PAL_SUPPORT=1    # PAL support
FT_DEFINES += -D FT_NTSC_SUPPORT=1   # NTSC support
FT_DEFINES += -D FT_SFX_STREAMS=4    # Set all 4 channels for SFX

###################
# Compiler/linker flags
ASFLAGS = -g -I $(SRC_DIR) $(INCLUDE_LIBS_FLAGS) $(INCLUDE_DATA_FLAGS) $(FT_DEFINES)
CCFLAGS = --add-source -Oi -Cl -g $(INCLUDE_LIBS_FLAGS) 
LDFLAGS = -Ln $(BUILD_DIR)/$(APP_NAME)_labels.txt -m $(BUILD_DIR)/$(APP_NAME)_map.txt --dbgfile $(APP_NAME).dbg -vm
INCLUDE_DATA_FLAGS := $(addprefix -I ,$(DATA_DIR_LIST)) $(addprefix --bin-include-dir ,$(DATA_DIR_LIST)) $(addprefix --bin-include-dir ,$(SRC_DIR_LIST))
INCLUDE_LIBS_FLAGS := $(addprefix -I ,$(SRC_DIR_LIST)) $(addprefix -I ,$(LIB_DIR_LIST))

###################
# other varibables (external programs etc)
EMULATOR = fceux
EMULATOR_DEBUG = nin.sh
EMULATOR_DEBUG2 = mesen.sh
EMULATOR_DEBUG3 = fceux_win.sh

.PHONY: all runtime run debug clean clean-both clean-runtime

#########################
### Build main target ###
all: $(TARGET)

$(TARGET): $(RUNTIME_LIB) $(OBJ_FILES) 
	$(LD) $(LDFLAGS) -C $(CONFIG_FILE) -o $@ $(OBJ_FILES) $(RUNTIME_LIB) 

####################################
### Main target files to compile ###
$(C_OBJ_FILES): $(BUILD_DIR)/%.o : %.c
	@mkdir -p $(@D)
	$(CC) $(CCFLAGS) $< -o $(@:.o=.s)
	$(AS) $(@:.o=.s) $(ASFLAGS) -l $(@:.o=)_listing.txt -o $@

$(S_OBJ_FILES): $(BUILD_DIR)/%.o : %.s 
	@mkdir -p $(@D)
	$(AS) $< $(ASFLAGS) -l $(@:.o=)_listing.txt -o $@

##########################
### Build runtime only ###
runtime: $(RUNTIME_LIB)

##################################
### Files related to C runtime ###
$(RUNTIME_LIB): $(RUNTIME_OBJ_FILES)
	$(AR) a $@ $^

$(RUNTIME_OBJ_FILES):
	@mkdir -p $(@D)
	$(AS) $(patsubst $(RUNTIME_BUILD_DIR)/%.o, $(LIBSRC_DIR)/%.s, $@) -g -o $@

##################################
### Ways to execute the target ###
run: $(TARGET) 
	$(EMULATOR) ./$<

debug: $(TARGET)
	$(EMULATOR_DEBUG) ./$<

debug2: $(TARGET)
	$(EMULATOR_DEBUG2) ./$<

debug3: $(TARGET)
	$(EMULATOR_DEBUG3) ./$<

######################################
### Cleaning main build only files ###
clean:
	rm -rf $(BUILD_DIR)
	rm -f $(TARGET)
	rm -f $(APP_NAME).dbg

###############################################
### Remove current runtime.librelated files ###
clean-runtime:
	rm -f $(RUNTIME_LIB)
	rm -rf $(RUNTIME_BUILD_DIR)

###############################################
### Clean both main build and runtime files ###
clean-both: clean clean-runtime
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Makefile, how to make it react to any content included?

Post by thefox »

I have a toolchain file for CMake which handles dependencies as you'd expect: https://github.com/fo-fo/ngin/blob/mast ... hain.cmake

I don't personally like Makefiles, too much uninteresting low-level crap to deal with.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
gauauu
Posts: 779
Joined: Sat Jan 09, 2016 9:21 pm
Location: Central Illinois, USA
Contact:

Re: Makefile, how to make it react to any content included?

Post by gauauu »

thefox wrote: I don't personally like Makefiles, too much uninteresting low-level crap to deal with.
The syntax sucks, but I've never found a better tool to easily build rules for other types of transformations (gfx -> chr, or map editor files -> binary, or famitracker -> converted music data, etc) that knows how to only re-build changed assets.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Makefile, how to make it react to any content included?

Post by Banshaku »

@thefox

Pardon my ignorance since I do not know much about cmake, does that mean I just use cmake to create the deps file with the toolchain file you provided? If it is then cool!

@gauauu

Not a big fan myself but it does the job. I guess my MakeFile "suck bad" since not much comment was said about it! :lol: It works for me so I guess I'm happy? ;)
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Makefile, how to make it react to any content included?

Post by koitsu »

I haven't commented on your Makefile because of its massive size (har har) and complexity. That is to say: if you are familiar enough with GNU make to be using all of the string translation and functions that you are, then I don't think you need anyone's help here with it. Really. You even seem to understand .PHONY and the difference between = and :=, which I always feel is a rarity these days.

Matter of opinion of course, but: if you don't like make, you can always try cmake, which is a whole new layer of hell (enough that a lot of people I know just go back to standard make because it's ugly at times but generally understood (except when it isn't)). "Tired of fighting GNU make? Try cmake to expand your profanity vocabulary!"
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Makefile, how to make it react to any content included?

Post by Banshaku »

@koitsu

Thank you for the comment, I really appreciate it ;) It is quite complex, I agree, but the result is a time saver for my current ask.

When I researched recently on how to improve my makeFile, I was able to understand many new concepts after reading the gnu manual and enjoyed the reading but unless you use it often... It gets forgotten quite fast. I may not remember exactly but at the least I know they have a special meaning and have to be careful (:= =), since it affect when the value is evaluated.

I would like to use a little bit at work but alas, this is a java world and we have many, many new layers of hell often related to the "new flavor of the day", which theses days is gradle ^^;; I don't remember how many time we changed compile tools in the last 4 years ... :lol:
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Makefile, how to make it react to any content included?

Post by thefox »

Banshaku wrote:@thefox

Pardon my ignorance since I do not know much about cmake, does that mean I just use cmake to create the deps file with the toolchain file you provided? If it is then cool!
Nope CMake is an entirely separate build system. It's actually a Makefile generator (it can also generate input for other build tools like Ninja). I'll admit it's not very easy to use that toolchain file without an example unless you're already familiar with CMake. (I could write an example, but if nobody's going to have any use for it, I won't.)
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Makefile, how to make it react to any content included?

Post by Banshaku »

So if I understand well, cmake would create my current makeFile based on some parameters defined elsewhere. This file (the deps one) is part of the process for generating all the files related to this target makefile so by itself it is not useful since I still need other settings/files to generate makeFile, deps etc . Did I understood correctly?

Then in that case, unless I migrate to cmake it would be hard to use that file then. If you have an example in your own files I can always extrapolate from there but deps is not urgent yet: as long that I just clean the project, it won't be an issue (just slow a little bit on an old core 2 duo).
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Makefile, how to make it react to any content included?

Post by rainwarrior »

Banshaku wrote:deps is not urgent yet: as long that I just clean the project, it won't be an issue (just slow a little bit on an old core 2 duo).
Well if you just made all .H files in your project a dependency of every .C file you'd should get the same result as having to do a clean rebuild for any header change without having to remember to do it. ;)
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 569
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Makefile, how to make it react to any content included?

Post by Jarhmander »

rainwarrior wrote:
Banshaku wrote:deps is not urgent yet: as long that I just clean the project, it won't be an issue (just slow a little bit on an old core 2 duo).
Well if you just made all .H files in your project a dependency of every .C file you'd should get the same result as having to do a clean rebuild for any header change without having to remember to do it. ;)
Except that it's suboptimal. make was invented so you didn't have to recompile everything. OTOH, compiling/assembling NES files is so fast that it's practically a non-issue.

Banshaku, did you look at my solution? I ask because it solves the problem automatically and transparently, which I'm pretty sure this is exactly what you want.

Heck, clone this repo (an old, uninteresting NES demo) : https://github.com/Jarhmander/nesgame-001

Now, go the directory and type make. The NES file is assembled and linked. Let's pretend to the system that we modified include/mapper69.inc : touch include/mapper69.inc. Now, type make again. The files src/mapper69.s, src/nmi.s, src/resetbanks.s and foo.s (the main file... I know) are assembled, the rest are not because they do not depend on include/mapper.inc.

Isn't that what you wanted? Heck, if you don't know how to modify your makefile, because you don't fully understand my makefile (it's really short, but there's no comments too), then if your project is on GitHub, I can even modify your makefile and send you a pull request with the additions. Isn't that great?
((λ (x) (x x)) (λ (x) (x x)))
User avatar
gauauu
Posts: 779
Joined: Sat Jan 09, 2016 9:21 pm
Location: Central Illinois, USA
Contact:

Re: Makefile, how to make it react to any content included?

Post by gauauu »

rainwarrior wrote:
Banshaku wrote:deps is not urgent yet: as long that I just clean the project, it won't be an issue (just slow a little bit on an old core 2 duo).
Well if you just made all .H files in your project a dependency of every .C file you'd should get the same result as having to do a clean rebuild for any header change without having to remember to do it. ;)
In larger scale projects, that's horrible. But in small NES stuff? Yeah, it's what I do. I can live with an extra 3 seconds of compiling every time I change a header.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Makefile, how to make it react to any content included?

Post by Banshaku »

@rainwarrior

Temporary quick hack, that could do but I would prefer to avoid it if possible ;)

@Jarhmander

I kept a copy for future reference but I didn't test yet. Since it seems to be an option of cc65/ca65 I should test it as soon as possible. I have been a busy bee testing raster effect with mmc3 and learning other simple things in C that for now it's been very low on my todo list ^^;; Once I test it, if it does work in my current makeFile I will be more than happy to share the result. Thanks to remind me about it. Sorry for not testing it yet since I think too that it is what I'm looking for! But since right now I'm in a testing phase, I change often the name of includes for testing multiple variation so the deps file would be out of date often. Once stabilized, that won't be an issue. As for my project, unfortunately it's not on github and it's nothing special yet. And since I'm testing with some assets from other games maybe it is better not to put it on github too ^^;; Once I have something interesting to share I will be more than happy to do so.

@gauauu

On a huge C++ project that would be a nightmare. I just imagine wxWidget recompiling the complete framework on a small change then 10~30 minutes later (well, my computer is slow...) you can now see the result!... Not a good idea. A few file, not really a issue! But Jarhmander has the actual solution, didn't test it yet. For that, I apologize.
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 569
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Makefile, how to make it react to any content included?

Post by Jarhmander »

I realize my example in the last post didn't prove something crucial... You have no dep file to maintain, it's entirely automatic. For instance, if you add an include file in any file, the dependency information will be updated automatically by a regular make invocation. This includes (no puns intended) also usages of .incbin: change the contents of a CHR bank, and the files that .incbin it will be re-assembled.

Sure, it's low priority, but it can help you now, because it's not affected by renames of the included files, because the dependency information is generated on the fly.
((λ (x) (x x)) (λ (x) (x x)))
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Makefile, how to make it react to any content included?

Post by Banshaku »

@Jarhmander

So no file to create then. I will give a look to your sample today and see what it does then. Thanks!
Post Reply