Last active
October 29, 2019 10:26
-
-
Save jdonszelmann/26c71445b12593d2224d98a4ad09a9d2 to your computer and use it in GitHub Desktop.
General makefile for any c/asm project
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
executable_name = yeet | |
version = 0.0.1 | |
arch ?= x86_64 | |
LINKER = gcc | |
CC = gcc | |
CPP = g++ | |
ASM = gcc | |
NASM = nasm | |
SOURCEDIR = src | |
BINDIR = bin | |
BUILDDIR = build | |
RESOURCESDIR = resources | |
TESTDIR = test | |
# any directory named this will be included | |
INCLUDEDIR = include | |
# Flags for the linker. | |
LFLAGS = | |
# string of -l<something> library names. | |
# Use "-lstdc++" for projects including c++ code | |
LIBRARIES = | |
# flags for the c compiler | |
CFLAGS = | |
# flags for the cpp compiler | |
CPPFLAGS = | |
# flags for the assembler (.s / gcc) | |
ASMFLAGS = | |
# flags for the assembler (.asm / nasm) | |
NASMFLAGS = | |
#gdb | |
GDBARGS = | |
# setup | |
#----------------------- | |
executable_fullname = $(executable_name)-$(version)-$(arch) | |
executable = $(BINDIR)/$(executable_fullname) | |
testexecutable = $(BINDIR)/test/$(executable_fullname) | |
dirs = $(shell find $(SOURCEDIR)/ -type d -print) | |
testdirs = $(shell find $(TESTDIR)/ -type d -print) | |
includedirs := $(sort $(foreach dir, $(foreach dir1, $(dirs), $(shell dirname $(dir1))), $(wildcard $(dir)/$(INCLUDEDIR)))) | |
CFLAGS += $(foreach dir, $(includedirs), -I./$(dir)) | |
CPPFLAGS += $(foreach dir, $(includedirs), -I./$(dir)) | |
ASMFLAGS += $(foreach dir, $(includedirs), -I./$(dir)) | |
# support for .S files | |
assembly_source_files := $(foreach dir,$(dirs),$(wildcard $(dir)/*.S)) | |
assembly_object_files := $(patsubst $(SOURCEDIR)/%.S, \ | |
$(BUILDDIR)/%.o, $(assembly_source_files)) | |
# support for .s files | |
assembly_source_files += $(foreach dir,$(dirs),$(wildcard $(dir)/*.s)) | |
assembly_object_files += $(patsubst $(SOURCEDIR)/%.s, \ | |
$(BUILDDIR)/%.o, $(assembly_source_files)) | |
# support for .asm files | |
nassembly_source_files := $(foreach dir,$(dirs),$(wildcard $(dir)/*.asm)) | |
nassembly_object_files := $(patsubst $(SOURCEDIR)/%.asm, \ | |
$(BUILDDIR)/%.o, $(nassembly_source_files)) | |
# support for .c files | |
c_source_files := $(foreach dir,$(dirs),$(wildcard $(dir)/*.c)) | |
c_object_files := $(patsubst $(SOURCEDIR)/%.c, \ | |
$(BUILDDIR)/%.o, $(c_source_files)) | |
# support for .cpp files | |
cpp_source_files := $(foreach dir,$(dirs),$(wildcard $(dir)/*.cpp)) | |
cpp_object_files := $(patsubst $(SOURCEDIR)/%.cpp, \ | |
$(BUILDDIR)/%.o, $(cpp_source_files)) | |
# support for .S tests | |
assembly_test_source_files := $(foreach dir,$(testdirs),$(wildcard $(dir)/*.S)) | |
assembly_test_object_files := $(patsubst $(TESTDIR)/%.S, \ | |
$(BUILDDIR)/%.o, $(assembly_test_object_files)) | |
# support for .s tests | |
assembly_test_source_files += $(foreach dir,$(testdirs),$(wildcard $(dir)/*.s)) | |
assembly_test_object_files += $(patsubst $(TESTDIR)/%.s, \ | |
$(BUILDDIR)/%.o, $(assembly_test_object_files)) | |
# support for .asm tests | |
nassembly_test_source_files := $(foreach dir,$(testdirs),$(wildcard $(dir)/*.asm)) | |
nassembly_test_object_files := $(patsubst $(TESTDIR)/%.asm, \ | |
$(BUILDDIR)/%.o, $(nassembly_test_object_files)) | |
# support for .c tests | |
c_test_source_files := $(foreach dir,$(testdirs),$(wildcard $(dir)/*.c)) | |
c_test_object_files := $(patsubst $(TESTDIR)/%.c, \ | |
$(BUILDDIR)/%.o, $(c_test_source_files)) | |
# support for .c tests | |
cpp_test_source_files := $(foreach dir,$(testdirs),$(wildcard $(dir)/*.cpp)) | |
cpp_test_object_files := $(patsubst $(TESTDIR)/%.cpp, \ | |
$(BUILDDIR)/%.o, $(cpp_test_source_files)) | |
cpp_test_functions := $(shell cat $(cpp_test_source_files) | sed -n "s/void \\(test_.*\\)().*/\\1/p") | |
# default rules | |
#----------------------- | |
.PHONY: clean run debug build test | |
# build the executable but don't run | |
build: $(executable) | resourcesdir | |
clean: | |
@rm -rf $(BUILDDIR) | |
@rm -rf $(BINDIR) | |
# run the executable | |
run: build | resourcesdir | |
@echo starting | |
@cd $(RESOURCESDIR) && ../$(executable) | |
# run the executable with gdb | |
debug: $(executable) | resourcesdir | |
@gdb --args $(executable) $(GDBARGS) | |
test: $(testexecutable) | testdir resourcesdir | |
@echo testing | |
@cd $(RESOURCESDIR) && ../$(testexecutable) | |
# intermediate rules | |
#----------------------- | |
resourcesdir: | |
@mkdir -p $(RESOURCESDIR) | |
testdir: | |
@mkdir -p $(TESTDIR) | |
@mkdir -p $(BINDIR)/test | |
builddir: | |
@mkdir -p $(BUILDDIR) | |
# linking | |
$(executable): $(assembly_object_files) $(c_object_files) $(nassembly_object_files) $(cpp_object_files) | builddir | |
@echo linking... | |
@mkdir -p $(BINDIR) | |
@$(LINKER) -L/usr/lib $(LFLAGS) -o $@ $(assembly_object_files) $(nassembly_object_files) $(c_object_files) $(cpp_object_files) $(LIBRARIES) | |
# test linking | |
$(testexecutable): testobject $(assembly_object_files) $(c_object_files) $(nassembly_object_files) $(cpp_object_files) $(assembly_test_object_files) $(c_test_object_files) $(nassembly_test_object_files) $(cpp_test_object_files) | builddir testdir | |
@echo linking tests... | |
@mkdir -p $(BINDIR)/test | |
@$(LINKER) -L/usr/lib $(LFLAGS) -Wl,--wrap,main -o $@ $(BUILDDIR)/__test.o $(assembly_object_files) $(nassembly_object_files) $(c_object_files) $(cpp_object_files) $(assembly_test_object_files) $(c_test_object_files) $(nassembly_test_object_files) $(cpp_test_object_files) $(LIBRARIES) | |
# compile assembly files (.S) | |
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.S | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(ASM) -c $(ASMFLAGS) $< -o $@ | |
# compile assembly files (.S) | |
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.s | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(ASM) -c $(ASMFLAGS) $< -o $@ | |
# compile assembly files | |
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.asm | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(NASM) $(NASMFLAGS) $< -o $@ | |
# compile c files | |
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.c | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(CC) -c $(CFLAGS) $< -o $@ | |
# compile cpp files | |
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.cpp | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(CPP) -c $(CPPFLAGS) $< -o $@ | |
# compile assembly files (.S) | |
$(BUILDDIR)/%.o: $(TESTDIR)/%.S | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(ASM) -c $(ASMFLAGS) $< -o $@ | |
# compile assembly files (.S) | |
$(BUILDDIR)/%.o: $(TESTDIR)/%.s | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(ASM) -c $(ASMFLAGS) $< -o $@ | |
# compile assembly files | |
$(BUILDDIR)/%.o: $(TESTDIR)/%.asm | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(NASM) $(NASMFLAGS) $< -o $@ | |
# compile c files | |
$(BUILDDIR)/%.o: $(TESTDIR)/%.c | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(CC) -c $(CFLAGS) $< -o $@ | |
# compile cpp files | |
$(BUILDDIR)/%.o: $(TESTDIR)/%.cpp | builddir | |
@mkdir -p $(shell dirname $@) | |
@echo compiling $< | |
@$(CPP) -c $(CPPFLAGS) $< -o $@ | |
.PHONY: testobject | |
define testfile | |
#include <iostream> | |
$(foreach function, $(cpp_test_functions), void $(function)();) | |
extern "C" int __wrap_main(){ | |
$(foreach function, $(cpp_test_functions), $(function)(); std::cout<<"$(function) successful"<<std::endl;) | |
return 0; | |
} | |
endef | |
export testfile | |
testobject: | builddir | |
@echo "$$testfile" | $(CPP) -c -o $(BUILDDIR)/__test.o -xc++ - |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment