ra4_draw  4bd0201e3d922d42bd545d4b045ed44db33454a4
compile.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 from __future__ import print_function
4 
5 import argparse
6 import shutil
7 import errno
8 import os
9 import subprocess
10 import multiprocessing
11 import sys
12 import fnmatch
13 
15  def __init__(self, src, inc, make, obj, exe):
16  self.src = src
17  self.inc = inc
18  self.make = make
19  self.obj = obj
20  self.exe = exe
21 
22 class Term(object):
23  BLACK = '\033[30m'
24  RED = '\033[31m'
25  GREEN = '\033[32m'
26  YELLOW = '\033[33m'
27  BLUE = '\033[34m'
28  MAGENTA = '\033[35m'
29  CYAN = '\033[36m'
30  WHITE = '\033[37m'
31 
32  BOLD = '\033[1m'
33  UNDERLINE = '\033[4m'
34 
35  END = '\033[0m'
36 
37 def fullPath(path):
38  return os.path.realpath(os.path.abspath(os.path.expanduser(path)))
39 
40 def ensureDir(path):
41  try:
42  os.makedirs(path)
43  except OSError:
44  if not os.path.isdir(path):
45  raise
46 
47 def tryRemove(directory, pattern):
48  if pattern == None:
49  try: shutil.rmtree(directory)
50  except OSError as e:
51  if e.errno != errno.ENOENT:
52  raise
53  finally:
54  return
55 
56  for root, dirs, files in os.walk(fullPath(directory), topdown=False):
57  for f in files:
58  if fnmatch.fnmatch(f, pattern):
59  os.remove(os.path.join(root, f))
60  try: os.rmdir(root)
61  except OSError as e:
62  if e.errno != errno.ENOTEMPTY:
63  raise
64 
65 def clean(dirs):
66  tryRemove(".", "*~")
67  tryRemove(".", "*#")
68  tryRemove(dirs.exe, "*.exe")
69  tryRemove(dirs.make, "*.d")
70  tryRemove(dirs.obj, "*.o")
71  tryRemove(dirs.obj, "*.a")
72  tryRemove(dirs.inc, "baby*.hpp")
73  tryRemove(dirs.src, "baby*.cpp")
74  tryRemove(".", ".subdirs.mk")
75  pass
76 
77 def ensureSubdirs(base, subdirs):
78  for subdir in subdirs:
79  ensureDir(os.path.join(base, subdir))
80 
81 def getSubdirs(base, subdirs):
82  base = fullPath(base)
83  for root, dirs, files in os.walk(base):
84  if root == base: continue
85  subdirs.add(os.path.relpath(root, base))
86 
87 def genSubdirs(dirs):
88  ra4_draw = os.path.dirname(fullPath(__file__))
89  srcdir = fullPath(os.path.join(ra4_draw, dirs.src))
90  incdir = fullPath(os.path.join(ra4_draw, dirs.inc))
91  objdir = fullPath(os.path.join(ra4_draw, dirs.obj))
92  makedir = fullPath(os.path.join(ra4_draw, dirs.make))
93  exedir = fullPath(os.path.join(ra4_draw, dirs.exe))
94 
95  subdirs = set()
96  getSubdirs(srcdir, subdirs)
97  getSubdirs(incdir, subdirs)
98 
99  ensureSubdirs(srcdir, subdirs)
100  ensureSubdirs(incdir, subdirs)
101  ensureSubdirs(objdir, subdirs)
102  ensureSubdirs(makedir, subdirs)
103  ensureSubdirs(exedir, subdirs)
104 
105  return subdirs
106 
107 def writeMakefile(subdirs):
108  ra4_draw = os.path.dirname(fullPath(__file__))
109  with open(os.path.join(ra4_draw, ".subdirs.mk"), "w") as f:
110  for subdir in subdirs:
111  make = os.path.join("$(MAKEDIR)", os.path.join(subdir, "%.d"))
112  cpp = os.path.join("$(SRCDIR)", os.path.join(subdir, "%.cpp"))
113  cxx = os.path.join("$(SRCDIR)", os.path.join(subdir, "%.cxx"))
114  obj = os.path.join("$(OBJDIR)", os.path.join(subdir, "%.o"))
115  exe = os.path.join("$(EXEDIR)", os.path.join(subdir, "%.exe"))
116 
117  f.write("".join((make,": ",cpp,"\n")))
118  f.write("\t$(GET_DEPS)\n\n")
119 
120  f.write("".join((make,": ",cxx,"\n")))
121  f.write("\t$(GET_DEPS)\n\n")
122 
123  f.write("".join((obj,": ",cpp,"\n")))
124  f.write("\t$(COMPILE)\n\n")
125 
126  f.write("".join((obj,": ",cxx,"\n")))
127  f.write("\t$(COMPILE)\n\n")
128 
129  f.write("".join((exe,": ",obj," $(LIBFILE)\n")))
130  f.write("\t$(LINK)\n\n")
131 
132 def genSubdirMake(dirs):
133  subdirs = genSubdirs(dirs)
134  writeMakefile(subdirs)
135 
136 def build(dirs, verbosity):
137  genSubdirs(dirs)
138 
139  command = ["make","-j",str(multiprocessing.cpu_count()),"-k","-r","-R",
140  "SRCDIR="+dirs.src, "INCDIR="+dirs.inc,
141  "MAKEDIR="+dirs.make, "OBJDIR="+dirs.obj, "EXEDIR="+dirs.exe]
142  if verbosity < 1:
143  command.append("--silent")
144  elif verbosity > 1:
145  command.append("--debug")
146  p = subprocess.Popen(command, stderr=subprocess.PIPE)
147  err_msg = p.communicate()[1]
148  if p.returncode == 0:
149  print("\n\n"+Term.GREEN+Term.BOLD
150  +"Compilation succeeded!"
151  +Term.END+"\n")
152  else:
153  print("\n\n"+Term.RED+Term.BOLD
154  +"################ ERRORS AND WARNINGS ################"
155  +Term.END+Term.END+"\n", file=sys.stderr)
156  print(err_msg.decode("utf-8"), file=sys.stderr)
157  print("\n\n"+Term.RED+Term.BOLD
158  +"Compilation failed."
159  +Term.END+"\n", file=sys.stderr)
160  sys.exit(p.returncode)
161 
162 def compile(mode, verbosity, dirs):
163  if mode == "build":
164  build(dirs, verbosity)
165  elif mode == "clean":
166  clean(dirs)
167  elif mode == "set_dirs":
168  genSubdirMake(dirs)
169  elif mode== "print_vars":
170  subprocess.check_call(["make","test","-r","-R","--silent",
171  "SRCDIR="+dirs.src, "INCDIR="+dirs.inc,
172  "MAKEDIR="+dirs.make, "OBJDIR="+dirs.obj, "EXEDIR="+dirs.exe, "print_vars"])
173  else:
174  raise Exception("Unrecognized option: "+mode)
175 
176 if __name__ == "__main__":
177  parser = argparse.ArgumentParser(description = "Compiles ra4_draw code",
178  formatter_class = argparse.ArgumentDefaultsHelpFormatter)
179  parser.add_argument("mode", nargs="?", default="build", choices=["build","clean","set_dirs","print_vars"],
180  help = "Selects which action to perform")
181  parser.add_argument("-v","--verbosity", type=int, default=1, choices=[0,1,2],
182  help = "Set verbosity. Lower = less printing.")
183  parser.add_argument("--src_dir", default = "src",
184  help = "Directory containing .cpp and .cxx files")
185  parser.add_argument("--inc_dir", default = "inc",
186  help = "Directory containing .hpp files")
187  parser.add_argument("--make_dir", default = "bin",
188  help = "Directory in which to store .d files")
189  parser.add_argument("--obj_dir", default = "bin",
190  help = "Directory in which to place .o files")
191  parser.add_argument("--exe_dir", default = "run",
192  help = "Directory in which to store .exe files")
193  args = parser.parse_args()
194 
195  compile(args.mode, args.verbosity,
196  DirStructure(args.src_dir, args.inc_dir, args.make_dir, args.obj_dir, args.exe_dir))
def clean(dirs)
Definition: compile.py:65
def fullPath(path)
Definition: compile.py:37
def build(dirs, verbosity)
Definition: compile.py:136
def genSubdirs(dirs)
Definition: compile.py:87
def compile(mode, verbosity, dirs)
Definition: compile.py:162
def ensureSubdirs(base, subdirs)
Definition: compile.py:77
def tryRemove(directory, pattern)
Definition: compile.py:47
def ensureDir(path)
Definition: compile.py:40
def writeMakefile(subdirs)
Definition: compile.py:107
def __init__(self, src, inc, make, obj, exe)
Definition: compile.py:15
def genSubdirMake(dirs)
Definition: compile.py:132
def getSubdirs(base, subdirs)
Definition: compile.py:81