File: makemake

package info (click to toggle)
abinit 9.10.4-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 518,712 kB
  • sloc: xml: 877,568; f90: 577,240; python: 80,760; perl: 7,019; ansic: 4,585; sh: 1,925; javascript: 601; fortran: 557; cpp: 454; objc: 323; makefile: 77; csh: 42; pascal: 31
file content (738 lines) | stat: -rwxr-xr-x 30,374 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
#!/usr/bin/env python3
#
# Copyright (C) 2011-2022 ABINIT Group (Yann Pouillon)
#
# This file is part of the ABINIT software package. For license information,
# please see the COPYING file in the top-level directory of the ABINIT source
# distribution.
#
from __future__ import print_function, division, absolute_import #, unicode_literals

try:
    from ConfigParser import ConfigParser
except ImportError:
    from configparser import ConfigParser
from time import gmtime, strftime

import os
import re
import stat
import sys

py2 = sys.version_info[0] <= 2

if sys.version[0:3] < "2.7":
    sys.stderr.write("makemake requires Python version 2.7 or above. Exiting.")
    sys.exit(1)

from subprocess import Popen, PIPE
import shlex

def getstatusoutput(command):
    if py2:
        process = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
    else:
        process = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)
    out, _ = process.communicate()
    return (process.returncode, out)

# ---------------------------------------------------------------------------- #

#
# ABINIT blocks (split of the source tree)
#

abinit_blocks = {
  "common": "shared/common/src",
  "core": "src",
  "libpaw": "shared/libpaw",
}

# ---------------------------------------------------------------------------- #

#
# Internal classes and functions
#

# Personalized configuration parser
class MyConfigParser(ConfigParser):

  def optionxform(self, option):
    return str(option)

                    # ------------------------------------ #

# Display section header
def print_header(name, title):

  print("[%s] === %s ===" % (name, title))

                    # ------------------------------------ #

# Display message
def print_message(name, title):

  print("[%s] %s" % (name, title))

                    # ------------------------------------ #

# Run external commands and check for errors
def run_script(name, title, cmdline, stop_on_error=True,
      indent_output=True):

  print("[%s]   %s" % (name, title))
  (ret, msg) = getstatusoutput(cmdline + " 2>&1")
  if ( msg != "" ):
    if ( indent_output ):
      sys.stderr.write("    " + re.sub("\n", "\n    ", msg) + "\n")
    else:
      sys.stderr.write(msg + "\n")
  if ( (ret != 0) and stop_on_error ):
    sys.stderr.write("cmdline: %s\n" % cmdline)
    sys.stderr.write("[%s] Aborting now! (ret = %d)\n" % (name, ret))
    sys.exit(1)

  return ret

                    # ------------------------------------ #

# Translate version strings into usable numbers
def translate_version(name, version_string):

  # Init
  ret = version_string
  ret = ret.split(".")

  # Force x.y.z version numbers
  while ( len(ret) < 3 ):
    ret.append("0")
  if ( len(ret) > 3 ):
    ret = ret[0:3]

  # Force 2 digits
  for i in range(len(ret)):
    try:
      if ( int(ret[i]) < 10 ):
        ret[i] = "0"+ret[i]
      elif ( int(ret[i]) > 99 ):
        sys.stderr.write(
          "[%s] Error: cannot handle 3-digit version numbers\n" % (name))
        sys.stderr.write("[%s] Aborting now!\n" % (name))
        sys.exit(1)
    except ValueError:
      if ( (i == 2) and (re.match("^[0-9][a-z]$", ret[i])) ):
        ret[i] = re.sub("[a-z]", "", ret[i])
        if ( len(ret[i]) < 2 ):
          ret[i] = "0" + ret[i]
      else:
        sys.stderr.write(
          "[%s] WARNING: invalid version number '%s' set to 0\n" % \
            (name, ret[i]))
        ret[i] = "00"

  # Finish
  ret = int("".join(ret))

  return ret

# ---------------------------------------------------------------------------- #

#
# Main program
#

# Initial setup
my_name     = "makemake"
my_configs  = {
  "make":"config/specs/makemake.conf",
  "bsys":"config/specs/buildsys.conf",
  "bins":"config/specs/binaries.conf",
  "libs":"config/specs/corelibs.conf",
  "fbks":"config/specs/fbversion.conf"}

# Check if we are in the top of the ABINIT source tree
if ( not os.path.exists("configure.ac") or
     not os.path.exists("src/98_main/abinit.F90") ):
  sys.stderr.write("[%s] You must be in the top of an ABINIT source tree!\n" % \
    (my_name))
  sys.stderr.write("[%s] Aborting now!\n" % (my_name))
  sys.exit(1)

# Check if we have config files
if ( os.path.exists(my_configs["make"]) ):
  mcnf = MyConfigParser()
  mcnf.read(my_configs["make"])
else:
  sys.stderr.write("[%s] Could not find config file (%s)" % \
    (my_name, my_configs["make"]))
  sys.stderr.write("[%s] Aborting now!" % (my_name))
  sys.exit(10)
if ( os.path.exists(my_configs["bsys"]) ):
  bcnf = MyConfigParser()
  bcnf.read(my_configs["bsys"])
else:
  sys.stderr.write("[%s] Could not find config file (%s)" % \
    (my_name, my_configs["bsys"]))
  sys.stderr.write("[%s] Aborting now!" % (my_name))
  sys.exit(11)
if ( os.path.exists(my_configs["bins"]) ):
  xcnf = MyConfigParser()
  xcnf.read(my_configs["bins"])
else:
  sys.stderr.write("[%s] Could not find config file (%s)" % \
    (my_name, my_configs["bins"]))
  sys.stderr.write("[%s] Aborting now!" % (my_name))
  sys.exit(12)
if ( os.path.exists(my_configs["libs"]) ):
  lcnf = MyConfigParser()
  lcnf.read(my_configs["libs"])
else:
  sys.stderr.write("[%s] Could not find config file (%s)" % \
    (my_name, my_configs["bins"]))
  sys.stderr.write("[%s] Aborting now!" % (my_name))
  sys.exit(13)
if ( not os.path.exists(my_configs["fbks"]) ):
  sys.stderr.write("[%s] Could not find config file (%s)" % \
    (my_name, my_configs["fbks"]))
  sys.stderr.write("[%s] Aborting now!" % (my_name))
  sys.exit(14)

# Parse command-line arguments
from optparse import OptionParser
my_help = "Usage: %prog [options] vdW-DF_file"
parser = OptionParser(usage=my_help, version="%prog for Abinit 9")
parser.add_option("-a", "--without-autotools", action="store_false",
  dest="run_autotools", default=True,
  help="Skip Autotools-related operations")
parser.add_option("-b", "--without-buildsys", action="store_false",
  dest="run_buildsys", default=True,
  help="Skip build-system update")
parser.add_option("-c", "--clean", action="store_true",
  dest="run_clean", default=False,
  help="Clean source tree")
parser.add_option("-k", "--keep-source", action="store_false",
  dest="run_wipe", default=True,
  help="Keep script-generated files when cleaning source tree")
parser.add_option("-m", "--without-makefiles", action="store_false",
  dest="run_makefiles", default=True,
  help="Skip makefile generation")
parser.add_option("-n", "--no-split", action="store_false",
  dest="split_source", default=True,
  help="Behave as if the source tree were not split")
parser.add_option("-s", "--without-source", action="store_false",
  dest="run_source", default=True,
  help="Skip source tree update (will skip abisrc as well)")
parser.add_option("-t", "--toggle", action="store", metavar="LIST",
  dest="toggle",
  help="Comma-separated list of subsystems to toggle")
parser.add_option("-x", "--without-subsystems", action="store_false",
  dest="run_subsystems", default=True,
  help="Skip subsystem synchronization")
(opts, args) = parser.parse_args()

# What time is it?
now = strftime("%Y/%m/%d %H:%M:%S +0000", gmtime())
try:
  start_time = int(strftime("%s", gmtime()))
except:
  start_time = 0

# Banner
print_message(my_name, "Starting at %s" % (now))
print_message(my_name, "-------------------------------------")

# Make sure the directory tree is writable
print_header(my_name, "Source tree consistency")
run_script(my_name, "Enabling write permission for all dirs & files",
  "chmod -R u+w .")

# Special case: clean-up
if ( opts.run_clean ):
  my_name = "abiclean"
  print_header(my_name, "Temporary directories and files")
  run_script(my_name, "Removing Bazaar backup files",
    "find src -name '*.~[0-9]~' -exec rm -f {} \;")
  run_script(my_name, "Removing temporary build dirs",
    "rm -rf tmp*")
  run_script(my_name, "Removing temporary test dirs",
    "find . -depth -name 'tmp-*' -exec rm -rf {} \;")
  run_script(my_name, "Removing old files",
    "find src -name '*.old' -exec rm -f {} \;")
  run_script(my_name, "Removing compiled Python files",
    "find . -name '*.pyc' -o -name '*.pyo' -exec rm -f {} \;")
  run_script(my_name, "Removing compiled Python cache directories",
    "find . -depth -name '__pycache__' -exec rm -rf {} \;")
  run_script(my_name, "Removing symbolic links in common",
    "find shared/common/src -type l -exec rm -f {} \;")
  run_script(my_name, "Removing symbolic links in core",
    "find src -type l -exec rm -f {} \;")

  print_header(my_name, "Abinit scripts outputs")
  run_script(my_name, "Removing file lists",
    "rm -f config/dist/auto-*.lst")
  run_script(my_name, "Removing M4 macros",
    "rm -f config/m4/auto-*.m4")
  #run_script(my_name, "Removing abilint outputs ",
  #  "rm -f .abilint abilint.log abilint.out")
  run_script(my_name, "Removing configuration dumper input",
    "rm -f config.dump.in")
  run_script(my_name, "Removing source split scripts",
    "rm -rf config/split")
  for block in sorted(abinit_blocks.keys()):
    run_script(my_name, "Removing abinit.dep files in %s" % block,
      "find %s -name 'abinit.dep' -exec rm {} \;" % abinit_blocks[block])
    run_script(my_name, "Removing abinit.dir files in %s" % block,
      "find %s -name 'abinit.dir' -exec rm {} \;" % abinit_blocks[block])
    run_script(my_name, "Removing abirules logs in %s" % block,
      "rm -f %s/tmp-abirules.log" % abinit_blocks[block])
    run_script(my_name, "Removing abirules outputs in %s" % block,
      "find %s -name '*.abirules' -exec rm -f {} \;" % abinit_blocks[block])
    run_script(my_name, "Removing abiauty outputs in %s" % block,
      "find %s -name '*.abiauty' -exec rm -f {} \;" % abinit_blocks[block])

  print_header(my_name, "Core-managed documentation")
  run_script(my_name, "Removing certified build examples",
    "rm -f doc/build/config-examples/*.ac")
  run_script(my_name, "Removing uncertified build examples",
    "rm -f doc/build/config-examples/uncertified/*.ac")
  run_script(my_name, "Removing RoboDOC tarball",
    "rm -f robodoc-html*.tar.gz")

  # Identify subdirs to clean, delegate the rest to the subsystems
  print_header(my_name, "Core-managed build files")
  run_script(my_name, "Removing top Makefiles",
    "rm -f Makefile.am Makefile.in Makefile")
  cln_dirs = ["."]
  for bsub in bcnf.sections():
    if ( bcnf.get(bsub, "type") in ("master", "subsystem") ):
      cln_dirs += bcnf.get(bsub, "subdirs").split()
  for dcln in cln_dirs:
    run_script(my_name, "Removing local data in %s/" % dcln,
      "rm -f %s/config/local/*" % dcln)
    run_script(my_name, "Removing autoheader outputs in %s/" % dcln,
      "cd %s && rm -f config.h.in* config.h" % dcln)
    run_script(my_name, "Removing autoconf outputs in %s/" % dcln,
      "cd %s && rm -rf aclocal.m4 autom4te.cache configure confstat*" % dcln)
    if ( os.path.isdir("%s/config/gnu" % dcln) ):
      run_script(my_name, "Removing automake helpers in %s/" % dcln,
        "cd %s/config/gnu && rm -f compile config.guess config.sub depcomp install-sh ltmain.sh missing" % dcln)
    run_script(my_name, "Removing configure logs in %s/" % dcln,
      "cd %s && rm -f core config.log config.status stamp-h1" % dcln)
    if ( dcln != "." ):
      run_script(my_name, "Removing .deps dirs in %s/" % dcln,
        "find %s -depth -name '.deps' -exec rm -rf {} \;" % dcln)
      run_script(my_name, "Removing Makefile.am files in %s/" % dcln,
        "find %s -name Makefile.am -exec rm -f {} \;" % dcln)
      run_script(my_name, "Removing Makefile.in files in %s/" % dcln,
        "find %s -name Makefile.in -exec rm -f {} \;" % dcln)
      run_script(my_name, "Removing Makefile files in %s/" % dcln,
        "find %s -name Makefile -exec rm -f {} \;" % dcln)
      run_script(my_name, "Removing libraries and object files in %s/" % dcln,
        "find %s -name '*.a' -o -name '*.o' -exec rm {} \;" % dcln)
  for block in sorted(abinit_blocks.keys()):
    run_script(my_name, "Removing binary Fortran modules in %s" % block,
      "find %s -name '*.mod' -exec rm {} \;" % abinit_blocks[block])
  run_script(my_name, "Removing Python-generated files in src/",
    "find src -name '*.pickle' -exec rm {} \;")
  abinit_bins = xcnf.sections()
  abinit_bins.sort()
  abinit_bins = "src/98_main/" + " src/98_main/".join(abinit_bins)
  run_script(my_name, "Removing main Abinit binaries",
    "rm -f %s" % (abinit_bins))

  print_header(my_name, "Script-generated source files")
  if ( opts.run_wipe ):
    run_script(my_name, "Removing Fortran interfaces",
      "find src -name 'interfaces_*.F90' -exec rm {} \;")
    run_script(my_name, "Removing CPP options dumper routine",
      "rm -f shared/common/src/14_hidewrite/m_cppopts_dumper.F90")
    run_script(my_name, "Removing optimization flags dumper routine",
      "rm -f shared/common/src/14_hidewrite/m_optim_dumper.F90")
  else:
    print_message(my_name,
      "*** Skipping script-generated source file removal ***")

  print_header(my_name, "Files produced by the configure script")
  run_script(my_name, "Removing top config.* files",
    "rm -f config.dump config.mk config.optim config.pc config.py config.sh")
  run_script(my_name, "Removing Fortran modules containing package info",
    "rm -f shared/common/src/14_hidewrite/m_build_info.F90")

  print_header(my_name, "Subsystems")
  run_script(my_name, "Removing copied files in shared/common",
    "/bin/rm -f shared/common/AUTHORS shared/common/COPYING shared/common/ChangeLog shared/common/NEWS shared/common/README shared/common/README.md")
  for subsys in bcnf.sections():
    if ( bcnf.get(subsys, "type") == "subsystem" ):
      for subdir in bcnf.get(subsys, "subdirs").split():
        run_script(my_name, "Sluicing out the %s subsystem (subdir: %s)" % \
          (subsys, subdir),
          "cd %s && ./wipeout.sh" % subdir, indent_output=False)
    elif ( bcnf.get(subsys, "type") == "data" ):
      for subdir in bcnf.get(subsys, "subdirs").split():
        run_script(my_name, "Removing Makefile.am files in %s/" % subdir,
          "rm -f %s/Makefile.am" % subdir)
        run_script(my_name, "Removing Makefile.in files in %s/" % subdir,
          "rm -f %s/Makefile.in" % subdir)
        run_script(my_name, "Removing Makefile files in %s/" % subdir,
          "rm -f %s/Makefile" % subdir)

  run_script(my_name, "Removing byte-compiled ABINIT files",
    "find . -name 'abinit.srcc' -exec rm {} \;")
  run_script(my_name, "Removing byte-compiled Python files",
    "find . -name '*.py[co]' -exec rm {} \;")
  run_script(my_name, "Removing Python cache dirs",
    "find . -depth -name '__pycache__' -exec rm -r {} \;")
  run_script(my_name, "Removing abisrc.py Pickle files",
    "find . -depth -name '_project_py[23].pickle' -exec rm {} \;")
  run_script(my_name, "Removing abisrc output files",
    "rm -f abisrc.stderr abisrc.stdout")

  # Remove LibPAW symlink
  libpaw_dir = [item for item in lcnf.sections() \
    if ( lcnf.get(item, "parent") == "libpaw" )][0]
  libpaw_ln = os.path.join("shared", "common", "src", libpaw_dir)
  if ( os.path.exists(libpaw_ln) ):
    if ( os.path.islink(libpaw_ln) ):
      os.remove(libpaw_ln)
    else:
      raise OSError("a file is blocking the way: '%s' is not a symlink" % libpaw_ln)

  now = strftime("%Y/%m/%d %H:%M:%S +0000", gmtime())
  print_message(my_name, "--------------------------------------")
  print_message(my_name, "Finishing at %s" % (now))
  try:
    end_time = int(strftime("%s", gmtime()))
  except:
    end_time = 0
  print_message(my_name, "Time elapsed: %ds" % (end_time - start_time))
  sys.exit(0)

# Get Autotools versions
(m4_ret, m4_version) = getstatusoutput("m4 --version | sed 's/o/ /g' ")
(ac_ret, ac_version) = getstatusoutput("autoconf --version")
(am_ret, am_version) = getstatusoutput("automake --version")
(lt_ret, lt_version) = getstatusoutput("libtool  --version")

# Extract and process version numbers
if ( m4_ret == 0 ):
  m4_version = m4_version.split("\n")[0]
  m4_version = re.sub(r"^(GNU [Mm]4|m4 \(GNU M4\)) ", "", m4_version)
  m4_version = re.sub(" .*", "", m4_version)
  m4_version = translate_version(my_name, m4_version)
else:
  m4_version = 0

if ( ac_ret == 0 ):
  ac_version = ac_version.split("\n")[0]
  ac_version = re.sub(".*\(GNU Autoconf\) ", "", ac_version)
  ac_version = re.sub(" .*", "", ac_version)
  ac_version = translate_version(my_name, ac_version)
else:
  ac_version = 0

if ( am_ret == 0 ):
  am_version = am_version.split("\n")[0]
  am_version = re.sub(".*\(GNU automake\) ", "", am_version)
  am_version = re.sub(" .*", "", am_version)
  am_version = translate_version(my_name, am_version)
else:
  am_version = 0

if ( lt_ret == 0 ):
  lt_version = lt_version.split("\n")[0]
  lt_version = re.sub(".*\(GNU libtool\) ", "", lt_version)
  lt_version = re.sub(" .*", "", lt_version)
  lt_version = translate_version(my_name, lt_version)
else:
  lt_version = 0

if ( m4_version < 10408 ):
  sys.stderr.write("[%s] Error: M4 is too old (%d) - " % \
    (my_name, m4_version) + \
    "please install v1.4.8 or above\n%s: Aborting now\n" % (my_name))
  sys.exit(10)

if ( ac_version < 26100 ):
  sys.stderr.write("[%s] Error: Autoconf is too old (%d) - " % \
    (my_name, ac_version) + \
    "please install v2.61 or above\n%s: Aborting now\n" % (my_name))
  sys.exit(20)

if ( am_version < 11000 ):
  sys.stderr.write("[%s] Error: Automake is too old (%d) - " % \
    (my_name, am_version) + \
    "please install v1.10 or above\n%s: Aborting now\n" % (my_name))
  sys.exit(30)

# Make version information available to other scripts
at_info = open("config/local/autotools.sh", "wt")
at_info.write("""# Autotools version information
abi_m4_version="%6.6d"
abi_ac_version="%6.6d"
abi_am_version="%6.6d"
abi_lt_version="%6.6d"
""" % (m4_version, ac_version, am_version, lt_version))
at_info.close()

# Update build system
print_header(my_name, "Build system update")

if ( opts.run_buildsys ):
  run_script(my_name, "Resetting configuration dumper",
    "./config/scripts/make-config-dump-in")
  run_script(my_name, "Generating macros for the Autotools",
    "./config/scripts/make-macros-autotools")
  run_script(my_name, "Generating macros for dumpers",
    "./config/scripts/make-macros-dumpers")
  run_script(my_name, "Generating macros for environment variables",
    "./config/scripts/make-macros-environment")
  run_script(my_name, "Generating macros for command-line options",
    "./config/scripts/make-macros-options")
  run_script(my_name, "Generating macros for hints",
    "./config/scripts/make-macros-hints")
  run_script(my_name, "Generating macros for debugging",
    "./config/scripts/make-macros-debug")
  run_script(my_name, "Generating macros for default optimizations",
    "./config/scripts/make-macros-optim")
  run_script(my_name, "Generating macros for per-directory optimizations",
    "./config/scripts/make-macros-dirflags")
  run_script(my_name, "Generating macros for core libraries",
    "./config/scripts/make-macros-corelibs")
  run_script(my_name, "Generating macros for feature triggers",
    "./config/scripts/make-macros-triggers")
  run_script(my_name, "Generating macros for configure output",
    "./config/scripts/make-macros-output")
  run_script(my_name, "Generating source split symlink maker",
    "./config/scripts/make-symlink-maker")
else:
  print_message(my_name, "*** Skipping build system update ***")

# Update source tree
print_header(my_name, "Source tree update")

if ( opts.run_source ):
  run_script(my_name, "Removing build examples",
    "./config/scripts/clean-build-examples")
  run_script(my_name, "Generating build examples",
    "./config/scripts/make-build-examples")
  run_script(my_name, "Generating CPP option dumper",
    "./config/scripts/make-cppopts-dumper")

  # Create a symlink to the sources of LibPAW, so that the same naming
  # conventions can be used in the whole shared section of ABINIT
  libpaw_dir = [item for item in lcnf.sections() \
    if ( lcnf.get(item, "parent") == "libpaw" )][0]
  src = os.path.join("..", "..", "libpaw", "src")
  dst = os.path.join("shared", "common", "src", libpaw_dir)
  if ( os.path.islink(dst) ):
    os.remove(dst)
  elif ( os.path.exists(dst) ):
    raise OSError("a file is blocking the way: '%s' is not a symlink" % dst)
  os.symlink(src, dst)

  # Call abisrc to build dependency graph and create files for buildsystem
  #abisrc_cmdline = "./abisrc.py validate"
  abisrc_cmdline = "./abisrc.py makemake > abisrc.stdout 2> abisrc.stderr"
  print_message(my_name, "---> running %s" % (abisrc_cmdline))
  abisrc_exitcode = os.system(abisrc_cmdline)

  if abisrc_exitcode != 0:
    sys.stderr.write("""
       ****************************************************************
       ***                     FATAL ERROR!                         ***
       ****************************************************************
       *** The abisrc.py script returned a non-zero exit status.    ***
       *** This usually means that the script found subroutines or  ***
       *** functions that are not declared inside modules or that   ***
       *** there is a syntax error in the Fortran code or a bug     ***
       *** See above error message.                                 ***
       ****                                                         ***
       *** Please note that procedures outside Fortran modules are  ***
       *** not allowed any longer. See abisrc.stderr for details    ***
       *** about the errors.                                        ***
       ****************************************************************\n""")
    sys.stderr.write("[%s] Aborting now\n" % (my_name))
    sys.exit(1)
else:
  print_message(my_name, "*** Skipping source tree update ***")

# Generate subsystem data
print_header(my_name, "Synchronization of subsystems")

if ( opts.run_subsystems ):
  run_script(my_name, "Wiping out former file lists for subsystems",
    "rm -f config/dist/auto-*.lst")

  sub_togls = []
  togl_mode = {"attached":"detached", "detached":"attached"}

  if ( opts.toggle ):
    sub_togls = opts.toggle.split(",")
    sub_mlist = open("config/dist/custom-modes.lst", "wt")

  for subsys in bcnf.sections():
    if ( bcnf.get(subsys, "type") == "subsystem" ):
      for subdir in bcnf.get(subsys, "subdirs").split():
        run_script(my_name, "Sluicing out the %s subsystem (subdir: %s)" % \
          (subsys, subdir),
          "cd %s && ./wipeout.sh" % subsys, indent_output=False)
        run_script(my_name, "Refreshing the %s subsystem (subdir: %s)" % \
          (subsys, subdir),
          "cd %s && ./autogen.sh" % subsys,
          indent_output=False)
      sub_mode = bcnf.get(subsys, "mode")
      if ( subsys in sub_togls ):
        sub_mode = togl_mode[sub_mode]
        sub_mlist.write("%s %s\n" % (subsys, sub_mode))

  if ( opts.toggle ):
    sub_mlist.close()

  run_script(my_name, "Generating file lists for subsystems",
    "./config/scripts/make-file-lists")
  run_script(my_name, "Generating macros for subsystems",
    "./config/scripts/make-macros-subsystems")
  run_script(my_name, "Populating required files in shared/common",
    "/bin/cp -f AUTHORS COPYING ChangeLog NEWS README README.md shared/common")
else:
  print_message(my_name, "*** Skipping synchronization of subsystems ***")

# Generate makefiles
print_header(my_name, "Makefile generation (for Automake)")

if ( opts.run_makefiles ):
  run_script(my_name, "Generating makefiles for core libraries",
    "./config/scripts/make-makefiles-corelibs")
  run_script(my_name, "Generating makefiles for binaries",
    "./config/scripts/make-makefiles-binaries")
  run_script(my_name, "Generating makefiles for exports",
    "./config/scripts/make-makefiles-exports")
  run_script(my_name, "Generating makefiles for abichecks",
    "./config/scripts/make-makefiles-abichecks")
  run_script(my_name, "Generating intermediate makefiles",
    "./config/scripts/make-makefiles-inter")
  run_script(my_name, "Generating top makefile",
    "./config/scripts/make-makefiles-top")
  run_script(my_name, "Adding individual binary targets to top makefile",
    "./config/scripts/add-targets-binaries")
  run_script(my_name, "Adding individual library targets to top makefile",
    "./config/scripts/add-targets-libraries")
else:
  print_message(my_name, "*** Skipping makefile generation ***")

# Build Autotools framework
# Note: do not use "automake --force-missing", as it overwrites the
#       INSTALL file.
print_header(my_name, "Autotools framework generation")

if ( opts.run_autotools ):
  run_script(my_name, "Generating aclocal.m4",
    "aclocal -I config/m4")
  run_script(my_name, "Generating config.h.in",
    "autoheader")
  run_script(my_name, "Generating configure script",
    "autoconf")
  #run_script(my_name, "Generating libtool scripts",
  #  "libtoolize --automake --copy --force")
  run_script(my_name, "Generating Makefile.in for each directory",
    "automake --add-missing --copy")
else:
  print_message(my_name, "*** Skipping Autotools framework generation ***")

# Display warnings
if ( m4_version < 10415 ):
  print("""
     ****************************************************************
     ***                        WARNING!                          ***
     ****************************************************************
     ***                                                          ***
     *** Versions of M4 prior to 1.4.15 are known to crash the    ***
     *** configure script in random situations and have a few     ***
     *** security issues. Use at your own risks.                  ***
     ***                                                          ***
     *** We highly recommend you to upgrade to M4 1.4.17 for a    ***
     *** smoother experience with Fortran 2003 compilers.         ***
     ***                                                          ***
     *** Thanks a lot in advance for your understanding.          ***
     ***                                                          ***
     ****************************************************************
""")

if ( ac_version < 26800 ):
  print("""
     ****************************************************************
     ***                        WARNING!                          ***
     ****************************************************************
     ***                                                          ***
     *** You are using a highly outdated version of Autoconf.     ***
     ***                                                          ***
     *** Autoconf 2.68, released in 2010, fixes regressions,      ***
     *** Fortran-related bugs, and performance issues,            ***
     *** introduced in Autoconf versions from 2.64 to 2.67.       ***
     *** Autoconf 2.69 has been the reference version since 2012  ***
     *** and has become the default one in most Unix systems      ***
     *** since 2014.                                              ***
     ***                                                          ***
     *** You are thus strongly advised to upgrade your version    ***
     *** of Autoconf if you want to contribute to Abinit with     ***
     *** a fully functional build system. Otherwise you might     ***
     *** encounter strange issues difficult to understand and     ***
     *** impossible to reproduce by other developers.             ***
     ***                                                          ***
     *** Thanks a lot in advance for your understanding.          ***
     ***                                                          ***
     ****************************************************************
""")

if ( am_version < 11202 ):
  print("""
     ****************************************************************
     ***                        WARNING!                          ***
     ****************************************************************
     ***                                                          ***
     *** Automake versions prior to 1.12.2 contain several        ***
     *** portability bugs, an incomplete support for Fortran      ***
     *** 2003 and a security issue (CVE-2012-3386). More recent   ***
     *** versions, published since 2012, are now available and    ***
     *** fix many long-standing bugs. The minimum suitable        ***
     *** version for Abinit is 1.12.6, and the recommended one    ***
     *** is 1.15.                                                 ***
     ***                                                          ***
     *** You are strongly advised to upgrade your version of      ***
     *** Automake at your earliest convenience. Otherwise you     ***
     *** might experience strange issues difficult to understand  ***
     *** and impossible to reproduce by other developers.         ***
     ***                                                          ***
     *** Thanks a lot in advance for your understanding.          ***
     ***                                                          ***
     ****************************************************************
""")

if ( lt_version < 20402 ):
  print("""
     ****************************************************************
     ***                        WARNING!                          ***
     ****************************************************************
     ***                                                          ***
     *** Libtool integration into ABINIT has now started. You     ***
     *** will have to install Libtool 2.4.2 or later if you want  ***
     *** to benefit from the advanced features it provides.       ***
     ***                                                          ***
     *** Some features of the build system will be disabled until ***
     *** you install a proper version of Libtool. The recommended ***
     *** one is 2.4.6.                                            ***
     ***                                                          ***
     ****************************************************************
""")

# Footer
now = strftime("%Y/%m/%d %H:%M:%S +0000", gmtime())
print_message(my_name, "--------------------------------------")
print_message(my_name, "Finishing at %s" % (now))

# The end
try:
  end_time = int(strftime("%s", gmtime()))
except:
  end_time = 0
print_message(my_name, "Time elapsed: %ds" % (end_time - start_time))