1fd03db0fe9c7a7f72df560b2039f2c3050c2fab9epoger@google.com# Copyright 2011 Google Inc.
2877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com#
3fd03db0fe9c7a7f72df560b2039f2c3050c2fab9epoger@google.com# Use of this source code is governed by a BSD-style license that can be
4fd03db0fe9c7a7f72df560b2039f2c3050c2fab9epoger@google.com# found in the LICENSE file.
5877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
6877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com# "Makefile" replacement to build skia for Windows.
79c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com# More info at https://sites.google.com/site/skiadocs/
87815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com#
97815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com# Some usage examples:
107815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com#   make clean
117815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com#   make tests
127815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com#   make bench BUILDTYPE=Release
137815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com#   make gm GYP_DEFINES=skia_scalar=fixed BUILDTYPE=Release
147815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com#   make all
15877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
16877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comimport os
17877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comimport shutil
18877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comimport sys
19877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
200fb212581440a63edcc695a34302e96605989a11epoger@google.comBUILDTYPE = 'Debug'
210fb212581440a63edcc695a34302e96605989a11epoger@google.com
227815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com# special targets
239c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.comTARGET_ALL     = 'all'
249c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.comTARGET_CLEAN   = 'clean'
259c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.comTARGET_DEFAULT = 'most'
269c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.comTARGET_GYP     = 'gyp'
27877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
28877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comSCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
29a82c9eb5984d7bac69980a52ecac8bbc032802e1borenet@google.comOUT_SUBDIR = os.environ.get('SKIA_OUT', 'out')
30877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comGYP_SUBDIR = 'gyp'
31877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
32877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
33877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com# Simple functions that report what they are doing, and exit(1) on failure.
34877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comdef cd(path):
35877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    print '> cd %s' % path
360fb212581440a63edcc695a34302e96605989a11epoger@google.com    if not os.path.isdir(path):
370fb212581440a63edcc695a34302e96605989a11epoger@google.com        print 'directory %s does not exist' % path
38877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        sys.exit(1)
39877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    os.chdir(path)
40877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
41877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comdef rmtree(path):
42877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    print '> rmtree %s' % path
43877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    shutil.rmtree(path, ignore_errors=True)
44877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
45877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comdef runcommand(command):
46877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    print '> %s' % command
47877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    if os.system(command):
48877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        sys.exit(1)
49877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
50877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comdef MakeClean():
51877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    """Cross-platform "make clean" operation."""
52877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    cd(SCRIPT_DIR)
53877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    rmtree(OUT_SUBDIR)
54877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
55877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
56877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.comdef CheckWindowsEnvironment():
57877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    """For Windows: check environment variables needed for command-line build.
58877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
59877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    If those environment variables are missing, try to set them.
60877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    If environment variables can be set up, this function returns; otherwise,
61877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    it displays an error message and exits.
62877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    """
63877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    # If we already have the proper environment variables, nothing to do here.
64877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    try:
65877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        env_DevEnvDir = os.environ['DevEnvDir']
66877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        return  # found it, so we are done
67877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    except KeyError:
68877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        pass # go on and run the rest of this function
69877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
70877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    print ('\nCould not find Visual Studio environment variables.'
71877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com           '\nPerhaps you have not yet run vcvars32.bat as described at'
72877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com           '\nhttp://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx ?')
73877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    found_path = None
74877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    try:
75877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        possible_path = os.path.abspath(os.path.join(
76877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com            os.environ['VS100COMNTOOLS'], os.path.pardir, os.path.pardir,
77877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com            'VC', 'bin', 'vcvars32.bat'))
78877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        if os.path.exists(possible_path):
79877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com            found_path = possible_path
80877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    except KeyError:
81877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        pass
82877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    if found_path:
83877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        print '\nIt looks like you can run that script at:\n%s' % found_path
84877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    else:
85877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        print '\nUnable to find vcvars32.bat on your system.'
86877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    sys.exit(1)
87877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
88877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
897815e73c65a12541c31bd2e630a2d6549744181cepoger@google.comdef MakeWindows(targets):
90877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    """For Windows: build as appropriate for the command line arguments.
91877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
92877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    parameters:
937815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        targets: build targets as a list of strings
94877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    """
959118413608e277b4500130bc2117400f9d9b0201Eric Boren    if os.environ.get('CHROME_HEADLESS', '0') != '1':
969118413608e277b4500130bc2117400f9d9b0201Eric Boren        # TODO(epoger): I'm not sure if this is needed for ninja builds.
979118413608e277b4500130bc2117400f9d9b0201Eric Boren        CheckWindowsEnvironment()
980fb212581440a63edcc695a34302e96605989a11epoger@google.com
99877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    # Run gyp_skia to prepare Visual Studio projects.
100877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    cd(SCRIPT_DIR)
101877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    runcommand('python gyp_skia')
1020fb212581440a63edcc695a34302e96605989a11epoger@google.com
10358d69d846071ff9a84e879041f2f092006bfcd14epoger@google.com    # We already built the gypfiles...
10458d69d846071ff9a84e879041f2f092006bfcd14epoger@google.com    while TARGET_GYP in targets:
10558d69d846071ff9a84e879041f2f092006bfcd14epoger@google.com        targets.remove(TARGET_GYP)
10658d69d846071ff9a84e879041f2f092006bfcd14epoger@google.com
10758d69d846071ff9a84e879041f2f092006bfcd14epoger@google.com    # And call ninja to do the work!
10858d69d846071ff9a84e879041f2f092006bfcd14epoger@google.com    if targets:
10958d69d846071ff9a84e879041f2f092006bfcd14epoger@google.com        runcommand('ninja -C %s %s' % (
11058d69d846071ff9a84e879041f2f092006bfcd14epoger@google.com            os.path.join(OUT_SUBDIR, BUILDTYPE), ' '.join(targets)))
1117815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com
1127815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com
1137815e73c65a12541c31bd2e630a2d6549744181cepoger@google.comdef Make(args):
1147815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    """Main function.
1157815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com
1167815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    parameters:
1177815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        args: command line arguments as a list of strings
1187815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    """
1197815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    # handle any variable-setting parameters or special targets
1207815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    global BUILDTYPE
1219c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com
1229c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com    # if no targets were specified at all, make default target
1239c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com    if not args:
1249c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com        args = [TARGET_DEFAULT]
1259c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com
1267815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    targets = []
1277815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    for arg in args:
1286714ea4e4d96ad49c79ad51959db980141c56c38epoger@google.com        # If user requests "make all", chain to our explicitly-declared "everything"
1296714ea4e4d96ad49c79ad51959db980141c56c38epoger@google.com        # target. See https://code.google.com/p/skia/issues/detail?id=932 ("gyp
1306714ea4e4d96ad49c79ad51959db980141c56c38epoger@google.com        # automatically creates "all" target on some build flavors but not others")
1317815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        if arg == TARGET_ALL:
1326714ea4e4d96ad49c79ad51959db980141c56c38epoger@google.com            targets.append('everything')
1337815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        elif arg == TARGET_CLEAN:
134877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com            MakeClean()
1357815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        elif arg.startswith('BUILDTYPE='):
1367815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com            BUILDTYPE = arg[10:]
1377815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        elif arg.startswith('GYP_DEFINES='):
1387815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com            os.environ['GYP_DEFINES'] = arg[12:]
139877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        else:
1407815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com            targets.append(arg)
1417815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com
1427815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    # if there are no remaining targets, we're done
1437815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    if not targets:
1447815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        sys.exit(0)
1457815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com
1467815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    # dispatch to appropriate Make<Platform>() variant.
1477815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    if os.name == 'nt':
1487815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        MakeWindows(targets)
1497815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        sys.exit(0)
1507815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    elif os.name == 'posix':
1517815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        if sys.platform == 'darwin':
1527815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com            print 'Mac developers should not run this script; see ' \
1539c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com                'https://sites.google.com/site/skiadocs/user-documentation/quick-start-guides/mac'
1547815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com            sys.exit(1)
1557815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        elif sys.platform == 'cygwin':
1569c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com            print 'Windows development on Cygwin is not currently supported; see ' \
1579c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com                'https://sites.google.com/site/skiadocs/user-documentation/quick-start-guides/windows'
1587815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com            sys.exit(1)
1597815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        else:
1607815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com            print 'Unix developers should not run this script; see ' \
1619c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com                'https://sites.google.com/site/skiadocs/user-documentation/quick-start-guides/linux'
1627815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com            sys.exit(1)
163877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com    else:
1647815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com        print 'unknown platform (os.name=%s, sys.platform=%s); see %s' % (
1659c875d34ff13d82f581448ced0d9eb5b067368b9epoger@google.com            os.name, sys.platform, 'https://sites.google.com/site/skiadocs/')
166877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com        sys.exit(1)
1677815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com    sys.exit(0)
1687815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com
1697815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com
1707815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com# main()
1717815e73c65a12541c31bd2e630a2d6549744181cepoger@google.comMake(sys.argv[1:])
1727815e73c65a12541c31bd2e630a2d6549744181cepoger@google.com
173877cfe380d396ffe688125ee55f541930b1f5a21epoger@google.com
174