Simple Dependency Resolution Under a Directory Structure with GNU Make
Jul 29th 2008 | Posted by Kadir Pekel as General, gnu / linux

Since i decided to begin a C/C++ project, i thought that i must firstly prepare a development environment for my own convenience. So i began to dig about make tool for building an environment for myself. The most important feature i wish to implement was a proper directory structure. After hours reading GNU make manual, i found myself writing one that resolves header and source dependency between object files under a directory structure.
Here i share well parametrized and documented simplistic make file that supplies all my needs. The directory structure i use is:
./src
./src/greeter.cpp
./src/printer.cpp
./src/main.cpp
./bin
./makefile
./obj
./inc
./inc/printer.h
./inc/greeter.h
Since i’m not an make tool expert, please feel free to share if there is an absurdity or if you want extend it somehow
makefile:
# ------------------------------------------------------------------------------ # Copyright [2008] [Kadir PEKEL] # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # This simple GNU make file automates your build processes with simple # dependency resolution under a DIRECTORY STRUCTURE. # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Name your own project # ------------------------------------------------------------------------------ PROJECT = testProject # ------------------------------------------------------------------------------ # Compiler parameters # ------------------------------------------------------------------------------ CC = g++ CFLAGS = -Wall -g # ------------------------------------------------------------------------------ # Directory structure # ------------------------------------------------------------------------------ SRC_DIR = src OUT_DIR = bin OBJ_DIR = obj INC_DIR = inc # ------------------------------------------------------------------------------ # Source file sufix # ------------------------------------------------------------------------------ SUFFIX = .cpp # ------------------------------------------------------------------------------ # You shouldn't modify below unless you do know what you are doing. # - # The thing that is going on here is that any source file under the source # directory is compiled into its own object file under the objects directory. # Dependency declaration of the object file to its corresponding source file # is done automatically. Also, if your source file has got a header file with # the same name in the include directory, it's also declared as a dependency # for the related object file. # ------------------------------------------------------------------------------ ALL_CFLAGS = -I. -I./$(INC_DIR) OUTPUT = $(OUT_DIR)/$(PROJECT) SRC_FILES = $(wildcard $(SRC_DIR)/*$(SUFFIX)) OBJ_FILES = $(patsubst $(SRC_DIR)/%$(SUFFIX), $(OBJ_DIR)/%.o, $(SRC_FILES)) INC_FILES = $(wildcard $(INC_DIR)/*.h) INC_SRC_FILES = $(patsubst $(INC_DIR)/%.h, $(SRC_DIR)/%$(SUFFIX), $(INC_FILES)) INC_SRC_OBJ_FILES = $(patsubst $(SRC_DIR)/%$(SUFFIX), $(OBJ_DIR)/%.o, \ $(INC_SRC_FILES)) _main: $(OBJ_FILES) $(CC) $(CFLAGS) $(ALL_CFLAGS) $(OBJ_FILES) -o $(OUTPUT) $(INC_SRC_OBJ_FILES): $(OBJ_DIR)/%.o: $(INC_DIR)/%.h $(OBJ_DIR)/%.o: $(SRC_DIR)/%$(SUFFIX) $(CC) $(CFLAGS) $(ALL_CFLAGS) -c $< -o $@ # ------------------------------------------------------------------------------ # Default target that does the work when you type 'make' without pointing to # any target # ------------------------------------------------------------------------------ .DEFAULT : all all: _main # ------------------------------------------------------------------------------ # Put your cross dependiences here # ------------------------------------------------------------------------------ $(OBJ_DIR)/greeter.o: $(INC_DIR)/printer.h $(OBJ_DIR)/main.o: $(INC_DIR)/greeter.h # ------------------------------------------------------------------------------ # Here you can write down custom targets and if you wish, you can make the # default target dependent to yours. For ex: 'all: _main <your_target>' # ------------------------------------------------------------------------------ .PHONY : clean clean: -rm $(OBJ_DIR)/* $(OUT_DIR)/* your_target: @echo "your target"
Subscribe in a reader
Subscribe via e-mail