Skip to content

Instantly share code, notes, and snippets.

@FlyingJester
Created October 25, 2016 21:36
Show Gist options
  • Save FlyingJester/1c74b8e9563920f68b43286d415c7109 to your computer and use it in GitHub Desktop.
Save FlyingJester/1c74b8e9563920f68b43286d415c7109 to your computer and use it in GitHub Desktop.
Starter Makefile generator
import glob
import os
import sys
def WriteTarget(file, name, depends):
file.write(name + ".o: ")
for d in depends:
file.write(d + " ")
file.write("\n\t$(CC) $(CCFLAGS) -c " + name + ".c -o " + name + ".o\n")
paths = glob.glob(os.path.join(os.getcwd(), "*.c"))
files = []
for path in paths:
depends = []
file = open(path, "rb")
line = "\n"
while len(line) != 0:
line = file.readline()
if len(line) > 10 and line.startswith("#include"):
spl = line.split("\"", 3)
length = len(spl)
if length > 2 and os.path.isfile(spl[1]):
depends.append(spl[1])
path = os.path.basename(path)
files.append({"path":path[:-2], "depends":[path] + depends})
makefile = open("mkmkfile", "wb")
makefile.write(
"CC?=gcc\n" +
"LINK?=gcc\n" +
"CCFLAGS=-Os -g -Wall -Wextra -pedantic -Werror -ansi\n" +
"LINKFLAGS=-g\n\n")
def NumFilesShareDepends(files, depends):
num = 0
for file in files:
missed = False
for d in depends:
if d["name"] not in file["depends"]:
missed = True
break
if not missed:
num += 1
if len(files) != 0:
all_file_depends = []
for d in files[0]["depends"]:
all_file_depends.append(d)
unified_depends = {}
for file in files:
i = 0
depends = file["depends"]
if len(depends) > 4:
while i < len(all_file_depends):
if all_file_depends[i] not in depends:
all_file_depends.pop(i)
else:
i += 1
for d in depends:
if d in unified_depends:
unified_depends[d] += 1
else:
unified_depends[d] = 1
# Sort the most used headers, breaking once we find a set that more than a half of the files require.
unified_depends_list = []
for key, value in unified_depends.iteritems():
if key in all_file_depends:
continue
i = 0
while i < len(unified_depends_list):
if unified_depends_list[i]["num"] < value:
break
else:
i += 1
unified_depends_list.insert(i, {"name":key, "num":value})
num_to_use = len(files) / 10
i = 0
unified_depends = []
while i < num_to_use:
unified_depends.append(unified_depends_list[i]["name"])
i+=1
makefile.write("UNIFIED_HEADERS=")
for d in unified_depends:
makefile.write(d)
makefile.write(" ")
makefile.write("\n\n")
for file in files:
i = 0
marked = False
while i < len(file["depends"]):
if file["depends"][i] in unified_depends:
marked = True
file["depends"].pop(i)
else:
i += 1
if marked:
file["depends"].insert(1, "$(UNIFIED_HEADERS)")
if len(all_file_depends) > 0:
makefile.write("HEADERS=")
for d in all_file_depends:
makefile.write(d)
makefile.write(" ")
makefile.write("\n\n")
for file in files:
i = 0
marked = False
while i < len(file["depends"]):
if file["depends"][i] in all_file_depends:
marked = True
file["depends"].pop(i)
else:
i += 1
if marked:
file["depends"].insert(1, "$(HEADERS)")
objs = ""
for file in files:
objs += " " + file["path"] + ".o"
makefile.write("OBJS=")
makefile.write(objs)
makefile.write("\n\nall: a.out\n\n")
for file in files:
WriteTarget(makefile, file["path"], file["depends"])
makefile.write("\n")
makefile.write("a.out: $(OBJS)\n\t$(LINK) $(LINKFLAGS) $(OBJS) -o a.out\n")
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment