updated on Thu Jan 26 00:18:00 UTC 2012
[aur-mirror.git] / boost-svn / boost-build-config
blob15f7908cd3ede4b3369a5e381df17f45542409bc
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.2"
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     s = "using boostbook\n: {DOCBOOK_XSL_DIR}\n: {DOCBOOK_DTD_DIR}\n: {BOOSTBOOK_DIR} ;"
235     ret = {}
236     path = (os.path.join(DOCBOOK_PATH, name) for name in os.listdir(DOCBOOK_PATH))
237     l = [i for i in path if os.path.isdir(i)]
238     xsl, xml = [], []
239     for i in l:
240         if "xsl" in i:
241             xsl.append(i)
242         if "xml" in i:
243             xml.append(i)
245     if not xsl or not xml:
246         return ""
248     # Find the newest version
249     def version_key(version):
250         import re
251         return re.split('\D*', version)
252     
253     ret["BOOSTBOOK_DIR"] = boostbook_path
254     ret["DOCBOOK_XSL_DIR"] = max(xsl, key = version_key)
255     ret["DOCBOOK_DTD_DIR"] = max(xml, key = version_key)
256     return s.format(**ret)
258 def site_config():
259     conf = {}
260     for name in TRIVIAL_TOOLS:
261         conf[name] = "using {} ;".format(name) if name in all_name else ""
262     for name in TOOLS_LIST:
263         conf[name] = globals()[name]()
264     return conf
266 def main():
267     """
268     Generate configuration file for boost build automatically.
269     """
270     global site_path
271     global boostbook_path
272     import argparse
273     parser = argparse.ArgumentParser(
274             # display before help
275             description=main.__doc__,
276             # display after help
277             epilog=("License {}. This is free software. "
278                 "If you are lucky, this program will not delete your /usr. "
279                 "However, It has not been tested widely."
280                 ).format(__license__),
281             )
282     parser.add_argument('-s', '--setup',
283             required=True,
284             action='store_true',
285             help="You have to input this argument, otherwise it will not proceed."
286             )
287     parser.add_argument('--version', 
288             action='version', 
289             version='%(prog)s ' + __version__
290             )
291     parser.add_argument('-o',
292             default=site_path,
293             help="Place the configuration into %(metavar)s (default: %(default)s)",
294             metavar="<file>"
295             )
296     parser.add_argument('-b', "--boostbook_path",
297             default=boostbook_path,
298             help="Boost book directory (default: %(default)s)",
299             metavar="<path>"
300             )
301     parser.add_argument('-a', "--add_tools",
302             nargs=2,
303             # Bad idea:
304             # If using nargs='*' instead,
305             # No need to type quotation marks.
306             # However, it will confuse the user.
307             action='append',
308             help=('Force to add a tool. '
309                 'Simple usage: -a gcc "using gcc : : \\"distcc g++\\" ;" '
310                 ),
311             metavar=("<name>", "<information>")
312             )
313     args = parser.parse_args()
314     site_path = args.o
315     boostbook_path = args.boostbook_path
316     add_conf = {}
317     if args.add_tools:
318         for i in args.add_tools:
319             add_conf[i[0]] = " ".join(i[1:])
320     conf = site_config()
321     conf.update(add_conf)
322     data = SITE_DATA
323     for i in conf:
324         if i not in TOOLS_LIST and i not in TRIVIAL_TOOLS:
325             data += "{" + i + "}\n"
326     data = data.format(**conf)
327     open(site_path,"w").write(data)
329 if __name__ == "__main__":
330     main()