1*b7893ccfSSadaf Ebrahimi#!/usr/bin/env python 2*b7893ccfSSadaf Ebrahimi 3*b7893ccfSSadaf Ebrahimi# Copyright 2017 The Glslang Authors. All rights reserved. 4*b7893ccfSSadaf Ebrahimi# Copyright (c) 2018 Valve Corporation 5*b7893ccfSSadaf Ebrahimi# Copyright (c) 2018 LunarG, Inc. 6*b7893ccfSSadaf Ebrahimi# 7*b7893ccfSSadaf Ebrahimi# Licensed under the Apache License, Version 2.0 (the "License"); 8*b7893ccfSSadaf Ebrahimi# you may not use this file except in compliance with the License. 9*b7893ccfSSadaf Ebrahimi# You may obtain a copy of the License at 10*b7893ccfSSadaf Ebrahimi# 11*b7893ccfSSadaf Ebrahimi# http://www.apache.org/licenses/LICENSE-2.0 12*b7893ccfSSadaf Ebrahimi# 13*b7893ccfSSadaf Ebrahimi# Unless required by applicable law or agreed to in writing, software 14*b7893ccfSSadaf Ebrahimi# distributed under the License is distributed on an "AS IS" BASIS, 15*b7893ccfSSadaf Ebrahimi# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16*b7893ccfSSadaf Ebrahimi# See the License for the specific language governing permissions and 17*b7893ccfSSadaf Ebrahimi# limitations under the License. 18*b7893ccfSSadaf Ebrahimi 19*b7893ccfSSadaf Ebrahimi# This script was heavily leveraged from KhronosGroup/glslang 20*b7893ccfSSadaf Ebrahimi# update_glslang_sources.py. 21*b7893ccfSSadaf Ebrahimi"""update_deps.py 22*b7893ccfSSadaf Ebrahimi 23*b7893ccfSSadaf EbrahimiGet and build dependent repositories using known-good commits. 24*b7893ccfSSadaf Ebrahimi 25*b7893ccfSSadaf EbrahimiPurpose 26*b7893ccfSSadaf Ebrahimi------- 27*b7893ccfSSadaf Ebrahimi 28*b7893ccfSSadaf EbrahimiThis program is intended to assist a developer of this repository 29*b7893ccfSSadaf Ebrahimi(the "home" repository) by gathering and building the repositories that 30*b7893ccfSSadaf Ebrahimithis home repository depend on. It also checks out each dependent 31*b7893ccfSSadaf Ebrahimirepository at a "known-good" commit in order to provide stability in 32*b7893ccfSSadaf Ebrahimithe dependent repositories. 33*b7893ccfSSadaf Ebrahimi 34*b7893ccfSSadaf EbrahimiPython Compatibility 35*b7893ccfSSadaf Ebrahimi-------------------- 36*b7893ccfSSadaf Ebrahimi 37*b7893ccfSSadaf EbrahimiThis program can be used with Python 2.7 and Python 3. 38*b7893ccfSSadaf Ebrahimi 39*b7893ccfSSadaf EbrahimiKnown-Good JSON Database 40*b7893ccfSSadaf Ebrahimi------------------------ 41*b7893ccfSSadaf Ebrahimi 42*b7893ccfSSadaf EbrahimiThis program expects to find a file named "known-good.json" in the 43*b7893ccfSSadaf Ebrahimisame directory as the program file. This JSON file is tailored for 44*b7893ccfSSadaf Ebrahimithe needs of the home repository by including its dependent repositories. 45*b7893ccfSSadaf Ebrahimi 46*b7893ccfSSadaf EbrahimiProgram Options 47*b7893ccfSSadaf Ebrahimi--------------- 48*b7893ccfSSadaf Ebrahimi 49*b7893ccfSSadaf EbrahimiSee the help text (update_deps.py --help) for a complete list of options. 50*b7893ccfSSadaf Ebrahimi 51*b7893ccfSSadaf EbrahimiProgram Operation 52*b7893ccfSSadaf Ebrahimi----------------- 53*b7893ccfSSadaf Ebrahimi 54*b7893ccfSSadaf EbrahimiThe program uses the user's current directory at the time of program 55*b7893ccfSSadaf Ebrahimiinvocation as the location for fetching and building the dependent 56*b7893ccfSSadaf Ebrahimirepositories. The user can override this by using the "--dir" option. 57*b7893ccfSSadaf Ebrahimi 58*b7893ccfSSadaf EbrahimiFor example, a directory named "build" in the repository's root directory 59*b7893ccfSSadaf Ebrahimiis a good place to put the dependent repositories because that directory 60*b7893ccfSSadaf Ebrahimiis not tracked by Git. (See the .gitignore file.) The "external" directory 61*b7893ccfSSadaf Ebrahimimay also be a suitable location. 62*b7893ccfSSadaf EbrahimiA user can issue: 63*b7893ccfSSadaf Ebrahimi 64*b7893ccfSSadaf Ebrahimi$ cd My-Repo 65*b7893ccfSSadaf Ebrahimi$ mkdir build 66*b7893ccfSSadaf Ebrahimi$ cd build 67*b7893ccfSSadaf Ebrahimi$ ../scripts/update_deps.py 68*b7893ccfSSadaf Ebrahimi 69*b7893ccfSSadaf Ebrahimior, to do the same thing, but using the --dir option: 70*b7893ccfSSadaf Ebrahimi 71*b7893ccfSSadaf Ebrahimi$ cd My-Repo 72*b7893ccfSSadaf Ebrahimi$ mkdir build 73*b7893ccfSSadaf Ebrahimi$ scripts/update_deps.py --dir=build 74*b7893ccfSSadaf Ebrahimi 75*b7893ccfSSadaf EbrahimiWith these commands, the "build" directory is considered the "top" 76*b7893ccfSSadaf Ebrahimidirectory where the program clones the dependent repositories. The 77*b7893ccfSSadaf EbrahimiJSON file configures the build and install working directories to be 78*b7893ccfSSadaf Ebrahimiwithin this "top" directory. 79*b7893ccfSSadaf Ebrahimi 80*b7893ccfSSadaf EbrahimiNote that the "dir" option can also specify an absolute path: 81*b7893ccfSSadaf Ebrahimi 82*b7893ccfSSadaf Ebrahimi$ cd My-Repo 83*b7893ccfSSadaf Ebrahimi$ scripts/update_deps.py --dir=/tmp/deps 84*b7893ccfSSadaf Ebrahimi 85*b7893ccfSSadaf EbrahimiThe "top" dir is then /tmp/deps (Linux filesystem example) and is 86*b7893ccfSSadaf Ebrahimiwhere this program will clone and build the dependent repositories. 87*b7893ccfSSadaf Ebrahimi 88*b7893ccfSSadaf EbrahimiHelper CMake Config File 89*b7893ccfSSadaf Ebrahimi------------------------ 90*b7893ccfSSadaf Ebrahimi 91*b7893ccfSSadaf EbrahimiWhen the program finishes building the dependencies, it writes a file 92*b7893ccfSSadaf Ebrahiminamed "helper.cmake" to the "top" directory that contains CMake commands 93*b7893ccfSSadaf Ebrahimifor setting CMake variables for locating the dependent repositories. 94*b7893ccfSSadaf EbrahimiThis helper file can be used to set up the CMake build files for this 95*b7893ccfSSadaf Ebrahimi"home" repository. 96*b7893ccfSSadaf Ebrahimi 97*b7893ccfSSadaf EbrahimiA complete sequence might look like: 98*b7893ccfSSadaf Ebrahimi 99*b7893ccfSSadaf Ebrahimi$ git clone [email protected]:My-Group/My-Repo.git 100*b7893ccfSSadaf Ebrahimi$ cd My-Repo 101*b7893ccfSSadaf Ebrahimi$ mkdir build 102*b7893ccfSSadaf Ebrahimi$ cd build 103*b7893ccfSSadaf Ebrahimi$ ../scripts/update_deps.py 104*b7893ccfSSadaf Ebrahimi$ cmake -C helper.cmake .. 105*b7893ccfSSadaf Ebrahimi$ cmake --build . 106*b7893ccfSSadaf Ebrahimi 107*b7893ccfSSadaf EbrahimiJSON File Schema 108*b7893ccfSSadaf Ebrahimi---------------- 109*b7893ccfSSadaf Ebrahimi 110*b7893ccfSSadaf EbrahimiThere's no formal schema for the "known-good" JSON file, but here is 111*b7893ccfSSadaf Ebrahimia description of its elements. All elements are required except those 112*b7893ccfSSadaf Ebrahimimarked as optional. Please see the "known_good.json" file for 113*b7893ccfSSadaf Ebrahimiexamples of all of these elements. 114*b7893ccfSSadaf Ebrahimi 115*b7893ccfSSadaf Ebrahimi- name 116*b7893ccfSSadaf Ebrahimi 117*b7893ccfSSadaf EbrahimiThe name of the dependent repository. This field can be referenced 118*b7893ccfSSadaf Ebrahimiby the "deps.repo_name" structure to record a dependency. 119*b7893ccfSSadaf Ebrahimi 120*b7893ccfSSadaf Ebrahimi- url 121*b7893ccfSSadaf Ebrahimi 122*b7893ccfSSadaf EbrahimiSpecifies the URL of the repository. 123*b7893ccfSSadaf EbrahimiExample: https://github.com/KhronosGroup/Vulkan-Loader.git 124*b7893ccfSSadaf Ebrahimi 125*b7893ccfSSadaf Ebrahimi- sub_dir 126*b7893ccfSSadaf Ebrahimi 127*b7893ccfSSadaf EbrahimiThe directory where the program clones the repository, relative to 128*b7893ccfSSadaf Ebrahimithe "top" directory. 129*b7893ccfSSadaf Ebrahimi 130*b7893ccfSSadaf Ebrahimi- build_dir 131*b7893ccfSSadaf Ebrahimi 132*b7893ccfSSadaf EbrahimiThe directory used to build the repository, relative to the "top" 133*b7893ccfSSadaf Ebrahimidirectory. 134*b7893ccfSSadaf Ebrahimi 135*b7893ccfSSadaf Ebrahimi- install_dir 136*b7893ccfSSadaf Ebrahimi 137*b7893ccfSSadaf EbrahimiThe directory used to store the installed build artifacts, relative 138*b7893ccfSSadaf Ebrahimito the "top" directory. 139*b7893ccfSSadaf Ebrahimi 140*b7893ccfSSadaf Ebrahimi- commit 141*b7893ccfSSadaf Ebrahimi 142*b7893ccfSSadaf EbrahimiThe commit used to checkout the repository. This can be a SHA-1 143*b7893ccfSSadaf Ebrahimiobject name or a refname used with the remote name "origin". 144*b7893ccfSSadaf EbrahimiFor example, this field can be set to "origin/sdk-1.1.77" to 145*b7893ccfSSadaf Ebrahimiselect the end of the sdk-1.1.77 branch. 146*b7893ccfSSadaf Ebrahimi 147*b7893ccfSSadaf Ebrahimi- deps (optional) 148*b7893ccfSSadaf Ebrahimi 149*b7893ccfSSadaf EbrahimiAn array of pairs consisting of a CMake variable name and a 150*b7893ccfSSadaf Ebrahimirepository name to specify a dependent repo and a "link" to 151*b7893ccfSSadaf Ebrahimithat repo's install artifacts. For example: 152*b7893ccfSSadaf Ebrahimi 153*b7893ccfSSadaf Ebrahimi"deps" : [ 154*b7893ccfSSadaf Ebrahimi { 155*b7893ccfSSadaf Ebrahimi "var_name" : "VULKAN_HEADERS_INSTALL_DIR", 156*b7893ccfSSadaf Ebrahimi "repo_name" : "Vulkan-Headers" 157*b7893ccfSSadaf Ebrahimi } 158*b7893ccfSSadaf Ebrahimi] 159*b7893ccfSSadaf Ebrahimi 160*b7893ccfSSadaf Ebrahimiwhich represents that this repository depends on the Vulkan-Headers 161*b7893ccfSSadaf Ebrahimirepository and uses the VULKAN_HEADERS_INSTALL_DIR CMake variable to 162*b7893ccfSSadaf Ebrahimispecify the location where it expects to find the Vulkan-Headers install 163*b7893ccfSSadaf Ebrahimidirectory. 164*b7893ccfSSadaf EbrahimiNote that the "repo_name" element must match the "name" element of some 165*b7893ccfSSadaf Ebrahimiother repository in the JSON file. 166*b7893ccfSSadaf Ebrahimi 167*b7893ccfSSadaf Ebrahimi- prebuild (optional) 168*b7893ccfSSadaf Ebrahimi- prebuild_linux (optional) (For Linux and MacOS) 169*b7893ccfSSadaf Ebrahimi- prebuild_windows (optional) 170*b7893ccfSSadaf Ebrahimi 171*b7893ccfSSadaf EbrahimiA list of commands to execute before building a dependent repository. 172*b7893ccfSSadaf EbrahimiThis is useful for repositories that require the execution of some 173*b7893ccfSSadaf Ebrahimisort of "update" script or need to clone an auxillary repository like 174*b7893ccfSSadaf Ebrahimigoogletest. 175*b7893ccfSSadaf Ebrahimi 176*b7893ccfSSadaf EbrahimiThe commands listed in "prebuild" are executed first, and then the 177*b7893ccfSSadaf Ebrahimicommands for the specific platform are executed. 178*b7893ccfSSadaf Ebrahimi 179*b7893ccfSSadaf Ebrahimi- custom_build (optional) 180*b7893ccfSSadaf Ebrahimi 181*b7893ccfSSadaf EbrahimiA list of commands to execute as a custom build instead of using 182*b7893ccfSSadaf Ebrahimithe built in CMake way of building. Requires "build_step" to be 183*b7893ccfSSadaf Ebrahimiset to "custom" 184*b7893ccfSSadaf Ebrahimi 185*b7893ccfSSadaf EbrahimiYou can insert the following keywords into the commands listed in 186*b7893ccfSSadaf Ebrahimi"custom_build" if they require runtime information (like whether the 187*b7893ccfSSadaf Ebrahimibuild config is "Debug" or "Release"). 188*b7893ccfSSadaf Ebrahimi 189*b7893ccfSSadaf EbrahimiKeywords: 190*b7893ccfSSadaf Ebrahimi{0} reference to a dictionary of repos and their attributes 191*b7893ccfSSadaf Ebrahimi{1} reference to the command line arguments set before start 192*b7893ccfSSadaf Ebrahimi{2} reference to the CONFIG_MAP value of config. 193*b7893ccfSSadaf Ebrahimi 194*b7893ccfSSadaf EbrahimiExample: 195*b7893ccfSSadaf Ebrahimi{2} returns the CONFIG_MAP value of config e.g. debug -> Debug 196*b7893ccfSSadaf Ebrahimi{1}.config returns the config variable set when you ran update_dep.py 197*b7893ccfSSadaf Ebrahimi{0}[Vulkan-Headers][repo_root] returns the repo_root variable from 198*b7893ccfSSadaf Ebrahimi the Vulkan-Headers GoodRepo object. 199*b7893ccfSSadaf Ebrahimi 200*b7893ccfSSadaf Ebrahimi- cmake_options (optional) 201*b7893ccfSSadaf Ebrahimi 202*b7893ccfSSadaf EbrahimiA list of options to pass to CMake during the generation phase. 203*b7893ccfSSadaf Ebrahimi 204*b7893ccfSSadaf Ebrahimi- ci_only (optional) 205*b7893ccfSSadaf Ebrahimi 206*b7893ccfSSadaf EbrahimiA list of environment variables where one must be set to "true" 207*b7893ccfSSadaf Ebrahimi(case-insensitive) in order for this repo to be fetched and built. 208*b7893ccfSSadaf EbrahimiThis list can be used to specify repos that should be built only in CI. 209*b7893ccfSSadaf EbrahimiTypically, this list might contain "TRAVIS" and/or "APPVEYOR" because 210*b7893ccfSSadaf Ebrahimieach of these CI systems sets an environment variable with its own 211*b7893ccfSSadaf Ebrahiminame to "true". Note that this could also be (ab)used to control 212*b7893ccfSSadaf Ebrahimithe processing of the repo with any environment variable. The default 213*b7893ccfSSadaf Ebrahimiis an empty list, which means that the repo is always processed. 214*b7893ccfSSadaf Ebrahimi 215*b7893ccfSSadaf Ebrahimi- build_step (optional) 216*b7893ccfSSadaf Ebrahimi 217*b7893ccfSSadaf EbrahimiSpecifies if the dependent repository should be built or not. This can 218*b7893ccfSSadaf Ebrahimihave a value of 'build', 'custom', or 'skip'. The dependent repositories are 219*b7893ccfSSadaf Ebrahimibuilt by default. 220*b7893ccfSSadaf Ebrahimi 221*b7893ccfSSadaf Ebrahimi- build_platforms (optional) 222*b7893ccfSSadaf Ebrahimi 223*b7893ccfSSadaf EbrahimiA list of platforms the repository will be built on. 224*b7893ccfSSadaf EbrahimiLegal options include: 225*b7893ccfSSadaf Ebrahimi"windows" 226*b7893ccfSSadaf Ebrahimi"linux" 227*b7893ccfSSadaf Ebrahimi"darwin" 228*b7893ccfSSadaf Ebrahimi 229*b7893ccfSSadaf EbrahimiBuilds on all platforms by default. 230*b7893ccfSSadaf Ebrahimi 231*b7893ccfSSadaf EbrahimiNote 232*b7893ccfSSadaf Ebrahimi---- 233*b7893ccfSSadaf Ebrahimi 234*b7893ccfSSadaf EbrahimiThe "sub_dir", "build_dir", and "install_dir" elements are all relative 235*b7893ccfSSadaf Ebrahimito the effective "top" directory. Specifying absolute paths is not 236*b7893ccfSSadaf Ebrahimisupported. However, the "top" directory specified with the "--dir" 237*b7893ccfSSadaf Ebrahimioption can be a relative or absolute path. 238*b7893ccfSSadaf Ebrahimi 239*b7893ccfSSadaf Ebrahimi""" 240*b7893ccfSSadaf Ebrahimi 241*b7893ccfSSadaf Ebrahimifrom __future__ import print_function 242*b7893ccfSSadaf Ebrahimi 243*b7893ccfSSadaf Ebrahimiimport argparse 244*b7893ccfSSadaf Ebrahimiimport json 245*b7893ccfSSadaf Ebrahimiimport distutils.dir_util 246*b7893ccfSSadaf Ebrahimiimport os.path 247*b7893ccfSSadaf Ebrahimiimport subprocess 248*b7893ccfSSadaf Ebrahimiimport sys 249*b7893ccfSSadaf Ebrahimiimport platform 250*b7893ccfSSadaf Ebrahimiimport multiprocessing 251*b7893ccfSSadaf Ebrahimiimport shlex 252*b7893ccfSSadaf Ebrahimiimport shutil 253*b7893ccfSSadaf Ebrahimi 254*b7893ccfSSadaf EbrahimiKNOWN_GOOD_FILE_NAME = 'known_good.json' 255*b7893ccfSSadaf Ebrahimi 256*b7893ccfSSadaf EbrahimiCONFIG_MAP = { 257*b7893ccfSSadaf Ebrahimi 'debug': 'Debug', 258*b7893ccfSSadaf Ebrahimi 'release': 'Release', 259*b7893ccfSSadaf Ebrahimi 'relwithdebinfo': 'RelWithDebInfo', 260*b7893ccfSSadaf Ebrahimi 'minsizerel': 'MinSizeRel' 261*b7893ccfSSadaf Ebrahimi} 262*b7893ccfSSadaf Ebrahimi 263*b7893ccfSSadaf EbrahimiVERBOSE = False 264*b7893ccfSSadaf Ebrahimi 265*b7893ccfSSadaf EbrahimiDEVNULL = open(os.devnull, 'wb') 266*b7893ccfSSadaf Ebrahimi 267*b7893ccfSSadaf Ebrahimi 268*b7893ccfSSadaf Ebrahimidef command_output(cmd, directory, fail_ok=False): 269*b7893ccfSSadaf Ebrahimi """Runs a command in a directory and returns its standard output stream. 270*b7893ccfSSadaf Ebrahimi 271*b7893ccfSSadaf Ebrahimi Captures the standard error stream and prints it if error. 272*b7893ccfSSadaf Ebrahimi 273*b7893ccfSSadaf Ebrahimi Raises a RuntimeError if the command fails to launch or otherwise fails. 274*b7893ccfSSadaf Ebrahimi """ 275*b7893ccfSSadaf Ebrahimi if VERBOSE: 276*b7893ccfSSadaf Ebrahimi print('In {d}: {cmd}'.format(d=directory, cmd=cmd)) 277*b7893ccfSSadaf Ebrahimi p = subprocess.Popen( 278*b7893ccfSSadaf Ebrahimi cmd, cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 279*b7893ccfSSadaf Ebrahimi (stdout, stderr) = p.communicate() 280*b7893ccfSSadaf Ebrahimi if p.returncode != 0: 281*b7893ccfSSadaf Ebrahimi print('*** Error ***\nstderr contents:\n{}'.format(stderr)) 282*b7893ccfSSadaf Ebrahimi if not fail_ok: 283*b7893ccfSSadaf Ebrahimi raise RuntimeError('Failed to run {} in {}'.format(cmd, directory)) 284*b7893ccfSSadaf Ebrahimi if VERBOSE: 285*b7893ccfSSadaf Ebrahimi print(stdout) 286*b7893ccfSSadaf Ebrahimi return stdout 287*b7893ccfSSadaf Ebrahimi 288*b7893ccfSSadaf Ebrahimiclass GoodRepo(object): 289*b7893ccfSSadaf Ebrahimi """Represents a repository at a known-good commit.""" 290*b7893ccfSSadaf Ebrahimi 291*b7893ccfSSadaf Ebrahimi def __init__(self, json, args): 292*b7893ccfSSadaf Ebrahimi """Initializes this good repo object. 293*b7893ccfSSadaf Ebrahimi 294*b7893ccfSSadaf Ebrahimi Args: 295*b7893ccfSSadaf Ebrahimi 'json': A fully populated JSON object describing the repo. 296*b7893ccfSSadaf Ebrahimi 'args': Results from ArgumentParser 297*b7893ccfSSadaf Ebrahimi """ 298*b7893ccfSSadaf Ebrahimi self._json = json 299*b7893ccfSSadaf Ebrahimi self._args = args 300*b7893ccfSSadaf Ebrahimi # Required JSON elements 301*b7893ccfSSadaf Ebrahimi self.name = json['name'] 302*b7893ccfSSadaf Ebrahimi self.url = json['url'] 303*b7893ccfSSadaf Ebrahimi self.sub_dir = json['sub_dir'] 304*b7893ccfSSadaf Ebrahimi self.commit = json['commit'] 305*b7893ccfSSadaf Ebrahimi # Optional JSON elements 306*b7893ccfSSadaf Ebrahimi self.build_dir = None 307*b7893ccfSSadaf Ebrahimi self.install_dir = None 308*b7893ccfSSadaf Ebrahimi if json.get('build_dir'): 309*b7893ccfSSadaf Ebrahimi self.build_dir = os.path.normpath(json['build_dir']) 310*b7893ccfSSadaf Ebrahimi if json.get('install_dir'): 311*b7893ccfSSadaf Ebrahimi self.install_dir = os.path.normpath(json['install_dir']) 312*b7893ccfSSadaf Ebrahimi self.deps = json['deps'] if ('deps' in json) else [] 313*b7893ccfSSadaf Ebrahimi self.prebuild = json['prebuild'] if ('prebuild' in json) else [] 314*b7893ccfSSadaf Ebrahimi self.prebuild_linux = json['prebuild_linux'] if ( 315*b7893ccfSSadaf Ebrahimi 'prebuild_linux' in json) else [] 316*b7893ccfSSadaf Ebrahimi self.prebuild_windows = json['prebuild_windows'] if ( 317*b7893ccfSSadaf Ebrahimi 'prebuild_windows' in json) else [] 318*b7893ccfSSadaf Ebrahimi self.custom_build = json['custom_build'] if ('custom_build' in json) else [] 319*b7893ccfSSadaf Ebrahimi self.cmake_options = json['cmake_options'] if ( 320*b7893ccfSSadaf Ebrahimi 'cmake_options' in json) else [] 321*b7893ccfSSadaf Ebrahimi self.ci_only = json['ci_only'] if ('ci_only' in json) else [] 322*b7893ccfSSadaf Ebrahimi self.build_step = json['build_step'] if ('build_step' in json) else 'build' 323*b7893ccfSSadaf Ebrahimi self.build_platforms = json['build_platforms'] if ('build_platforms' in json) else [] 324*b7893ccfSSadaf Ebrahimi # Absolute paths for a repo's directories 325*b7893ccfSSadaf Ebrahimi dir_top = os.path.abspath(args.dir) 326*b7893ccfSSadaf Ebrahimi self.repo_dir = os.path.join(dir_top, self.sub_dir) 327*b7893ccfSSadaf Ebrahimi if self.build_dir: 328*b7893ccfSSadaf Ebrahimi self.build_dir = os.path.join(dir_top, self.build_dir) 329*b7893ccfSSadaf Ebrahimi if self.install_dir: 330*b7893ccfSSadaf Ebrahimi self.install_dir = os.path.join(dir_top, self.install_dir) 331*b7893ccfSSadaf Ebrahimi # Check if platform is one to build on 332*b7893ccfSSadaf Ebrahimi self.on_build_platform = False 333*b7893ccfSSadaf Ebrahimi if self.build_platforms == [] or platform.system().lower() in self.build_platforms: 334*b7893ccfSSadaf Ebrahimi self.on_build_platform = True 335*b7893ccfSSadaf Ebrahimi 336*b7893ccfSSadaf Ebrahimi def Clone(self): 337*b7893ccfSSadaf Ebrahimi distutils.dir_util.mkpath(self.repo_dir) 338*b7893ccfSSadaf Ebrahimi command_output(['git', 'clone', self.url, '.'], self.repo_dir) 339*b7893ccfSSadaf Ebrahimi 340*b7893ccfSSadaf Ebrahimi def Fetch(self): 341*b7893ccfSSadaf Ebrahimi command_output(['git', 'fetch', 'origin'], self.repo_dir) 342*b7893ccfSSadaf Ebrahimi 343*b7893ccfSSadaf Ebrahimi def Checkout(self): 344*b7893ccfSSadaf Ebrahimi print('Checking out {n} in {d}'.format(n=self.name, d=self.repo_dir)) 345*b7893ccfSSadaf Ebrahimi if self._args.do_clean_repo: 346*b7893ccfSSadaf Ebrahimi shutil.rmtree(self.repo_dir, ignore_errors=True) 347*b7893ccfSSadaf Ebrahimi if not os.path.exists(os.path.join(self.repo_dir, '.git')): 348*b7893ccfSSadaf Ebrahimi self.Clone() 349*b7893ccfSSadaf Ebrahimi self.Fetch() 350*b7893ccfSSadaf Ebrahimi if len(self._args.ref): 351*b7893ccfSSadaf Ebrahimi command_output(['git', 'checkout', self._args.ref], self.repo_dir) 352*b7893ccfSSadaf Ebrahimi else: 353*b7893ccfSSadaf Ebrahimi command_output(['git', 'checkout', self.commit], self.repo_dir) 354*b7893ccfSSadaf Ebrahimi print(command_output(['git', 'status'], self.repo_dir)) 355*b7893ccfSSadaf Ebrahimi 356*b7893ccfSSadaf Ebrahimi def CustomPreProcess(self, cmd_str, repo_dict): 357*b7893ccfSSadaf Ebrahimi return cmd_str.format(repo_dict, self._args, CONFIG_MAP[self._args.config]) 358*b7893ccfSSadaf Ebrahimi 359*b7893ccfSSadaf Ebrahimi def PreBuild(self): 360*b7893ccfSSadaf Ebrahimi """Execute any prebuild steps from the repo root""" 361*b7893ccfSSadaf Ebrahimi for p in self.prebuild: 362*b7893ccfSSadaf Ebrahimi command_output(shlex.split(p), self.repo_dir) 363*b7893ccfSSadaf Ebrahimi if platform.system() == 'Linux' or platform.system() == 'Darwin': 364*b7893ccfSSadaf Ebrahimi for p in self.prebuild_linux: 365*b7893ccfSSadaf Ebrahimi command_output(shlex.split(p), self.repo_dir) 366*b7893ccfSSadaf Ebrahimi if platform.system() == 'Windows': 367*b7893ccfSSadaf Ebrahimi for p in self.prebuild_windows: 368*b7893ccfSSadaf Ebrahimi command_output(shlex.split(p), self.repo_dir) 369*b7893ccfSSadaf Ebrahimi 370*b7893ccfSSadaf Ebrahimi def CustomBuild(self, repo_dict): 371*b7893ccfSSadaf Ebrahimi """Execute any custom_build steps from the repo root""" 372*b7893ccfSSadaf Ebrahimi for p in self.custom_build: 373*b7893ccfSSadaf Ebrahimi cmd = self.CustomPreProcess(p, repo_dict) 374*b7893ccfSSadaf Ebrahimi command_output(shlex.split(cmd), self.repo_dir) 375*b7893ccfSSadaf Ebrahimi 376*b7893ccfSSadaf Ebrahimi def CMakeConfig(self, repos): 377*b7893ccfSSadaf Ebrahimi """Build CMake command for the configuration phase and execute it""" 378*b7893ccfSSadaf Ebrahimi if self._args.do_clean_build: 379*b7893ccfSSadaf Ebrahimi shutil.rmtree(self.build_dir) 380*b7893ccfSSadaf Ebrahimi if self._args.do_clean_install: 381*b7893ccfSSadaf Ebrahimi shutil.rmtree(self.install_dir) 382*b7893ccfSSadaf Ebrahimi 383*b7893ccfSSadaf Ebrahimi # Create and change to build directory 384*b7893ccfSSadaf Ebrahimi distutils.dir_util.mkpath(self.build_dir) 385*b7893ccfSSadaf Ebrahimi os.chdir(self.build_dir) 386*b7893ccfSSadaf Ebrahimi 387*b7893ccfSSadaf Ebrahimi cmake_cmd = [ 388*b7893ccfSSadaf Ebrahimi 'cmake', self.repo_dir, 389*b7893ccfSSadaf Ebrahimi '-DCMAKE_INSTALL_PREFIX=' + self.install_dir 390*b7893ccfSSadaf Ebrahimi ] 391*b7893ccfSSadaf Ebrahimi 392*b7893ccfSSadaf Ebrahimi # For each repo this repo depends on, generate a CMake variable 393*b7893ccfSSadaf Ebrahimi # definitions for "...INSTALL_DIR" that points to that dependent 394*b7893ccfSSadaf Ebrahimi # repo's install dir. 395*b7893ccfSSadaf Ebrahimi for d in self.deps: 396*b7893ccfSSadaf Ebrahimi dep_commit = [r for r in repos if r.name == d['repo_name']] 397*b7893ccfSSadaf Ebrahimi if len(dep_commit): 398*b7893ccfSSadaf Ebrahimi cmake_cmd.append('-D{var_name}={install_dir}'.format( 399*b7893ccfSSadaf Ebrahimi var_name=d['var_name'], 400*b7893ccfSSadaf Ebrahimi install_dir=dep_commit[0].install_dir)) 401*b7893ccfSSadaf Ebrahimi 402*b7893ccfSSadaf Ebrahimi # Add any CMake options 403*b7893ccfSSadaf Ebrahimi for option in self.cmake_options: 404*b7893ccfSSadaf Ebrahimi cmake_cmd.append(option) 405*b7893ccfSSadaf Ebrahimi 406*b7893ccfSSadaf Ebrahimi # Set build config for single-configuration generators 407*b7893ccfSSadaf Ebrahimi if platform.system() == 'Linux' or platform.system() == 'Darwin': 408*b7893ccfSSadaf Ebrahimi cmake_cmd.append('-DCMAKE_BUILD_TYPE={config}'.format( 409*b7893ccfSSadaf Ebrahimi config=CONFIG_MAP[self._args.config])) 410*b7893ccfSSadaf Ebrahimi 411*b7893ccfSSadaf Ebrahimi # Use the CMake -A option to select the platform architecture 412*b7893ccfSSadaf Ebrahimi # without needing a Visual Studio generator. 413*b7893ccfSSadaf Ebrahimi if platform.system() == 'Windows': 414*b7893ccfSSadaf Ebrahimi if self._args.arch == '64' or self._args.arch == 'x64' or self._args.arch == 'win64': 415*b7893ccfSSadaf Ebrahimi cmake_cmd.append('-A') 416*b7893ccfSSadaf Ebrahimi cmake_cmd.append('x64') 417*b7893ccfSSadaf Ebrahimi 418*b7893ccfSSadaf Ebrahimi # Apply a generator, if one is specified. This can be used to supply 419*b7893ccfSSadaf Ebrahimi # a specific generator for the dependent repositories to match 420*b7893ccfSSadaf Ebrahimi # that of the main repository. 421*b7893ccfSSadaf Ebrahimi if self._args.generator is not None: 422*b7893ccfSSadaf Ebrahimi cmake_cmd.extend(['-G', self._args.generator]) 423*b7893ccfSSadaf Ebrahimi 424*b7893ccfSSadaf Ebrahimi if VERBOSE: 425*b7893ccfSSadaf Ebrahimi print("CMake command: " + " ".join(cmake_cmd)) 426*b7893ccfSSadaf Ebrahimi 427*b7893ccfSSadaf Ebrahimi ret_code = subprocess.call(cmake_cmd) 428*b7893ccfSSadaf Ebrahimi if ret_code != 0: 429*b7893ccfSSadaf Ebrahimi sys.exit(ret_code) 430*b7893ccfSSadaf Ebrahimi 431*b7893ccfSSadaf Ebrahimi def CMakeBuild(self): 432*b7893ccfSSadaf Ebrahimi """Build CMake command for the build phase and execute it""" 433*b7893ccfSSadaf Ebrahimi cmake_cmd = ['cmake', '--build', self.build_dir, '--target', 'install'] 434*b7893ccfSSadaf Ebrahimi if self._args.do_clean: 435*b7893ccfSSadaf Ebrahimi cmake_cmd.append('--clean-first') 436*b7893ccfSSadaf Ebrahimi 437*b7893ccfSSadaf Ebrahimi if platform.system() == 'Windows': 438*b7893ccfSSadaf Ebrahimi cmake_cmd.append('--config') 439*b7893ccfSSadaf Ebrahimi cmake_cmd.append(CONFIG_MAP[self._args.config]) 440*b7893ccfSSadaf Ebrahimi 441*b7893ccfSSadaf Ebrahimi # Speed up the build. 442*b7893ccfSSadaf Ebrahimi if platform.system() == 'Linux' or platform.system() == 'Darwin': 443*b7893ccfSSadaf Ebrahimi cmake_cmd.append('--') 444*b7893ccfSSadaf Ebrahimi num_make_jobs = multiprocessing.cpu_count() 445*b7893ccfSSadaf Ebrahimi env_make_jobs = os.environ.get('MAKE_JOBS', None) 446*b7893ccfSSadaf Ebrahimi if env_make_jobs is not None: 447*b7893ccfSSadaf Ebrahimi try: 448*b7893ccfSSadaf Ebrahimi num_make_jobs = min(num_make_jobs, int(env_make_jobs)) 449*b7893ccfSSadaf Ebrahimi except ValueError: 450*b7893ccfSSadaf Ebrahimi print('warning: environment variable MAKE_JOBS has non-numeric value "{}". ' 451*b7893ccfSSadaf Ebrahimi 'Using {} (CPU count) instead.'.format(env_make_jobs, num_make_jobs)) 452*b7893ccfSSadaf Ebrahimi cmake_cmd.append('-j{}'.format(num_make_jobs)) 453*b7893ccfSSadaf Ebrahimi if platform.system() == 'Windows': 454*b7893ccfSSadaf Ebrahimi cmake_cmd.append('--') 455*b7893ccfSSadaf Ebrahimi cmake_cmd.append('/maxcpucount') 456*b7893ccfSSadaf Ebrahimi 457*b7893ccfSSadaf Ebrahimi if VERBOSE: 458*b7893ccfSSadaf Ebrahimi print("CMake command: " + " ".join(cmake_cmd)) 459*b7893ccfSSadaf Ebrahimi 460*b7893ccfSSadaf Ebrahimi ret_code = subprocess.call(cmake_cmd) 461*b7893ccfSSadaf Ebrahimi if ret_code != 0: 462*b7893ccfSSadaf Ebrahimi sys.exit(ret_code) 463*b7893ccfSSadaf Ebrahimi 464*b7893ccfSSadaf Ebrahimi def Build(self, repos, repo_dict): 465*b7893ccfSSadaf Ebrahimi """Build the dependent repo""" 466*b7893ccfSSadaf Ebrahimi print('Building {n} in {d}'.format(n=self.name, d=self.repo_dir)) 467*b7893ccfSSadaf Ebrahimi print('Build dir = {b}'.format(b=self.build_dir)) 468*b7893ccfSSadaf Ebrahimi print('Install dir = {i}\n'.format(i=self.install_dir)) 469*b7893ccfSSadaf Ebrahimi 470*b7893ccfSSadaf Ebrahimi # Run any prebuild commands 471*b7893ccfSSadaf Ebrahimi self.PreBuild() 472*b7893ccfSSadaf Ebrahimi 473*b7893ccfSSadaf Ebrahimi if self.build_step == 'custom': 474*b7893ccfSSadaf Ebrahimi self.CustomBuild(repo_dict) 475*b7893ccfSSadaf Ebrahimi return 476*b7893ccfSSadaf Ebrahimi 477*b7893ccfSSadaf Ebrahimi # Build and execute CMake command for creating build files 478*b7893ccfSSadaf Ebrahimi self.CMakeConfig(repos) 479*b7893ccfSSadaf Ebrahimi 480*b7893ccfSSadaf Ebrahimi # Build and execute CMake command for the build 481*b7893ccfSSadaf Ebrahimi self.CMakeBuild() 482*b7893ccfSSadaf Ebrahimi 483*b7893ccfSSadaf Ebrahimi 484*b7893ccfSSadaf Ebrahimidef GetGoodRepos(args): 485*b7893ccfSSadaf Ebrahimi """Returns the latest list of GoodRepo objects. 486*b7893ccfSSadaf Ebrahimi 487*b7893ccfSSadaf Ebrahimi The known-good file is expected to be in the same 488*b7893ccfSSadaf Ebrahimi directory as this script unless overridden by the 'known_good_dir' 489*b7893ccfSSadaf Ebrahimi parameter. 490*b7893ccfSSadaf Ebrahimi """ 491*b7893ccfSSadaf Ebrahimi if args.known_good_dir: 492*b7893ccfSSadaf Ebrahimi known_good_file = os.path.join( os.path.abspath(args.known_good_dir), 493*b7893ccfSSadaf Ebrahimi KNOWN_GOOD_FILE_NAME) 494*b7893ccfSSadaf Ebrahimi else: 495*b7893ccfSSadaf Ebrahimi known_good_file = os.path.join( 496*b7893ccfSSadaf Ebrahimi os.path.dirname(os.path.abspath(__file__)), KNOWN_GOOD_FILE_NAME) 497*b7893ccfSSadaf Ebrahimi with open(known_good_file) as known_good: 498*b7893ccfSSadaf Ebrahimi return [ 499*b7893ccfSSadaf Ebrahimi GoodRepo(repo, args) 500*b7893ccfSSadaf Ebrahimi for repo in json.loads(known_good.read())['repos'] 501*b7893ccfSSadaf Ebrahimi ] 502*b7893ccfSSadaf Ebrahimi 503*b7893ccfSSadaf Ebrahimi 504*b7893ccfSSadaf Ebrahimidef GetInstallNames(args): 505*b7893ccfSSadaf Ebrahimi """Returns the install names list. 506*b7893ccfSSadaf Ebrahimi 507*b7893ccfSSadaf Ebrahimi The known-good file is expected to be in the same 508*b7893ccfSSadaf Ebrahimi directory as this script unless overridden by the 'known_good_dir' 509*b7893ccfSSadaf Ebrahimi parameter. 510*b7893ccfSSadaf Ebrahimi """ 511*b7893ccfSSadaf Ebrahimi if args.known_good_dir: 512*b7893ccfSSadaf Ebrahimi known_good_file = os.path.join(os.path.abspath(args.known_good_dir), 513*b7893ccfSSadaf Ebrahimi KNOWN_GOOD_FILE_NAME) 514*b7893ccfSSadaf Ebrahimi else: 515*b7893ccfSSadaf Ebrahimi known_good_file = os.path.join( 516*b7893ccfSSadaf Ebrahimi os.path.dirname(os.path.abspath(__file__)), KNOWN_GOOD_FILE_NAME) 517*b7893ccfSSadaf Ebrahimi with open(known_good_file) as known_good: 518*b7893ccfSSadaf Ebrahimi install_info = json.loads(known_good.read()) 519*b7893ccfSSadaf Ebrahimi if install_info.get('install_names'): 520*b7893ccfSSadaf Ebrahimi return install_info['install_names'] 521*b7893ccfSSadaf Ebrahimi else: 522*b7893ccfSSadaf Ebrahimi return None 523*b7893ccfSSadaf Ebrahimi 524*b7893ccfSSadaf Ebrahimi 525*b7893ccfSSadaf Ebrahimidef CreateHelper(args, repos, filename): 526*b7893ccfSSadaf Ebrahimi """Create a CMake config helper file. 527*b7893ccfSSadaf Ebrahimi 528*b7893ccfSSadaf Ebrahimi The helper file is intended to be used with 'cmake -C <file>' 529*b7893ccfSSadaf Ebrahimi to build this home repo using the dependencies built by this script. 530*b7893ccfSSadaf Ebrahimi 531*b7893ccfSSadaf Ebrahimi The install_names dictionary represents the CMake variables used by the 532*b7893ccfSSadaf Ebrahimi home repo to locate the install dirs of the dependent repos. 533*b7893ccfSSadaf Ebrahimi This information is baked into the CMake files of the home repo and so 534*b7893ccfSSadaf Ebrahimi this dictionary is kept with the repo via the json file. 535*b7893ccfSSadaf Ebrahimi """ 536*b7893ccfSSadaf Ebrahimi def escape(path): 537*b7893ccfSSadaf Ebrahimi return path.replace('\\', '\\\\') 538*b7893ccfSSadaf Ebrahimi install_names = GetInstallNames(args) 539*b7893ccfSSadaf Ebrahimi with open(filename, 'w') as helper_file: 540*b7893ccfSSadaf Ebrahimi for repo in repos: 541*b7893ccfSSadaf Ebrahimi if install_names and repo.name in install_names and repo.on_build_platform: 542*b7893ccfSSadaf Ebrahimi helper_file.write('set({var} "{dir}" CACHE STRING "" FORCE)\n' 543*b7893ccfSSadaf Ebrahimi .format( 544*b7893ccfSSadaf Ebrahimi var=install_names[repo.name], 545*b7893ccfSSadaf Ebrahimi dir=escape(repo.install_dir))) 546*b7893ccfSSadaf Ebrahimi 547*b7893ccfSSadaf Ebrahimi 548*b7893ccfSSadaf Ebrahimidef main(): 549*b7893ccfSSadaf Ebrahimi parser = argparse.ArgumentParser( 550*b7893ccfSSadaf Ebrahimi description='Get and build dependent repos at known-good commits') 551*b7893ccfSSadaf Ebrahimi parser.add_argument( 552*b7893ccfSSadaf Ebrahimi '--known_good_dir', 553*b7893ccfSSadaf Ebrahimi dest='known_good_dir', 554*b7893ccfSSadaf Ebrahimi help="Specify directory for known_good.json file.") 555*b7893ccfSSadaf Ebrahimi parser.add_argument( 556*b7893ccfSSadaf Ebrahimi '--dir', 557*b7893ccfSSadaf Ebrahimi dest='dir', 558*b7893ccfSSadaf Ebrahimi default='.', 559*b7893ccfSSadaf Ebrahimi help="Set target directory for repository roots. Default is \'.\'.") 560*b7893ccfSSadaf Ebrahimi parser.add_argument( 561*b7893ccfSSadaf Ebrahimi '--ref', 562*b7893ccfSSadaf Ebrahimi dest='ref', 563*b7893ccfSSadaf Ebrahimi default='', 564*b7893ccfSSadaf Ebrahimi help="Override 'commit' with git reference. E.g., 'origin/master'") 565*b7893ccfSSadaf Ebrahimi parser.add_argument( 566*b7893ccfSSadaf Ebrahimi '--no-build', 567*b7893ccfSSadaf Ebrahimi dest='do_build', 568*b7893ccfSSadaf Ebrahimi action='store_false', 569*b7893ccfSSadaf Ebrahimi help= 570*b7893ccfSSadaf Ebrahimi "Clone/update repositories and generate build files without performing compilation", 571*b7893ccfSSadaf Ebrahimi default=True) 572*b7893ccfSSadaf Ebrahimi parser.add_argument( 573*b7893ccfSSadaf Ebrahimi '--clean', 574*b7893ccfSSadaf Ebrahimi dest='do_clean', 575*b7893ccfSSadaf Ebrahimi action='store_true', 576*b7893ccfSSadaf Ebrahimi help="Clean files generated by compiler and linker before building", 577*b7893ccfSSadaf Ebrahimi default=False) 578*b7893ccfSSadaf Ebrahimi parser.add_argument( 579*b7893ccfSSadaf Ebrahimi '--clean-repo', 580*b7893ccfSSadaf Ebrahimi dest='do_clean_repo', 581*b7893ccfSSadaf Ebrahimi action='store_true', 582*b7893ccfSSadaf Ebrahimi help="Delete repository directory before building", 583*b7893ccfSSadaf Ebrahimi default=False) 584*b7893ccfSSadaf Ebrahimi parser.add_argument( 585*b7893ccfSSadaf Ebrahimi '--clean-build', 586*b7893ccfSSadaf Ebrahimi dest='do_clean_build', 587*b7893ccfSSadaf Ebrahimi action='store_true', 588*b7893ccfSSadaf Ebrahimi help="Delete build directory before building", 589*b7893ccfSSadaf Ebrahimi default=False) 590*b7893ccfSSadaf Ebrahimi parser.add_argument( 591*b7893ccfSSadaf Ebrahimi '--clean-install', 592*b7893ccfSSadaf Ebrahimi dest='do_clean_install', 593*b7893ccfSSadaf Ebrahimi action='store_true', 594*b7893ccfSSadaf Ebrahimi help="Delete install directory before building", 595*b7893ccfSSadaf Ebrahimi default=False) 596*b7893ccfSSadaf Ebrahimi parser.add_argument( 597*b7893ccfSSadaf Ebrahimi '--arch', 598*b7893ccfSSadaf Ebrahimi dest='arch', 599*b7893ccfSSadaf Ebrahimi choices=['32', '64', 'x86', 'x64', 'win32', 'win64'], 600*b7893ccfSSadaf Ebrahimi type=str.lower, 601*b7893ccfSSadaf Ebrahimi help="Set build files architecture (Windows)", 602*b7893ccfSSadaf Ebrahimi default='64') 603*b7893ccfSSadaf Ebrahimi parser.add_argument( 604*b7893ccfSSadaf Ebrahimi '--config', 605*b7893ccfSSadaf Ebrahimi dest='config', 606*b7893ccfSSadaf Ebrahimi choices=['debug', 'release', 'relwithdebinfo', 'minsizerel'], 607*b7893ccfSSadaf Ebrahimi type=str.lower, 608*b7893ccfSSadaf Ebrahimi help="Set build files configuration", 609*b7893ccfSSadaf Ebrahimi default='debug') 610*b7893ccfSSadaf Ebrahimi parser.add_argument( 611*b7893ccfSSadaf Ebrahimi '--generator', 612*b7893ccfSSadaf Ebrahimi dest='generator', 613*b7893ccfSSadaf Ebrahimi help="Set the CMake generator", 614*b7893ccfSSadaf Ebrahimi default=None) 615*b7893ccfSSadaf Ebrahimi 616*b7893ccfSSadaf Ebrahimi args = parser.parse_args() 617*b7893ccfSSadaf Ebrahimi save_cwd = os.getcwd() 618*b7893ccfSSadaf Ebrahimi 619*b7893ccfSSadaf Ebrahimi # Create working "top" directory if needed 620*b7893ccfSSadaf Ebrahimi distutils.dir_util.mkpath(args.dir) 621*b7893ccfSSadaf Ebrahimi abs_top_dir = os.path.abspath(args.dir) 622*b7893ccfSSadaf Ebrahimi 623*b7893ccfSSadaf Ebrahimi repos = GetGoodRepos(args) 624*b7893ccfSSadaf Ebrahimi repo_dict = {} 625*b7893ccfSSadaf Ebrahimi 626*b7893ccfSSadaf Ebrahimi print('Starting builds in {d}'.format(d=abs_top_dir)) 627*b7893ccfSSadaf Ebrahimi for repo in repos: 628*b7893ccfSSadaf Ebrahimi # If the repo has a platform whitelist, skip the repo 629*b7893ccfSSadaf Ebrahimi # unless we are building on a whitelisted platform. 630*b7893ccfSSadaf Ebrahimi if not repo.on_build_platform: 631*b7893ccfSSadaf Ebrahimi continue 632*b7893ccfSSadaf Ebrahimi 633*b7893ccfSSadaf Ebrahimi field_list = ('url', 634*b7893ccfSSadaf Ebrahimi 'sub_dir', 635*b7893ccfSSadaf Ebrahimi 'commit', 636*b7893ccfSSadaf Ebrahimi 'build_dir', 637*b7893ccfSSadaf Ebrahimi 'install_dir', 638*b7893ccfSSadaf Ebrahimi 'deps', 639*b7893ccfSSadaf Ebrahimi 'prebuild', 640*b7893ccfSSadaf Ebrahimi 'prebuild_linux', 641*b7893ccfSSadaf Ebrahimi 'prebuild_windows', 642*b7893ccfSSadaf Ebrahimi 'custom_build', 643*b7893ccfSSadaf Ebrahimi 'cmake_options', 644*b7893ccfSSadaf Ebrahimi 'ci_only', 645*b7893ccfSSadaf Ebrahimi 'build_step', 646*b7893ccfSSadaf Ebrahimi 'build_platforms', 647*b7893ccfSSadaf Ebrahimi 'repo_dir', 648*b7893ccfSSadaf Ebrahimi 'on_build_platform') 649*b7893ccfSSadaf Ebrahimi repo_dict[repo.name] = {field: getattr(repo, field) for field in field_list} 650*b7893ccfSSadaf Ebrahimi 651*b7893ccfSSadaf Ebrahimi # If the repo has a CI whitelist, skip the repo unless 652*b7893ccfSSadaf Ebrahimi # one of the CI's environment variable is set to true. 653*b7893ccfSSadaf Ebrahimi if len(repo.ci_only): 654*b7893ccfSSadaf Ebrahimi do_build = False 655*b7893ccfSSadaf Ebrahimi for env in repo.ci_only: 656*b7893ccfSSadaf Ebrahimi if not env in os.environ: 657*b7893ccfSSadaf Ebrahimi continue 658*b7893ccfSSadaf Ebrahimi if os.environ[env].lower() == 'true': 659*b7893ccfSSadaf Ebrahimi do_build = True 660*b7893ccfSSadaf Ebrahimi break 661*b7893ccfSSadaf Ebrahimi if not do_build: 662*b7893ccfSSadaf Ebrahimi continue 663*b7893ccfSSadaf Ebrahimi 664*b7893ccfSSadaf Ebrahimi # Clone/update the repository 665*b7893ccfSSadaf Ebrahimi repo.Checkout() 666*b7893ccfSSadaf Ebrahimi 667*b7893ccfSSadaf Ebrahimi # Build the repository 668*b7893ccfSSadaf Ebrahimi if args.do_build and repo.build_step != 'skip': 669*b7893ccfSSadaf Ebrahimi repo.Build(repos, repo_dict) 670*b7893ccfSSadaf Ebrahimi 671*b7893ccfSSadaf Ebrahimi # Need to restore original cwd in order for CreateHelper to find json file 672*b7893ccfSSadaf Ebrahimi os.chdir(save_cwd) 673*b7893ccfSSadaf Ebrahimi CreateHelper(args, repos, os.path.join(abs_top_dir, 'helper.cmake')) 674*b7893ccfSSadaf Ebrahimi 675*b7893ccfSSadaf Ebrahimi sys.exit(0) 676*b7893ccfSSadaf Ebrahimi 677*b7893ccfSSadaf Ebrahimi 678*b7893ccfSSadaf Ebrahimiif __name__ == '__main__': 679*b7893ccfSSadaf Ebrahimi main() 680