abinit/config/scripts/make-makefiles-inter

281 lines
9.0 KiB
Python
Executable File

#!/usr/bin/env python
#
# Copyright (C) 2005-2025 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 sys
class MyConfigParser(ConfigParser):
def optionxform(self,option):
return str(option)
# ---------------------------------------------------------------------------- #
#
# Subroutines
#
# Makefile header
def makefile_header(name,stamp):
return """#
# Makefile for ABINIT -*- Automake -*-
# Generated by %s on %s
#
# IMPORTANT NOTE
#
# Any manual change to this file will systematically be overwritten.
# Please modify the %s script or its config file instead.
#
""" % (name,stamp,name)
def makefile_subdirs(filename,prefix):
ret = ""
re_begin = re.compile("^## BEGIN BUILD$")
re_end = re.compile("^## END BUILD$")
tmp = open(filename, "rt").readlines()
save_line = False
for line in tmp:
if ( re_end.match(line) ):
save_line = False
if ( save_line ):
ret += line
if ( re_begin.match(line) ):
save_line = True
ret = re.sub("#","",ret).strip().split()
ret = ["$(%s%s)" % (prefix,x) for x in ret]
return ret
# ---------------------------------------------------------------------------- #
#
# Main program
#
# Initial setup
my_name = "make-makefiles-inter"
my_configs = {
"libs":"config/specs/corelibs.conf",
"bsys":"config/specs/buildsys.conf",
}
mf_sep = "\n# ---------------------------------------------------------------------------- #\n"
# 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") ):
print("%s: You must be in the top of an ABINIT source tree." % my_name)
print("%s: Aborting now." % my_name)
sys.exit(1)
# Read config file(s)
for cnf_file in my_configs.values():
if ( os.path.exists(cnf_file) ):
if ( re.search(r"\.cf$",cnf_file) ):
exec(compile(open(cnf_file).read(), cnf_file, 'exec'))
else:
print("%s: Could not find config file (%s)." % (my_name,cnf_file))
print("%s: Aborting now." % my_name)
sys.exit(2)
# What time is it?
now = strftime("%Y/%m/%d %H:%M:%S +0000",gmtime())
# Parse configuration
cnf = MyConfigParser()
cnf.read(my_configs["libs"])
abinit_parents = list(set([cnf.get(item, "parent") for item in cnf.sections()]))
# Process available libraries, one parent at a time
for parent in abinit_parents:
# Select parent dir
if ( parent == "common" ):
par_dir = os.path.join("shared", "common", "src")
elif ( parent == "libpaw" ):
par_dir = os.path.join("shared", "libpaw")
else:
par_dir = "src"
# Select subdirs to process
abinit_libs = sorted([item for item in cnf.sections() \
if ( cnf.get(item, "parent") == parent )])
# Extract information for each subdir
lib_specs = {
"abirules": [],
"optional": [],
"subdirs": [],
}
lib_specs["subdirs"] += ["incs", "mods"]
for lib in abinit_libs:
if ( parent == "libpaw" ):
subdir = "src"
else:
subdir = lib
if ( cnf.get(lib, "abirules") == "yes" ):
lib_specs["abirules"].append(subdir)
if ( cnf.get(lib, "optional") == "yes" ):
lib_specs["optional"].append(subdir)
lib_specs["subdirs"].append("$(%s_%s)" % (parent, subdir))
else:
lib_specs["subdirs"].append(subdir)
if ( parent == "core" ):
lib_specs["abirules"].append("98_main")
lib_specs["subdirs"].append("98_main")
# Start Makefile.am
makefile = makefile_header(my_name, now)
# Declare optional subdirs
if ( len(lib_specs["optional"]) > 0):
makefile += "# Optional subdirectories\n"
for subdir in lib_specs["optional"]:
makefile += "if DO_BUILD_{NAME}\n {parent}_{name} = {name}\nelse\n {parent}_{name} =\nendif\n".format(NAME=subdir.upper(), name=subdir, parent=parent)
# List all subdirectories
if ( len(lib_specs["subdirs"]) > 0 ):
makefile += "\n# Registered subdirectories\nSUBDIRS = \\\n "
makefile += " \\\n ".join(lib_specs["subdirs"]) + "\n"
# Add cmake file(s)
cml = os.path.join(par_dir, "CMakeLists.txt")
if ( os.path.exists(cml) ):
makefile += "\n# CMake file\n "
makefile += "EXTRA_DIST = CMakeLists.txt\n"
# Add an abirules target
if ( len(lib_specs["abirules"]) > 0 ):
makefile += mf_sep
makefile += """
# Enforce ABINIT Coding Style (the so-called ABIRULES)
#
# Note concerning abirules (as of 5.8.0)
# The order of config.h vs abi_common.h is not preserved.
# This should be corrected by hand. It is to be done, at present,
# in get_irredg, merge_kgirr, setshells, sigma
"""
makefile += "abirules:\n\t@echo 'Reporting possible errors in the abirules procedure' >tmp-abirules.log\n"
for subdir in lib_specs["abirules"]:
makefile += "\t@$(PERL) ../developers/maintainers/abirules.pl -d %s >>tmp-abirules.log\n" % (subdir)
makefile += "\t@grep 'Error' tmp-abirules.log\n"
# Add a help target
makefile += mf_sep
makefile += "\n# Help\n"
makefile += "help:\n\t@cat $(top_srcdir)/doc/help_make/help_make_{}.txt\n".format(parent)
# Add a parents target
makefile += mf_sep
makefile += "\n# Creation of parent subroutines\n"
makefile += "parents:\n\t$(PERL) $(top_srcdir)/developers/maintainers/parents.pl -s\n"
makefile +="\trm -f *.old */*.old\n"
# Add a local maintainer-clean target
makefile += mf_sep
makefile += "\n# Thorough clean-up\nmaintainer-clean-local:\n\trm -f tmp-abirules.log\n"
for file_ext in ["old", "orig", "rej"]:
makefile += "\tfind . -name '*.%s' -exec rm {} \\;\n" % file_ext
# Include additional information
mf_add = os.path.join("config", "makefiles", "{}.am".format(parent))
if ( os.path.exists(mf_add) ):
makefile += mf_sep
makefile += "\n"
makefile += open(mf_add, "r").read()
# Write down Makefile.am
with open(os.path.join(par_dir, "Makefile.am"), "w") as mf_parent:
mf_parent.write(makefile)
# Write Makefile.am for includes
if ( os.path.exists(os.path.join(par_dir, "incs")) ):
includes = []
inc_specs = os.path.join(par_dir, "incs", "abinit.src")
with open(inc_specs, "r") as src_cnf:
exec(compile(src_cnf.read(), inc_specs, 'exec'))
with open(os.path.join(par_dir, "incs", "Makefile.am"), "w") as mf_incs:
inc_text = makefile_header(my_name, now)
inc_text += "all-local:\n\t@echo \"There is no buildable file here\"\n\n"
if ( len(includes) > 0 ):
inc_text += "EXTRA_DIST = \\\n\t" + " \\\n\t".join(includes) + "\n"
if ( os.path.exists(os.path.join(par_dir, "incs", "CMakeLists.txt")) ):
if ( len(includes) > 0 ):
inc_text += "\nEXTRA_DIST += CMakeLists.txt\n"
else:
inc_text += "\nEXTRA_DIST = CMakeLists.txt\n"
mf_incs.write(inc_text)
# Write Makefile.am for modules
if ( os.path.exists(os.path.join(par_dir, "mods")) ):
with open(os.path.join(par_dir, "mods", "Makefile.am"), "w") as mf_mods:
mod_text = makefile_header(my_name, now)
mod_text += "all-local:\n\t@echo \"There is no buildable file here\"\n\n"
mod_text += "mostlyclean-local:\n\trm -f *.$(MODEXT) *.h\n"
if ( os.path.exists(os.path.join(par_dir, "mods", "CMakeLists.txt")) ):
inc_text += "\nEXTRA_DIST = CMakeLists.txt\n"
mf_mods.write(mod_text)
# Write shared intermediate Makefile.am files
with open("shared/Makefile.am", "w") as mf_shared:
mf_shared.write(makefile_header(my_name, now))
mf_shared.write("""\
SUBDIRS = .
if DO_BUILD_SHARED_COMMON
SUBDIRS += common
endif
if DO_BUILD_SHARED_LIBPAW
SUBDIRS += libpaw
endif
""")
if ( os.path.exists("shared/CMakeLists.txt") ):
mf_shared.write("\nEXTRA_DIST = CMakeLists.txt\n")
with open("shared/common/Makefile.am", "w") as mf_common:
mf_common.write(makefile_header(my_name, now))
mf_common.write("SUBDIRS = src\n")
if ( os.path.exists("shared/common/CMakeLists.txt") ):
mf_common.write("\nEXTRA_DIST = CMakeLists.txt\n")
# Write makefiles for subsystems
cnf_bsys = MyConfigParser()
cnf_bsys.read(my_configs["bsys"])
for subsys in cnf_bsys.sections():
if ( (cnf_bsys.get(subsys, "mode") == "detached") and \
(cnf_bsys.get(subsys, "type") == "data") ):
sub_path = os.path.join("config", "dist", "auto-%s.lst" % subsys)
if ( os.path.exists(sub_path) ):
sub_idx = len(subsys) + 1
sub_files = [item[sub_idx:].strip() for item in open(sub_path, "r").readlines()]
with open(os.path.join(subsys, "Makefile.am"), "w") as mf_sub:
mf_sub.write(makefile_header(my_name, now))
mf_sub.write("EXTRA_DIST = \\\n " + " \\\n ".join(sub_files) + "\n")
# Add cmake file
cml = os.path.join(sub_path, "CMakeLists.txt")
if ( os.path.exists(cml) ):
mf_sub.write("EXTRA_DIST += CMakeLists.txt\n")