Skip to content

Commit

Permalink
Replacing the bulid system
Browse files Browse the repository at this point in the history
  • Loading branch information
jyothiraditya-n committed Aug 22, 2023
1 parent 0d9d992 commit 70e7aab
Show file tree
Hide file tree
Showing 27 changed files with 870 additions and 445 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
build/
.config/
.config.mk
238 changes: 128 additions & 110 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# libClame: Command-line Arguments Made Easy
# Copyright (C) 2021-2023 Jyothiraditya Nellakra
# Amocao C/C++ Build System Copyright (C) 2021-2023 Jyothiraditya Nellakra
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
Expand All @@ -8,166 +7,185 @@
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <https://www.gnu.org/licenses/>.

# Make sure that config runs before making anything.
ifeq ($(shell [ -d ".config/" ] && echo "config"),)
ifeq ($(filter config,$(MAKECMDGOALS)),)
ifeq ($(filter autoconfig,$(MAKECMDGOALS)),)
ifeq ($(wildcard .config.mk),) # The config file is missing.

ifneq ($(filter autoconfig,$(MAKECMDGOALS)),) # Run make autoconfig.
$(info *** Configuration missing; running 'make autoconfig'.)
$(shell make autoconfig)
$(shell chmod +x configure.sh)
$(shell ./configure.sh --auto)

else # Run make config.
$(info *** Configuration missing; running 'make config'.)
$(shell chmod +x configure.sh)
$(shell ./configure.sh)

endif
endif
endif

# We want to build with debugging symbols as a default.
.DEFAULT_GOAL = debug
# Include the config file.
include .config.mk

# Getting Config Values.
CC = $(shell cat .config/cc.conf)
CPP = $(shell cat .config/cpp.conf)
LD = $(shell cat .config/ld.conf)
AR = $(shell cat .config/ar.conf)
# We are a library, and our main goal is to construct the archive file.
FINAL = build/$(NAME).a

LD_LIBS = $(shell cat .config/ld_libs.conf)
# We want to build with debugging symbols as a default.
.DEFAULT_GOAL = debug

ifneq ($(filter release,$(MAKECMDGOALS)),)

CFLAGS = $(shell cat .config/cflags_release.conf)
CCFLAGS = $(shell cat .config/ccflags_release.conf)
LATEX = $(shell cat .config/latex_release.conf)
TEST_FLAGS = -valgrind
CFLAGS = $(CFLAGS_RELEASE)
CCFLAGS = $(CCFLAGS_RELEASE)
TEST_FLAGS = $(TEST_FLAGS_RELEASE)

else

CFLAGS = $(shell cat .config/cflags_debug.conf)
CCFLAGS = $(shell cat .config/ccflags_debug.conf)
LATEX = $(shell cat .config/latex_debug.conf)
TEST_FLAGS = -nogrind
CFLAGS = $(CFLAGS_DEBUG)
CCFLAGS = $(CCFLAGS_DEBUG)
TEST_FLAGS = $(TEST_FLAGS_DEBUG)

endif

# Files that need to be created.
folders = build/ build/docs/ build/src/
# Lists of files to be used in our recipe rules.

# Shell scripts.
build_scripts = $(wildcard *.sh)
test_scripts = $(wildcard tests/*.sh)
scripts = $(build_scripts) $(test_scripts)

c_srcs = $(shell find * -type f -name "*.c")
cpp_srcs += $(shell find * -type f -name "*.cpp")

c_headers = $(shell find inc/ -type f -name "*.h")
cpp_headers += $(shell find inc/ -type f -name "*.hpp")
headers = $(c_headers) $(cpp_headers)

c_texs = $(patsubst demos/%.c,build/docs/%.c.tex,$(wildcard demos/*.c))
cpp_texs = $(patsubst demos/%.cpp,build/docs/%.cpp.tex,$(wildcard demos/*.cpp))
texs = $(c_texs) $(cpp_texs)

docs = $(texs) $(wildcard docs/*)
demo_scripts = $(shell find demos/ -name "*.sh")
test_scripts = $(shell find tests/ -name "*.sh")
scripts = $(build_scripts) $(demo_scripts) $(test_scripts)

c_objs = $(patsubst src/%.c,build/src/%.o,$(wildcard src/*.c))
cpp_objs = $(patsubst src/%.cpp,build/src/%_cpp.o,$(wildcard src/*.cpp))
objs = $(c_objs) $(cpp_objs)
# Core C/C++ source files.
c_srcs = $(shell find src/ -name "*.c")
cc_srcs = $(shell find src/ -name "*.cc")

c_demos = $(patsubst demos/%.c,build/%_demo,$(wildcard demos/*.c))
cpp_demos += $(patsubst demos/%.cpp,build/%_cpp_demo,$(wildcard demos/*.cpp))
demos = $(c_demos) $(cpp_de_mos)
# Core C/C++ header files.
c_headers = $(shell find inc/ -name "*.h")
cc_headers = $(shell find inc/ -name "*.hh")
headers = $(c_headers) $(cc_headers)

c_tests = $(patsubst tests/%.c,build/%_test,$(wildcard tests/*.c))
cpp_tests += $(patsubst tests/%.cpp,build/%_cpp_test,$(wildcard tests/*.cpp))
tests = $(c_tests) $(cpp_tests)
# Objects that need to be made from the C/C++ source files.
c_objs = $(patsubst %.c,build/%.o,$(c_srcs))
cc_objs = $(patsubst %.cc,build/%_cc.o,$(cc_srcs))
objs = $(c_objs) $(cc_objs)

# Automatic Rules for creating those files.
$(folders) : % :
mkdir -p $@
# C/C++ demo program source files.
c_demo_srcs = $(shell find demos/ -name "*.c")
cc_demo_srcs = $(shell find demos/ -name "*.cc")

.PHONY : $(scripts)
# C/C++ demo program output files.
c_demos = $(patsubst demos/%.c,build/%_demo,$(c_demo_srcs))
cc_demos = $(patsubst demos/%.cc,build/%_cc_demo,$(cc_demo_srcs))
demos = $(c_demos) $(cc_demos) $(demo_scripts)

$(scripts) : % :
chmod +x $@

$(c_texs) : build/docs/%.c.tex : demos/%.c $(build_scripts) | \
build/docs/texs.tex
./make_tex.sh "c" $< $@ build/docs/texs.tex

$(cpp_texs) : build/docs/%.cpp.tex : demos/%.cpp $(build_scripts) | \
build/docs/texs.tex
./make_tex.sh "cpp" $< $@ build/docs/texs.tex

$(c_objs) : build/src/%.o : src/%.c $(headers) | build/src/
$(CC) $(CFLAGS) -c $< -o $@

$(cpp_objs) : build/src/%_cpp.o : src/%.cpp $(headers) | build/src/
$(CPP) $(CCFLAGS) -c $< -o $@
# C/C++ test program source files.
c_test_srcs = $(shell find tests/ -name "*.c")
cc_test_srcs = $(shell find tests/ -name "*.cc")

$(c_demos) : build/%_demo : demos/%.c $(headers) build/libClame.a
$(CC) $(CFLAGS) $< -o $@ $(LD_LIBS)
# C/C++ test program output files.
c_tests = $(patsubst tests/%.c,build/%_test,$(c_test_srcs))
cc_tests = $(patsubst tests/%.cc,build/%_cc_test,$(cc_test_srcs))
tests = $(c_tests) $(cc_tests) $(test_scripts)

$(cpp_demos) : build/%_cpp_demo : demos/%.cpp $(headers) build/libClame.a
$(CPP) $(CCFLAGS) $< -o $@ $(LD_LIBS)
# Automatic rules for creating those files.
.PHONY: $(scripts)

$(c_tests) : build/%_test : tests/%.c $(headers) build/libClame.a
$(CC) $(CFLAGS) $< -o $@ $(LD_LIBS)
# Command to print out how many targets are done and how many remain.
DONE_TALLY = X # Counting starts at 1.
DONE_COUNT = $(words $(DONE_TALLY)$(eval DONE_TALLY := X $(DONE_TALLY)))
LEFT_COUNT = $$(PROGRESS="" $(MAKE) -kq $(MAKECMDGOALS) | wc -l)
TOTAL_COUNT = $$(echo "$(DONE_COUNT) + $(LEFT_COUNT)" | bc -l)

$(cpp_tests) : build/%_cpp_test : tests/%.cpp $(headers) build/libClame.a
$(CPP) $(CCFLAGS) $< -o $@ $(LD_LIBS)
PERCENTAGE = $$(echo "$(DONE_COUNT) * 100 / $(TOTAL_COUNT)" | bc -l)
PROGRESS ?= printf " \033[0;1m[%.0f%%]\r\033[0;0m" $(PERCENTAGE)

# Other, manually defined recipes.
.PHONY : build/docs/texs.tex

build/docs/texs.tex : | build/docs/
-rm $@

build/libClame.a : $(objs)
$(AR) -r build/libClame.a $(objs)

build/libClame.pdf : $(docs)
mkdir -p build/docs/
cp docs/* build/docs/
cd build/docs/; $(LATEX)
mv build/docs/main.pdf build/libClame.pdf
$(scripts) : % :
@+printf " CHMOD ${@}\n"; $(PROGRESS)
@chmod +x $@

$(c_objs) : build/%.o : %.c $(headers)
@+printf " CC ${<}\n"; $(PROGRESS)
@mkdir -p $(@D)
@$(CC) $(CFLAGS) -c $< -o $@

$(cc_objs) : build/%_cc.o : %.cc $(headers)
@+printf " CXX ${<}\n"; $(PROGRESS)
@mkdir -p $(@D)
@$(CXX) $(CCFLAGS) -c $< -o $@

$(c_demos) : build/%_demo : demos/%.c $(headers) $(FINAL) $(LIBS)
@+printf " CC ${<}\n"; $(PROGRESS)
@mkdir -p $(@D)
@$(CC) $(CFLAGS) $< -o $@ $(LD_LIBS)

$(cc_demos) : build/%_cc_demo : demos/%.cc $(headers) $(FINAL) $(LIBS)
@+printf " CXX ${<}\n"; $(PROGRESS)
@mkdir -p $(@D)
@$(CXX) $(CCFLAGS) $< -o $@ $(LD_LIBS)

$(c_tests) : build/%_test : tests/%.c $(headers) $(FINAL) $(LIBS)
@+printf " CC ${<}\n"; $(PROGRESS)
@mkdir -p $(@D)
@$(CC) $(CFLAGS) $< -o $@ $(LD_LIBS)

$(cc_tests) : build/%_cc_test : tests/%.cc $(headers) $(FINAL) $(LIBS)
@+printf " CXX ${<}\n"; $(PROGRESS)
@mkdir -p $(@D)
@$(CXX) $(CCFLAGS) $< -o $@ $(LD_LIBS)

# Our main target file.
$(FINAL): $(objs)
@+printf " AR $(FINAL)\n"; $(PROGRESS)
@mkdir -p $(@D)
@$(AR) rcs $(FINAL) $(objs)

# Commands
.PHONY : release debug demos docs clean deep-clean
.PHONY : release debug demos clean deep-clean
.PHONY : config autoconfig tidy format

release : build/libClame.a
release: $(FINAL)

debug : build/libClame.a
debug: $(FINAL)

demos : $(demos)

docs : build/libClame.pdf
demos: $(demos)

clean :
-rm -r build/
@+printf " RM build/\n"; $(PROGRESS)
@-rm -r build/

deep-clean : clean
-rm -r .config/
config : $(build_scripts)
@+printf " RM .config.mk\n"; $(PROGRESS)
@-rm -r .config.mk

./configure.sh
config: $(build_scripts)
@+printf " BASH configure.sh\n"; $(PROGRESS)
@./configure.sh

autoconfig : $(build_scripts)
./configure.sh -auto
autoconfig: $(build_scripts)
@+printf " BASH configure.sh --auto\n"; $(PROGRESS)
@./configure.sh --auto

tidy :
clang-tidy $(c_srcs) $(headers) -- $(CFLAGS)
cland-tidy $(cpp_srcs) $(headers) -- $(CCFLAGS)

# Testing requires a little bit of hacky coding.
@+printf " BASH clang-tidy ...\n"; $(PROGRESS)
@clang-tidy $(c_srcs) $(headers) -- $(CFLAGS)
@clang-tidy $(c_demo_srcs) -- $(CFLAGS)
@clang-tidy $(c_test_srcs) -- $(CFLAGS)
@cland-tidy $(cc_srcs) $(headers) -- $(CCFLAGS)
@cland-tidy $(cc_demo_srcs) -- $(CCFLAGS)
@cland-tidy $(cc_test_srcs) -- $(CCFLAGS)

# Testing requires a little bit of hacky coding for the make configuration.
runnable_tests = $(patsubst %,run-%,$(test_scripts))

.PHONY : $(runnable_tests) test
.PHONY: $(runnable_tests) test
$(runnable_tests) : run-% : % $(tests)
$< $(TEST_FLAGS)
@+printf " BASH ${<}\n"; $(PROGRESS)
@$< $(TEST_FLAGS)

test : $(runnable_tests)
test: $(runnable_tests)
31 changes: 31 additions & 0 deletions amocao.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Amocao C/C++ Build System Copyright (C) 2021-2023 Jyothiraditya Nellakra
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <https://www.gnu.org/licenses/>.

# This is an amocao build configuration for this program:
name="libClame"

# Commands to make release and debug builds of libraries.
make_release["$name"]="\$(MAKE) --no-print-directory release"
make_debug["$name"]="\$(MAKE) --no-print-directory debug"

# Commands to clean build files from libraries.
make_clean["$name"]="\$(MAKE) --no-print-directory clean"

# Commands to configure libraries' build systems.
make_config["$name"]="\$(MAKE) --no-print-directory config"
make_autoconfig["$name"]="\$(MAKE) --no-print-directory autoconfig"

# Commands to clear out the config files.
make_deep_clean["$name"]="\$(MAKE) --no-print-directory deep-clean"
Loading

0 comments on commit 70e7aab

Please sign in to comment.