8 from textwrap import dedent
14 parser = argparse.ArgumentParser()
15 parser.add_argument('--validate', action='store_true', help='Run in validate mode')
16 parser.add_argument('--required-tag', type=str, action='append', default=set())
17 parser.add_argument('--hadrian', action='store_true', help='Do not assume the make base build system')
18 args = parser.parse_args()
21 print(dedent(s), file=sys.stderr)
27 def check_for_url_rewrites():
28 if os.path.isdir('.git') and \
29 subprocess.check_output('git config remote.origin.url'.split()).find(b'github.com') != -1 and \
30 subprocess.call(['git', 'config', '--get-regexp', '^url.*github.com/.*/packages-.insteadOf']) != 0:
31 # If we cloned from github, make sure the url rewrites are set.
32 # Otherwise 'git submodule update --init' prints confusing errors.
34 It seems you cloned this repository from GitHub. But your git config files
35 don't contain the url rewrites that are needed to make this work (GitHub
36 doesn't support '/' in repository names, so we use a different naming scheme
37 for the submodule repositories there).
39 Please run the following commands first:
41 git config --global url."git://github.com/ghc/packages-".insteadOf git://github.com/ghc/packages/
42 git config --global url."http://github.com/ghc/packages-".insteadOf http://github.com/ghc/packages/
43 git config --global url."https://github.com/ghc/packages-".insteadOf https://github.com/ghc/packages/
44 git config --global url."ssh://git\@github.com/ghc/packages-".insteadOf ssh://git\@github.com/ghc/packages/
45 git config --global url."git\@github.com:/ghc/packages-".insteadOf git\@github.com:/ghc/packages/
49 git submodule update --init
52 Or start over, and clone the GHC repository from the haskell server:
54 git clone --recursive git://git.haskell.org/ghc.git
56 For more information, see:
57 * https://ghc.haskell.org/trac/ghc/wiki/Newcomers or
58 * https://ghc.haskell.org/trac/ghc/wiki/Building/GettingTheSources#CloningfromGitHub
61 def check_boot_packages():
62 # Check that we have all boot packages.
64 for l in open('packages', 'r'):
70 die("Error: Bad line in packages file: " + l)
75 # If $tag is not "-" then it is an optional repository, so its
76 # absence isn't an error.
77 if tag in args.required_tag:
78 # We would like to just check for a .git directory here,
79 # but in an lndir tree we avoid making .git directories,
80 # so it doesn't exist. We therefore require that every repo
81 # has a LICENSE file instead.
82 license_path = os.path.join(dir_, 'LICENSE')
83 if not os.path.isfile(license_path):
85 Error: %s doesn't exist" % license_path)
86 Maybe you haven't run 'git submodule update --init'?
89 # Create libraries/*/{ghc.mk,GNUmakefile}
93 for package in glob.glob("libraries/*/"):
94 packages_file = os.path.join(package, 'ghc-packages')
95 if os.path.isfile(packages_file):
96 for subpkg in open(packages_file, 'r'):
97 library_dirs.append(os.path.join(package, subpkg.strip()))
99 library_dirs.append(package)
101 for package in library_dirs:
102 if package[-1] == '/':
104 package = package[:-1]
106 dir_ = os.path.relpath(package, 'libraries')
107 cabals = glob.glob(os.path.join(package, '*.cabal.in'))
109 cabals = glob.glob(os.path.join(package, '*.cabal'))
112 die('Too many .cabal files in %s' % package)
113 elif len(cabals) == 1:
116 if os.path.isfile(cabal):
117 # strip both .cabal and .in
118 pkg = os.path.splitext(os.path.splitext(os.path.basename(cabal))[0])[0]
121 ghc_mk = os.path.join(package, 'ghc.mk')
122 print('Creating %s' % ghc_mk)
123 with open(ghc_mk, 'w') as f:
126 {package}_PACKAGE = {pkg}
127 {package}_dist-install_GROUP = libraries
128 $(if $(filter {dir},$(PACKAGES_STAGE0)),$(eval $(call build-package,{package},dist-boot,0)))
129 $(if $(filter {dir},$(PACKAGES_STAGE1)),$(eval $(call build-package,{package},dist-install,1)))
130 $(if $(filter {dir},$(PACKAGES_STAGE2)),$(eval $(call build-package,{package},dist-install,2)))
131 """.format(package = package,
137 # Run autoreconf on everything that needs it.
140 # Get the normalized ACLOCAL_PATH for Windows
141 # This is necessary since on Windows this will be a Windows
142 # path, which autoreconf doesn't know doesn't know how to handle.
143 ac_local = os.environ['ACLOCAL_PATH']
144 ac_local_arg = re.sub(r';', r':', ac_local)
145 ac_local_arg = re.sub(r'\\', r'/', ac_local_arg)
146 ac_local_arg = re.sub(r'(\w):/', r'/\1/', ac_local_arg)
147 reconf_cmd = 'ACLOCAL_PATH=%s autoreconf' % ac_local_arg
149 reconf_cmd = 'autoreconf'
151 for dir_ in ['.'] + glob.glob('libraries/*/'):
152 if os.path.isfile(os.path.join(dir_, 'configure.ac')):
153 print("Booting %s" % dir_)
154 processes[dir_] = subprocess.Popen(['sh', '-c', reconf_cmd], cwd=dir_)
156 # Wait for all child processes to finish.
158 for k,v in processes.items():
161 print_err('autoreconf in %s failed with exit code %d' % (k, code))
167 def check_build_mk():
168 if not args.validate and not os.path.isfile("mk/build.mk"):
171 WARNING: You don't have a mk/build.mk file.
173 By default a standard GHC build will be done, which uses optimisation
174 and builds the profiling libraries. This will take a long time, so may
175 not be what you want if you are developing GHC or the libraries, rather
176 than simply building it to use it.
178 For information on creating a mk/build.mk file, please see:
179 http://ghc.haskell.org/trac/ghc/wiki/Building/Using#Buildconfiguration
182 check_for_url_rewrites()