• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Maeriden

Subdirectories in makefile

9 posts in this topic

In an effort to try to learn makefiles I wrote this
 

C = $(CXX)
CFLAGS = -g -Wall -Wextra -I$(SRC_DIR) -std=c++0x

SRC_DIR = src
BIN_DIR = bin
OBJ_DIR = obj

vpath %.cpp $(SRC_DIR)
vpath %.h $(SRC_DIR)
vpath %.o $(OBJ_DIR)

GPATH = src obj

SRC = main.cpp resources.cpp ui.cpp
OBJ = $(SRC:.cpp=.o)

.PHONY: clean all

all: $(OBJ)
    $C -o $(BIN_DIR)/exe $^


main.o: main.cpp defaults.h
    $C -c $< -o $(OBJ_DIR)/$@ $(CFLAGS)

resources.o: resources.cpp resources.h
    $C -c $< -o $(OBJ_DIR)/$@ $(CFLAGS)

ui.o: ui.cpp ui.h defaults.h
    $C -c $< -o $(OBJ_DIR)/$@ $(CFLAGS)


clean:
    rm -f $(OBJ_DIR)/*.o


When I run make and the obj directory is empty it compiles all the .cpp files and places them in $(OBJ_DIR)/$@ -> obj/file.o

However when it is time to execute the all target, g++ doesn't find .o files, because $^ contains only the files without the directory prepended

According to http://www.gnu.org/software/make/manual/make.html#Search-Algorithm this is the intended behavior (though not what I want at all) and it says I can modify it using the GPATH variable, which I set but seems to be ignored by make

Notes: if I run make again it finds the files in the obj directory, and since they don't need to be recompiled the path is preserved, so I can't even modify all to be

$C -o $(BIN_DIR)/exe $(addprefix $(OBJ_DIR)/$^)

A first invocation of make would build and link the files correctly, but the second time it would try to link obj/obj/file.o and fail



What am I doing wrong?

0

Share this post


Link to post
Share on other sites

Using make when not all files are in the same dir is notoriously complicated (maybe switch to a less time consuming tool?).

It could help if in your link command under all: you change $^ to $(OBJ_DIR)/$^ so those files can be found.

0

Share this post


Link to post
Share on other sites

That's what I thought at the beginning (see the note). In that case if any .o is not found it gets built in $(OBJ_DIR), then make links files in $(OBJ_DIR) and makes me happy. But every time that a file does NOT need to be rebuilt, the path where make finds it is remembered (so main.o becomes obj/main.o) when used both as target and dependency. Proceeding to the link command it becomes g++ -o bin/exe obj/obj/main.o

 

What really makes my head hurt is why make ignores GPATH. I wouldn't have any problem if only that worked

0

Share this post


Link to post
Share on other sites
If you set the SRC .cpp files to include the directory for each one, it might work however I don't really recommend that.

Why do you need you .o files in a separate folder? If you do "rm -f $(OBJ)" it will clean them all up anyway.

Also, I dont know if you care, but I personally try to keep away from GNU extensions so that it works with different make tools (i.e BSD make).
main.o: main.cpp defaults.h
    $C -c $< -o $(OBJ_DIR)/$@ $(CFLAGS)

resources.o: resources.cpp resources.h
    $C -c $< -o $(OBJ_DIR)/$@ $(CFLAGS)

ui.o: ui.cpp ui.h defaults.h
    $C -c $< -o $(OBJ_DIR)/$@ $(CFLAGS)
You also dont need this bit, you can just make a rule to generate .o files from .cpp (this is the main reason for make) An example of such a rule would be ".cpp.o:".

If you need an example, I am very happy to post my template.
0

Share this post


Link to post
Share on other sites

 Why do you need you .o files in a separate folder? If you do "rm -f $(OBJ)" it will clean them all up anyway.

Well, I don't actually plan on cleaning the .o files very often, and I prefer not to keep them in the project root directory

 Also, I dont know if you care, but I personally try to keep away from GNU extensions so that it works with different make tools (i.e BSD make).

I don't specifically need to write a file that works with other tools, but I suppose it would be better to learn how to do it. Which extensions did I use?

 You also dont need this bit, you can just make a rule to generate .o files from .cpp (this is the main reason for make) An example of such a rule would be ".cpp.o:".

I've been wondering about this kind of rules. I've seen "$(OBJ): %.o: %.cpp" (here) but I can't understand how that would handle recompilation in the case a header file included by the source is modified

 

Thanks for the offer, but I've already seen quite a bit of examples. What I need is someone who would explain them

0

Share this post


Link to post
Share on other sites

but I can't understand how that would handle recompilation in the case a header file included by the source is modified

Yeah, this is a little bit tricky (which is where a lot of devs use a tool to generate the makefile for them). You ideally need to work out the dependencies of each cpp to work out which header they rely on. GCC does support this with the use of .d files. I have never really looked into this.

Personally... when working with a smallish project I just get a list of all my .h files and add them as a rule dependency. I.e if any header in the project changes, the whole thing gets re-compiled.

When I work on a large project... I break the project up into seperate modules (each with their own Makefile) and am back to working with a smallish project ;D Edited by Karsten_
0

Share this post


Link to post
Share on other sites

Using make when not all files are in the same dir is notoriously complicated (maybe switch to a less time consuming tool?).

It could help if in your link command under all: you change $^ to $(OBJ_DIR)/$^ so those files can be found.

 

Well, I had the same problem a while ago, and wanted to find a general-purpose solution, and sort of found one, at least for Linux. What I did was mirror the src directory structure onto obj, and use some arcane commands to make it work. I had to ask on stackoverflow... Anyway here it is, at least for one of my projects:

 

EXECUTABLE = epsilon
INCLUDE = -Iinclude/
CXX = g++

OBJECTS = $(subst cpp,o,$(subst src/,obj/,$(shell find src/ -name '*.cpp')))

HEADERS = $(shell find include/ -name '*.hpp')

CPPFLAGS = -O2 -std=c++11 -march=native
LDLIBS = -lOpenCL

$(EXECUTABLE): $(OBJECTS) 
	@mkdir -p bin/
	@echo Linking $(EXECUTABLE)...
	@$(CXX) $(OBJECTS) -o $(addprefix bin/, $(EXECUTABLE)) $(LDLIBS)

$(OBJECTS): obj/%.o : src/%.cpp $(HEADERS)
	@mkdir -p $(@D)
	@echo Building $@ from $<...
	@$(CXX) $(CPPFLAGS) $(INCLUDE) -c $< -o $@

clean:
	@echo Cleaning $(EXECUTABLE)...
	@rm -f $(addprefix bin/, $(EXECUTABLE))
	@rm -f obj/ --recursive

 

I don't remember if you need to create the root obj/ directory first, try it out, I guess. I think it is not very efficient, however, but that may just be my own incompetence at writing makefiles. Yes, using a shell find is probably a horrible idea and any experienced member will likely laugh at the code above, but it has worked for me so far and designing pretty makefiles is not one of my priorities.

0

Share this post


Link to post
Share on other sites
Mmm it's not very different from mine. To get around the issue of directories the target objects are written directly with obj/ prepended.
I wanted to avoid this solution because I didn't understand how to make make (no pun) work out the headers dependencies with a rule like $(OBJECTS): obj/%.o : src/%.cpp and thus decided to write a rule for each .o to avoid recompiling the whole project. Doing so meant that I had to manually write the directory variable in each rule, which seemed kind of dumb.

From the informations I was able to gather (I couldn't find an example that explained problems with GPATH) it looks like the solutions are: writing the path manually for each rule, using the general rule and have all the sources recompiled every time an header changes, or learning to use .d files (which will wait since I got fed up with make for a while).
Or use a different make system.

Thank you all for your advice, I really apreciate it :) Edited by Maeriden
0

Share this post


Link to post
Share on other sites

Make does have variables, so you can have the directory be a variable, so you only have to change it in one place.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0