mirror of
https://github.com/pfloos/quack
synced 2024-11-03 12:43:48 +01:00
290 lines
7.5 KiB
Python
Executable File
290 lines
7.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import os
|
|
import sys
|
|
|
|
DEBUG=False
|
|
try:
|
|
DEBUG = sys.argv[1] == "debug"
|
|
except:
|
|
pass
|
|
|
|
|
|
if "QUACK_ROOT" not in os.environ:
|
|
os.chdir("..")
|
|
print("")
|
|
print("Please set the QUACK_ROOT environment variable, for example:")
|
|
print("")
|
|
print("$ export QUACK_ROOT={0}".format(os.getcwd()))
|
|
print("")
|
|
sys.exit(1)
|
|
|
|
QUACK_ROOT=os.environ["QUACK_ROOT"]
|
|
|
|
if not DEBUG:
|
|
compile_gfortran_mac = """
|
|
FC = gfortran
|
|
AR = libtool -static -o
|
|
FFLAGS = -I$IDIR -J$IDIR -fbacktrace -g -Wall -Wno-unused -Wno-unused-dummy-argument -O3
|
|
CC = gcc
|
|
CXX = g++
|
|
LAPACK=-lblas -llapack
|
|
STDCXX=-lc++
|
|
FIX_ORDER_OF_LIBS=
|
|
"""
|
|
|
|
compile_gfortran_linux = """
|
|
FC = gfortran
|
|
AR = ar crs
|
|
FFLAGS = -I$IDIR -J$IDIR -fbacktrace -g -Wall -Wno-unused -Wno-unused-dummy-argument -O3
|
|
CC = gcc
|
|
CXX = g++
|
|
LAPACK=-lblas -llapack
|
|
STDCXX=-lstdc++
|
|
FIX_ORDER_OF_LIBS=-Wl,--start-group
|
|
"""
|
|
else:
|
|
compile_gfortran_mac = """
|
|
FC = gfortran
|
|
AR = libtool -static -o
|
|
FFLAGS = -I$IDIR -J$IDIR -fbacktrace -Wall -g -msse4.2 -fcheck=all -Waliasing -Wampersand -Wconversion -Wsurprising -Wintrinsics-std -Wno-tabs -Wintrinsic-shadow -Wline-truncation -Wreal-q-constant
|
|
CC = gcc
|
|
CXX = g++
|
|
LAPACK=-lblas -llapack
|
|
STDCXX=-lc++
|
|
FIX_ORDER_OF_LIBS=
|
|
"""
|
|
|
|
compile_gfortran_linux = """
|
|
FC = gfortran
|
|
AR = ar crs
|
|
FFLAGS = -I$IDIR -J$IDIR -fbacktrace -Wall -g -msse4.2 -fcheck=all -Waliasing -Wampersand -Wconversion -Wsurprising -Wintrinsics-std -Wno-tabs -Wintrinsic-shadow -Wline-truncation -Wreal-q-constant
|
|
CC = gcc
|
|
CXX = g++
|
|
LAPACK=-lblas -llapack
|
|
STDCXX=-lstdc++
|
|
FIX_ORDER_OF_LIBS=-Wl,--start-group
|
|
"""
|
|
|
|
|
|
if sys.platform in ["linux", "linux2"]:
|
|
compiler = compile_gfortran_linux
|
|
elif sys.platform == "darwin":
|
|
compiler = compile_gfortran_mac
|
|
else:
|
|
print("Unknown platform. Only Linux and Darwin are supported.")
|
|
sys.exit(-1)
|
|
|
|
header = """#
|
|
# This file was automatically generated. Do not modify this file.
|
|
# To change compiling options, make the modifications in
|
|
# {0}/src/make_ninja.py
|
|
#
|
|
|
|
QUACK_ROOT={0}
|
|
IDIR=$QUACK_ROOT/include
|
|
LDIR=$QUACK_ROOT/lib
|
|
BDIR=$QUACK_ROOT/bin
|
|
SDIR=$QUACK_ROOT/src
|
|
|
|
LIBXC_VERSION=5.0.0
|
|
|
|
""".format(QUACK_ROOT)
|
|
|
|
rule_fortran = """
|
|
rule fc
|
|
command = $FC $FFLAGS -c $in -o $out
|
|
|
|
"""
|
|
|
|
rule_build_lib = """
|
|
rule build_lib
|
|
command = $AR $out $in
|
|
description = Linking $out
|
|
|
|
"""
|
|
LIBS="$LDIR/libnumgrid.a "
|
|
rule_build_exe = """
|
|
LIBS = {0} $LAPACK $STDCXX
|
|
|
|
rule build_exe
|
|
command = $FC $FIX_ORDER_OF_LIBS $in $LIBS -o $out
|
|
pool = console
|
|
description = Linking $out
|
|
|
|
rule build_lib
|
|
command = cd $dir ; ninja $out
|
|
pool = console
|
|
description = Compiling $out
|
|
|
|
""".format(LIBS)
|
|
|
|
rule_git_clone = """
|
|
rule git_clone
|
|
command = cd $QUACK_ROOT ; git clone $url
|
|
pool = console
|
|
description = Cloning $in
|
|
|
|
"""
|
|
|
|
build_numgrid = """
|
|
rule make_numgrid
|
|
command = cd $QUACK_ROOT/numgrid-tools ; LDIR="$LDIR" SDIR="$SDIR" CC="$CC" CXX="$CXX" FC="$FC" ./install_numgrid.sh
|
|
description = Building numgrid
|
|
pool = console
|
|
|
|
build $LDIR/libnumgrid.a: make_numgrid
|
|
generator = true
|
|
"""
|
|
|
|
build_qcaml = """
|
|
rule install_qcaml
|
|
command = cd $QUACK_ROOT/qcaml-tools ; ./install_qcaml.sh
|
|
pool = console
|
|
description = Installing QCaml
|
|
generator = true
|
|
|
|
build $QUACK_ROOT/qcaml-tools/qcaml/README.md: install_qcaml
|
|
generator = true
|
|
"""
|
|
|
|
build_GoDuck = """
|
|
rule make_goduck
|
|
command = cd $QUACK_ROOT/qcaml-tools ; make
|
|
pool = console
|
|
description = Compiling GoDuck
|
|
|
|
build $QUACK_ROOT/GoDuck: make_goduck $QUACK_ROOT/qcaml-tools/qcaml/README.md
|
|
"""
|
|
|
|
|
|
build_in_lib_dir = "\n".join([
|
|
header,
|
|
compiler,
|
|
rule_fortran,
|
|
rule_build_lib,
|
|
])
|
|
|
|
|
|
build_in_exe_dir = "\n".join([
|
|
header,
|
|
compiler,
|
|
rule_fortran,
|
|
rule_build_exe,
|
|
])
|
|
|
|
build_main = "\n".join([
|
|
header,
|
|
compiler,
|
|
rule_git_clone,
|
|
build_numgrid,
|
|
build_qcaml,
|
|
build_GoDuck,
|
|
])
|
|
|
|
exe_dirs = [ "QuAcK"]
|
|
lib_dirs = list(filter(lambda x: os.path.isdir(x) and \
|
|
x not in exe_dirs, os.listdir(".")))
|
|
|
|
def create_ninja_in_libdir(directory):
|
|
def write_rule(f, source_file, replace):
|
|
obj_file = os.path.join("obj", source_file.replace(replace, ".o"))
|
|
f.write("build {0}: fc {1}\n".format(obj_file,source_file))
|
|
return obj_file
|
|
|
|
with open(os.path.join(directory, "build.ninja"),"w") as f:
|
|
f.write(build_in_lib_dir)
|
|
objects = []
|
|
for filename in os.listdir(directory):
|
|
for suffix in [".f", ".f90"]:
|
|
if filename.endswith(suffix):
|
|
obj_file = write_rule(f, filename, suffix)
|
|
objects.append(obj_file)
|
|
objects = " ".join(objects)
|
|
f.write("build $LDIR/{0}.a: build_lib {1}\n".format(directory,objects))
|
|
f.write("default $LDIR/{0}.a\n".format(directory))
|
|
|
|
|
|
def create_ninja_in_exedir(directory):
|
|
def write_rule(f, source_file, replace):
|
|
obj_file = os.path.join("obj", source_file.replace(replace, ".o"))
|
|
f.write("build {0}: fc {1}\n".format(obj_file,source_file))
|
|
return obj_file
|
|
|
|
with open(os.path.join(directory, "build.ninja"),"w") as f:
|
|
f.write(build_in_exe_dir)
|
|
objects = []
|
|
for filename in os.listdir(directory):
|
|
for suffix in [".f", ".f90"]:
|
|
if filename.endswith(suffix):
|
|
obj_file = write_rule(f, filename, suffix)
|
|
objects.append(obj_file)
|
|
objects = " ".join(objects)
|
|
for libname in lib_dirs:
|
|
f.write("build $LDIR/{0}.a: build_lib\n dir = $SDIR/{0}\n".format(libname))
|
|
libs = " ".join([ "$LDIR/{0}.a".format(x) for x in lib_dirs]) + " "+LIBS
|
|
f.write("build $BDIR/{0}: build_exe {1} {2}\n".format(directory,libs,objects))
|
|
f.write("default $BDIR/{0}\n".format(directory))
|
|
|
|
|
|
def create_main_ninja():
|
|
|
|
libs = " ".join([ "$LDIR/{0}.a".format(x) for x in lib_dirs]) + " "+LIBS
|
|
with open("build.ninja","w") as f:
|
|
f.write(build_main)
|
|
f.write("""
|
|
rule build_exe
|
|
command = cd $SDIR/$dir ; ninja $out
|
|
pool = console
|
|
|
|
rule build_lib
|
|
command = cd $dir ; ninja $out
|
|
pool = console
|
|
description = Compiling $out
|
|
|
|
""")
|
|
for exe_dir in exe_dirs:
|
|
sources = [ "$SDIR/{0}/{1}".format(exe_dir,x) for x in os.listdir(exe_dir) ]
|
|
sources = filter(lambda x: x.endswith(".f") or x.endswith(".f90"), sources)
|
|
sources = " ".join(sources)
|
|
f.write("build $BDIR/{0}: build_exe {1} $LDIR/libnumgrid.a {2}\n".format(exe_dir,libs,sources))
|
|
f.write(" dir = {0} \n".format(exe_dir) )
|
|
|
|
for libname in lib_dirs:
|
|
sources = [ "$SDIR/{0}/{1}".format(libname,x) for x in os.listdir(libname) ]
|
|
sources = filter(lambda x: x.endswith(".f") or x.endswith(".f90"), sources)
|
|
sources = " ".join(sources)
|
|
if libname == "numgrid":
|
|
f.write("build $LDIR/{0}.a: build_lib {1}\n dir = $SDIR/{0}\n".format(libname, sources))
|
|
else:
|
|
f.write("build $LDIR/{0}.a: build_lib {1} $LDIR/numgrid.a\n dir = $SDIR/{0}\n".format(libname, sources))
|
|
f.write("build all: phony $QUACK_ROOT/GoDuck $BDIR/QuAcK\n")
|
|
f.write("default all\n")
|
|
|
|
def create_makefile(directory):
|
|
with open(os.path.join(directory, "Makefile"),"w") as f:
|
|
f.write("""default:
|
|
ninja
|
|
make -C ..
|
|
|
|
clean:
|
|
ninja -t clean
|
|
|
|
debug:
|
|
ninja -t clean
|
|
make -C .. debug
|
|
""")
|
|
|
|
def main():
|
|
for lib_dir in lib_dirs:
|
|
create_ninja_in_libdir(lib_dir)
|
|
create_makefile(lib_dir)
|
|
|
|
for exe_dir in exe_dirs:
|
|
create_ninja_in_exedir(exe_dir)
|
|
create_makefile(exe_dir)
|
|
|
|
create_main_ninja()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|