1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A helper script for setting up forwarding headers."""
import errno
import os
import sys
def GetHeaderFilesInDir(dir_path):
"""Return a list of all header files under dir_path
(as absolute native paths)."""
all_files = []
for root, dirs, files in os.walk(dir_path):
all_files.extend([os.path.join(root, f) for f in files if f.endswith('.h')])
return all_files
def PathForInclude(path):
# We should always use unix-style forward slashes in #includes.
return path.replace(os.sep, '/')
def NativePath(path):
return path.replace('/', os.sep)
def PathForGyp(path):
# GYP will try to shell-escape backslashes, so we should always
# return unix-style paths with forward slashes as the directory separators.
return path.replace(os.sep, '/')
def Inputs(args):
"""List the files in the provided input dir.
args: A list with 1 value, the input dir.
Returns: 0 on success, other value on error."""
if len(args) != 1:
print "'inputs' expects only one input directory."
return -1
for filename in GetHeaderFilesInDir(args[0]):
print PathForGyp(filename)
return 0
def Outputs(args):
"""Takes an input dir and an output dir and figures out new output files
based on copying from the input dir to the output dir.
args: A list with 2 values, the input dir and the output dir.
Returns: 0 on success, other value on error."""
if len(args) != 2:
print "'outputs' expects an input directory and an output directory."
return -1
base_input_dir = NativePath(args[0])
output_dir = NativePath(args[1])
input_files = GetHeaderFilesInDir(base_input_dir)
for filename in input_files:
rel_path = os.path.relpath(filename, base_input_dir)
print PathForGyp(os.path.join(output_dir, rel_path))
def SetupHeaders(args):
"""Takes an input dir and an output dir and sets up forwarding headers
from output dir to files in input dir.
args: A list with 3 values, the input dir, the output dir, and the dir
that #include paths will be relative to..
Returns: 0 on success, other value on error."""
if len(args) != 3:
print ("'setup_headers' expects an input directory, an output directory, ."
"and a directory to make includes relative to.")
return -1
base_input_dir = NativePath(args[0])
output_dir = NativePath(args[1])
relative_to_dir = NativePath(args[2])
input_files = GetHeaderFilesInDir(base_input_dir)
for input_filename in input_files:
rel_path = os.path.relpath(input_filename, base_input_dir)
out_filename = os.path.join(output_dir, rel_path)
TryToMakeDir(os.path.split(out_filename)[0])
WriteForwardingHeader(input_filename, out_filename, relative_to_dir)
def TryToMakeDir(dir_name):
"""Create the directory dir_name if it doesn't exist."""
try:
os.makedirs(dir_name)
except OSError, e:
if e.errno != errno.EEXIST:
raise e
def WriteForwardingHeader(input_filename, out_filename, relative_to_dir):
"""Create a forwarding header from out_filename to input_filename."""
# Windows has a file path limit of 260 characters, which can be hit when
# generating these forwarding headers. Instead of using an include
# that specifies the path relative to out_filename's dir, we compute a path
# relative to relative_to_dir, which must be included in gyp's include_dirs
# settings for this to work. Even those this is really only needed on
# Windows, we do this on all platforms to be consistent.
rel_path = os.path.relpath(input_filename, relative_to_dir)
out_file = open(out_filename, 'w')
out_file.write("""// This file is generated. Do not edit.
// The include is relative to "%s".
#include "%s"
""" % (os.path.abspath(relative_to_dir), PathForInclude(rel_path)))
out_file.close()
def Main(argv):
commands = {
'inputs': Inputs,
'outputs': Outputs,
'setup_headers': SetupHeaders,
}
command = argv[1]
args = argv[2:]
return commands[command](args)
if __name__ == '__main__':
sys.exit(Main(sys.argv))
|