updated on Sun Jan 22 16:00:49 UTC 2012
[aur-mirror.git] / boost-build-nightly / boost-build-config
blob9631210ad5978b64b3f6ac5e0213659eab2e8638
1 #!/usr/bin/env python3
2 '''
3 This tool is used to generate user-config.jam and site-config.jam
4 for boost library automatically. 
5 '''
6 import os
7 import os.path
9 __author__    = "Tianjiao Yin (ytj000@gamil.com)"
10 __date__      = "Fri, 24 Jun 2011 18:58:58 +0800"
11 __copyright__ = "Copyright 2011 Tianjiao Yin"
12 __license__   = "WTFPLv2"
13 __version__   = "0.3"
15 # Default path
16 site_path = "/etc/site-config.jam"
17 boostbook_path = "/usr/share/boostbook"
19 # Constant default path
20 QT_PATH = "/usr/share/qt" # useless useless
21 DOCBOOK_PATH = "/usr/share/xml/docbook/"
23 # Supporting list
24 TOOLS_LIST = ("specific_gcc", "python", "mpi", "boostbook")
26 # "using name ;" if name is executable
27 # Trivial tools don't need a special function.
28 # May be I should remove this and write functions for all;
29 TRIVIAL_TOOLS = ("gcc", "doxygen", "quickbook")
31 SITE_DATA = r'''# Copyright 2003, 2005 Douglas Gregor
32 # Copyright 2004 John Maddock
33 # Copyright 2002, 2003, 2004, 2007 Vladimir Prus
34 # Distributed under the Boost Software License, Version 1.0.
35 # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
37 #   This file is used to configure your Boost.Build installation. You can modify
38 # this file in place, or you can place it in a permanent location so that it
39 # does not get overwritten should you get a new version of Boost.Build. See:
41 #   http://www.boost.org/boost-build2/doc/html/bbv2/overview/configuration.html
43 # for documentation about possible permanent locations.
45 #   This file specifies which toolsets (C++ compilers), libraries, and other
46 # tools are available. Often, you should be able to just uncomment existing
47 # example lines and adjust them to taste. The complete list of supported tools,
48 # and configuration instructions can be found at:
50 #   http://boost.org/boost-build2/doc/html/bbv2/reference/tools.html
53 #   This file uses Jam language syntax to describe available tools. Mostly,
54 # there are 'using' lines, that contain the name of the used tools, and
55 # parameters to pass to those tools -- where paremeters are separated by
56 # semicolons. Important syntax notes:
58 #   - Both ':' and ';' must be separated from other tokens by whitespace
59 #   - The '\' symbol is a quote character, so when specifying Windows paths you
60 #     should use '/' or '\\' instead.
62 # More details about the syntax can be found at:
64 #   http://boost.org/boost-build2/doc/html/bbv2/advanced.html#bbv2.advanced.jam_language
68 # -------------------
69 # MSVC configuration.
70 # -------------------
72 # Configure msvc (default version, searched for in standard locations and PATH).
73 # using msvc ;
75 # Configure specific msvc version (searched for in standard locations and PATH).
76 # using msvc : 8.0 ;
79 # ----------------------
80 # Borland configuration.
81 # ----------------------
82 # using borland ;
85 # ----------------------
86 # STLPort configuration.
87 # ----------------------
89 #   Configure specifying location of STLPort headers. Libraries must be either
90 # not needed or available to the compiler by default.
91 # using stlport : : /usr/include/stlport ;
93 # Configure specifying location of both headers and libraries explicitly.
94 # using stlport : : /usr/include/stlport /usr/lib ;
97 # ------------------
98 # GCC configuration.
99 # ------------------
101 # Configure gcc (default version).
102 {gcc}
104 # Configure specific gcc version, giving alternative name to use.
105 {specific_gcc}
108 # -----------------
109 # QT configuration.
110 # -----------------
112 # Configure assuming QTDIR gives the installation prefix.
113 # using qt ;
115 # Configure with an explicit installation prefix.
116 # using qt : /usr/opt/qt ;
118 # ---------------------
119 # Python configuration.
120 # ---------------------
122 # Configure specific Python version.
123 {python}
126 # ------------------
127 # MPI configuration.
128 # ------------------
129 {mpi}
132 # ------------------------
133 # BoostBook configuration.
134 # ------------------------
135 {boostbook}
138 # ----------------------
139 # Doxygen configuration.
140 # ----------------------
141 {doxygen}
144 # ------------------------
145 # Quickbook configuration.
146 # ------------------------
147 {quickbook}
150 # --------------------
151 # Extra configuration.
152 # --------------------
155 def get_all_exec():
156     '''
157     Find all executable files.
158     Return file_names_dict, paths_list
159     '''
160     def is_exe(fpath):
161         return os.path.exists(fpath) and os.access(fpath, os.X_OK)
162     rec = set()
163     ans = []
164     for path in os.environ["PATH"].split(os.pathsep):
165         if os.path.exists(path):
166             for name in os.listdir(path):
167                 exe_file = os.path.join(path, name)
168                 if name not in rec and is_exe(exe_file):
169                     ans.append(exe_file)
170                     rec.add(name)
171     return rec, ans
173 all_name, all_path = get_all_exec()
175 def specific_gcc():
176     gccs = []
177     for i in all_name:
178         if len(i) > 4 and i[:4] == "g++-":
179             gccs.append("using gcc : {} : {} ;\n".format(i[4:], i))
180     return "\n".join(gccs)
184 def python():
186     def getpyver(cmd):
187         '''
188         Get python version
189         getpyver(python_path) --> python_version
191         Simple example:
192             getpyver("python3") --> "3.2"
193         '''
194         import subprocess
195         p = subprocess.Popen((cmd, "--version"), stderr=subprocess.PIPE)
196         p.wait();
197         p = p.stderr.read().decode('ascii')
198         p = p.split()[1].split('.')
199         return p[0] + '.' + p[1]
201     def get_cpy(cmd):
202         '''
203         Get python configure.
204         '''
205         pyv = getpyver(cmd)
206         pyinc = "/usr/include/python{}mu".format(pyv)
207         if not os.path.isdir(pyinc):
208             pyinc = "/usr/include/python{}".format(pyv)
209         for i in all_path:
210             fpath, fname = os.path.split(i)
211             if "python{}".format(pyv[0]) == fname:
212                 loca = i;
213                 break
214         py = "using python : {} : {} : {} : /usr/lib ;"
215         return py.format(pyv, loca, pyinc)
217     pys = []
219     # We choose python2 as default, so python2 must appear before than python3.
220     if "python2" in all_name:
221         pys.append(get_cpy("python2"))
222     if "python3" in all_name:
223         pys.append(get_cpy("python3"))
224     return "\n".join(pys)
226 def mpi():
227     if "mpicc" in all_name:
228         return "using mpi ;"
229     return ""
231 def boostbook():
232     if not os.path.isdir(boostbook_path): 
233         return ''
234     if not os.path.isdir(DOCBOOK_PATH):
235         return ''
236     s = "using boostbook\n: {DOCBOOK_XSL_DIR}\n: {DOCBOOK_DTD_DIR}\n: {BOOSTBOOK_DIR} ;"
237     ret = {}
238     path = (os.path.join(DOCBOOK_PATH, name) for name in os.listdir(DOCBOOK_PATH))
239     l = [i for i in path if os.path.isdir(i)]
240     xsl, xml = [], []
241     for i in l:
242         if "xsl" in i:
243             xsl.append(i)
244         if "xml" in i:
245             xml.append(i)
247     if not xsl or not xml:
248         return ""
250     # Find the newest version
251     def version_key(version):
252         import re
253         return re.split('\D*', version)
254     
255     ret["BOOSTBOOK_DIR"] = boostbook_path
256     ret["DOCBOOK_XSL_DIR"] = max(xsl, key = version_key)
257     ret["DOCBOOK_DTD_DIR"] = max(xml, key = version_key)
258     return s.format(**ret)
260 def site_config():
261     conf = {}
262     for name in TRIVIAL_TOOLS:
263         conf[name] = "using {} ;".format(name) if name in all_name else ""
264     for name in TOOLS_LIST:
265         conf[name] = globals()[name]()
266     return conf
268 def main():
269     """
270     Generate configuration file for boost build automatically.
271     """
272     global site_path
273     global boostbook_path
274     import argparse
275     parser = argparse.ArgumentParser(
276             # display before help
277             description=main.__doc__,
278             # display after help
279             epilog=("License {}. This is free software. "
280                 "If you are lucky, this program will not delete your /usr. "
281                 "However, It has not been tested widely."
282                 ).format(__license__),
283             )
284     parser.add_argument('-s', '--setup',
285             required=True,
286             action='store_true',
287             help="You have to input this argument, otherwise it will not proceed."
288             )
289     parser.add_argument('--version', 
290             action='version', 
291             version='%(prog)s ' + __version__
292             )
293     parser.add_argument('-o',
294             default=site_path,
295             help="Place the configuration into %(metavar)s (default: %(default)s)",
296             metavar="<file>"
297             )
298     parser.add_argument('-b', "--boostbook_path",
299             default=boostbook_path,
300             help="Boost book directory (default: %(default)s)",
301             metavar="<path>"
302             )
303     parser.add_argument('-a', "--add_tools",
304             nargs=2,
305             # Bad idea:
306             # If using nargs='*' instead,
307             # No need to type quotation marks.
308             # However, it will confuse the user.
309             action='append',
310             help=('Force to add a tool. '
311                 'Simple usage: -a gcc "using gcc : : \\"distcc g++\\" ;" '
312                 ),
313             metavar=("<name>", "<information>")
314             )
315     args = parser.parse_args()
316     site_path = args.o
317     boostbook_path = args.boostbook_path
318     add_conf = {}
319     if args.add_tools:
320         for i in args.add_tools:
321             add_conf[i[0]] = " ".join(i[1:])
322     conf = site_config()
323     conf.update(add_conf)
324     data = SITE_DATA
325     for i in conf:
326         if i not in TOOLS_LIST and i not in TRIVIAL_TOOLS:
327             data += "{" + i + "}\n"
328     data = data.format(**conf)
329     open(site_path,"w").write(data)
331 if __name__ == "__main__":
332     main()