甲胄是什么意思| 京兆尹是什么官| 指甲硬是什么原因| 刺身是什么意思| 小孩喜欢趴着睡觉是什么原因| 一什么老虎| 双侧肋膈角锐利是什么意思| 今天是什么年| 梦到很多蛇是什么意思| 小孩子发烧是什么原因引起的| complex是什么意思| 膝盖疼是什么原因引起的| 珊瑚色是什么颜色| 腰闪了是什么症状| 高考什么时候结束| 开学买什么| 吃鱼有什么好处| 什么是膝关节退行性变| 权衡利弊的意思是什么| 胃胀胃不消化吃什么药| 孕中期失眠是什么原因| 输卵管堵塞有什么样症状| 八段锦什么时候练最好| 6541是什么药| 牛皮癣是什么样的| 鼠目寸光是什么意思| 退烧药吃多了有什么副作用| 撒尿分叉是什么原因| 12min是什么意思| m什么意思| 挽联是什么意思| 咖喱是什么做的| 直肠ca代表什么病| 宫保鸡丁是什么菜系| 师夷长技以制夷是什么意思| 胃寒喝什么茶暖胃养胃| 百什么争什么| 鼻涕倒流到咽喉老吐痰吃什么药能根治| 马粟是什么| 甲鱼吃什么东西| 南红是什么| 语五行属什么| 尿路感染需要做什么检查| nt检查需要注意什么| 什么是灰指甲| 韭菜不能和什么一起吃| 编程属于什么专业| 压脚背有什么好处| 无缝衔接什么意思| 高铁动力来源是什么| 生意盎然什么意思| 属猪男和什么属相最配| 吃槐花有什么好处| 山东登州府现在叫什么| 锁阳泡酒有什么功效| 血小板吃什么补得快点| 5月4号是什么星座| 病案首页是什么| 211是什么| 缺营养吃什么补身体最好| 解构是什么意思| 拔牙后能吃什么东西| ppe是什么| 梦游的人为什么不能叫醒| 梦见挖坟墓预示什么| 界限性脑电图是什么意思| 嘴苦是什么情况| 黄连水有什么作用与功效| 肺结节是什么症状| 瘘管是什么病| 鲁班是干什么的| 肩膀麻木是什么原因引起的| 左心室高电压什么意思| hb是什么意思医学| 骨质疏松有什么症状| 为什么积食发烧很难退| 激素6项检查是些什么| 晨勃是什么意思| 掉头发缺什么维生素| 阿耨多罗三藐三菩提是什么意思| 镶什么牙实惠耐用| 海藻面膜有什么作用| 专案组是什么意思| 荷叶搭配什么一起喝减肥效果好| 达字五行属什么| jps是什么意思| 罗可以组什么词| 宝宝在肚子里打嗝是什么原因| 吃什么可以减肥肚子| 1月16日什么星座| 薄荷长什么样| 今天是什么节气24节气| 羊水多了对宝宝有什么影响| 9月19是什么星座| 不耐受和过敏有什么区别| 满目苍夷是什么意思| 忌什么意思| 婴儿什么时候长牙齿| 5点到7点是什么时辰| rm是什么位置| 字母圈什么意思| rosa是什么意思| 倒拔垂杨柳是什么意思| 上火为什么会牙疼| 18kgp是什么意思| 轮状胎盘是什么意思| 洋葱配什么菜炒好吃| 植入是什么意思| 更年期一般在什么年龄| c2驾驶证能开什么车| 氨基比林是什么药| 射手座男生喜欢什么样的女生| dg是什么| 刘备和刘表什么关系| 惜败是什么意思| 月经期喝什么汤好| 林冲属于什么生肖| kda什么意思| pad是什么| fic是什么意思| 乾隆为什么长寿| 胃出血有什么症状| kipling是什么牌子| 口臭要做什么检查| 一什么点心| 基础代谢是什么| joola是什么牌子| 脸上浮肿是什么原因导致的| 六月底是什么星座| 技压群雄的意思是什么| 6.15是什么日子| 膀胱不充盈什么意思| 属鼠的和什么属相相克| 黄精有什么作用和功效| 低筋面粉可以做什么| 经常犯困是什么原因| 虎鲸为什么对人类友好| 冬眠是什么意思| 痰多是什么原因造成的| 长裙配什么鞋子好看| 青蛙喜欢吃什么| 自我价值是什么意思| 屁股后面骨头疼是什么原因| 脚趾头抽筋是什么原因引起的| 耐克是什么牌子| 脑梗适合吃什么食物| 1月27日什么星座| 封闭针是什么| 人为什么会长痣| 黑便是什么原因| 多吃蒜有什么好处和坏处| 十月7号是什么星座| 间质性肺炎是什么意思| 斑鸠和鸽子有什么区别| 儿女情长英雄气短是什么意思| 年柱金舆是什么意思| 朱砂是什么做的| 印绶是什么意思| 神经纤维瘤挂什么科| 法是什么| rc是什么| 灵魂伴侣是指什么意思| 毓字五行属什么| 苦瓜泡酒有什么功效和作用| 非洲人吃什么主食| 释怀什么意思| 被螨虫咬了非常痒用什么药膏好| 外油内干是什么肤质| 二月二十五号是什么星座| 小腹痛吃什么药| 门槛是什么意思| 经常放屁是什么问题| 梦见已故老人是什么预兆| 陈皮泡水喝有什么作用| 羊水穿刺是检查什么的| 姑奶奶是什么意思| 安乐片是什么药| 上嘴唇上有痣代表什么| 鸡内金有什么功效| 慢性结肠炎是什么症状| 大便不正常是什么原因造成的| 检查腰部挂什么科| 黄豆什么时候播种| 黄喉是什么部位| 尿蛋白高是什么病| 非洲有什么动物| 狐狸和乌鸦告诉我们什么道理| 活泼开朗是什么意思| 为什么水晶要消磁| 小姐姐是什么意思| 手脚经常发麻是什么原因| 柠檬什么时候开花结果| 爱情公寓6什么时候上映| 皮卡丘什么意思| 吃菠萝有什么好处| 寸金难买寸光阴什么意思| 簋是什么| 81什么意思| 打嗝吃什么药效果好| 人几读什么| 办健康证要带什么| 借力是什么意思| 鸭子烧什么好吃| 赵字五行属什么| 全身骨头疼是什么原因| 经常吃维生素c有什么好处和坏处| 央行行长什么级别| 肌酐低是什么原因| 鹅口疮是什么原因引起的| 家是什么生肖| 撸铁是什么| 肝内低密度灶是什么意思| rm是什么意思| 什么颜色的衣服显白| 三焦是什么器官| 口比念什么| g50是什么高速| 雪村和赵英俊什么关系| 牙疼吃什么药效果好| buds是什么意思| 三教九流什么意思| 梦见小白兔是什么意思| 联姻是什么意思| 纸尿裤和拉拉裤有什么区别| 半夜12点是什么时辰| 腰疼吃什么药最有效| 梦见自己掉牙是什么意思| 女孩子喜欢什么礼物| 宝宝爱出汗是什么原因| 芒果吃多了有什么坏处| 紧迫感是什么意思| 免疫性疾病是什么意思| 东道主是什么意思| 仙茅配什么壮阳效果好| abby是什么意思| 什么人招蚊子| 头痛反胃想吐什么原因| 什么是腺肌症| 什么叫低级别上皮内瘤变| 教主是什么意思| 机体是什么意思| 兔子为什么不吃窝边草| 芥末是什么做的| laurel是什么牌子| 头发出油是什么原因| 护理部主任是什么级别| 五花八门是什么意思| 梦寐以求是什么意思| gag是什么意思| 五心烦热吃什么药| 598是什么意思| 鸡肉配什么菜好吃| 人心是什么意思| 君臣佐使是什么意思| 抗体弱阳性是什么意思| 肚子痛去医院挂什么科| 手术后吃什么鱼伤口愈合快| 话说多了声音嘶哑是什么原因| 空鼻症是什么| 人流后能吃什么水果| 怀孕一个月出血是什么情况| 避火图是什么| 冷幽默是什么意思| 什么是拘役| 百度
blob: d23e2f22d3379eb03314a909c4e16194a53c8626 [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2011 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Usage: Run with the '--help' flag to see how to use this script.
This tool will take a PDB on the command line, extract the source files that
were used in building the PDB, query the source server for which repository
and revision these files are at, and then finally write this information back
into the PDB in a format that the debugging tools understand. This allows for
automatic source debugging, as all of the information is contained in the PDB,
and the debugger can go out and fetch the source files.
You most likely want to run these immediately after a build, since the source
input files need to match the generated PDB, and we want the correct
revision information for the exact files that were used for the build.
Here's a quick overview of what this script does:
- Extract the list of source files listed in the PDB, i.e. all the source
files that have been used to produce the matching binary. This list contains
some files for which the source code is accessible (e.g. files from the
Chromium repo) and some from private repos (e.g. files that have been used
to build the CRT static library that we link against).
- Iterate over the list of files from the previous step, from here there's a
few different possibilities:
- This file is coming from a public Git repository (e.g. Chromium), in
this case this script will list all the files that are contained in this
repository and index them all at once (and then remove them from the
file list it's iterating over).
- This file is a generated file produced during the build. It will likely
be living in a subdirectory of the build directory, if the "--build-dir"
flag has been passed to this flag this flag this directory will be
automatically ignored.
- The directory containing this file isn't part of a Git checkout, this
file will be excluded and all the files from this directory will get
added to an exclusion list. Specifying the toolchain directory (via the
"--toolchain-dir" flag) allow automatically skipping all the files from
the VS toolchain directory (e.g. all the CRT files), this is much faster
than using Git to check if these files are from a Git repo.
- This file doesn't exist on disk, which means that it is coming from a
third party static library. This file will be ignored.
- A map that associates each source file to a public URL will be added in a
new stream in the PDB.
NOTE: Expected to run under a native win32 python, NOT cygwin. All paths are
dealt with as win32 paths, since we have to interact with the Microsoft tools.
"""
import optparse
import os
import re
import subprocess
import sys
import tempfile
import time
import win32api
from collections import namedtuple
from urllib.parse import urlparse
# Map that associates Git repository URLs with the URL that should be used to
# retrieve individual files from this repo. Entries in this map should have the
# following format:
# {
# 'url': |path to public URL, with the {revision} and {file_path} tags|,
# 'base64': |boolean indicating if the files are base64 encoded|
# }
#
# Here's an example of what the entry for the Chromium repo looks like:
# {
# 'url': 'chromium.googlesource/+/{revision}/{file_path}?format=TEXT',
# 'base64': True
# }
#
# The {revision} and {file_path} will be replaced by the appropriate values when
# building the source indexing map that gets added to the PDB.
#
# TODO(sebmarchand): Check if this is really needed, this is a legacy thing
# coming from when this script was used for SVN repos and we could probably do
# without it.
REPO_MAP = {}
# Regex matching a junction at it's printed by the 'dir' command.
# It usually looks like this when the junction has been created with mklink:
#
# Directory of C:\a
#
# 07/23/2015 06:42 PM <JUNCTION> b [C:\real_a\b]
#
# The junctions created with the 'junction' utility look almost the same, except
# for a leading '\??\' on the junction target:
#
# 07/23/2015 06:42 PM <JUNCTION> b [\??\C:\real_a\b]
_DIR_JUNCTION_RE = re.compile(r"""
.*<JUNCTION\>\s+(?P<dirname>[^ ]+)\s+\[(\\\?\?\\)?(?P<real_path>.*)\]
""", re.VERBOSE)
# A named tuple used to store the information about a repository.
#
# It contains the following members:
# - repo: The URL of the repository;
# - rev: The revision (or hash) of the current checkout.
# - file_list: The list of files coming from this repository.
# - root_path: The root path of this checkout.
# - path_prefix: A prefix to apply to the filename of the files coming from
# this repository.
RevisionInfo = namedtuple('RevisionInfo',
['repo', 'rev', 'files', 'root_path', 'path_prefix'])
def GetCasedFilePath(filename):
"""Return the correctly cased path for a given filename"""
return win32api.GetLongPathName(win32api.GetShortPathName(str(filename)))
def FindSrcSrvFile(filename, toolchain_dir):
"""Return the absolute path for a file in the srcsrv directory.
If |toolchain_dir| is null then this will assume that the file is in this
script's directory.
"""
bin_dir = os.path.join(toolchain_dir, 'Windows Kits', '10', 'Debuggers',
'x64', 'srcsrv')
if not os.path.exists(bin_dir):
bin_dir = os.path.join(toolchain_dir, 'win_sdk', 'Debuggers', 'x64',
'srcsrv')
assert(os.path.exists(bin_dir))
return os.path.abspath(os.path.join(bin_dir, filename))
def RunCommand(*cmd, **kwargs):
"""Runs a command.
Returns what have been printed to stdout by this command.
kwargs:
raise_on_failure: Indicates if an exception should be raised on failure, if
set to false then the function will return None.
"""
kwargs.setdefault('stdin', subprocess.PIPE)
kwargs.setdefault('stdout', subprocess.PIPE)
kwargs.setdefault('stderr', subprocess.PIPE)
kwargs.setdefault('universal_newlines', True)
kwargs.setdefault('encoding', 'utf-8')
raise_on_failure = kwargs.pop('raise_on_failure', True)
proc = subprocess.Popen(cmd, **kwargs)
ret, err = proc.communicate()
if proc.returncode != 0:
if raise_on_failure:
print('Error: %s' % err)
raise subprocess.CalledProcessError(proc.returncode, cmd)
return
ret = (ret or '').rstrip('\n')
return ret
def ExtractSourceFiles(pdb_filename, toolchain_dir):
"""Extract a list of local paths of the source files from a PDB."""
# Don't use |RunCommand| as it expect the return code to be 0 on success but
# srctool returns the number of files instead.
srctool = subprocess.Popen([FindSrcSrvFile('srctool.exe', toolchain_dir),
'-r', pdb_filename],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
universal_newlines=True)
src_files, _ = srctool.communicate()
if (not src_files or src_files.startswith("srctool: ") or
srctool.returncode <= 0):
raise Exception("srctool failed: " + src_files)
return set(
x.rstrip('\n').lower() for x in src_files.split('\n') if len(x) != 0)
def ReadSourceStream(pdb_filename, toolchain_dir):
"""Read the contents of the source information stream from a PDB."""
pdbstr = subprocess.Popen([FindSrcSrvFile('pdbstr.exe', toolchain_dir),
'-r', '-s:srcsrv',
'-p:%s' % pdb_filename],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
data, _ = pdbstr.communicate()
data = data.decode('utf-8')
# Old version of pdbstr.exe return -1 when the source requested stream is
# missing, while more recent ones return 1, use |abs| to workaround this.
if (((pdbstr.returncode != 0 and abs(pdbstr.returncode) != 1) or
data.startswith("pdbstr: "))):
raise Exception("pdbstr failed: " + data)
return data
def WriteSourceStream(pdb_filename, data, toolchain_dir):
"""Write the contents of the source information stream to a PDB."""
# Write out the data to a temporary filename that we can pass to pdbstr.
(f, fname) = tempfile.mkstemp()
f = os.fdopen(f, "wb")
f.write(data.encode('utf-8'))
f.close()
srctool = subprocess.Popen([FindSrcSrvFile('pdbstr.exe', toolchain_dir),
'-w', '-s:srcsrv',
'-i:%s' % fname,
'-p:%s' % pdb_filename],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
data, _ = srctool.communicate()
data = data.decode('utf-8')
if ((srctool.returncode != 0 and srctool.returncode != -1) or
data.startswith("pdbstr: ")):
raise Exception("pdbstr failed: " + data)
os.unlink(fname)
def ExtractGitInfo(local_filename):
"""Checks if a file is coming from a git repository and if so returns some
information about it.
Args:
local_filename: The name of the file that we want to check.
Returns:
None if the file doesn't come from a git repository, otherwise it returns a
RevisionInfo tuple.
"""
# Starts by checking if this file is coming from a git repository. For that
# we'll start by calling 'git info' on this file; for this to work we need to
# make sure that the current working directory is correctly cased. It turns
# out that even on Windows the casing of the path passed in the |cwd| argument
# of subprocess.Popen matters and if it's not correctly cased then 'git info'
# will return None even if the file is coming from a git repository. This
# is not the case if we're just interested in checking if the path containing
# |local_filename| is coming from a git repository, in this case the casing
# doesn't matter.
local_filename = GetCasedFilePath(local_filename)
local_file_basename = os.path.basename(local_filename)
local_file_dir = os.path.dirname(local_filename)
file_info = RunCommand('git.bat', 'log', '-n', '1', local_file_basename,
cwd=local_file_dir, raise_on_failure=False)
if not file_info:
# If this message is being printed then it may be necessary to add a new
# entry to tools/symsrc/indexing-exclusions.txt to prevent the expensive
# calls from happening.
print('No results from running git log %s in %s. This can be expensive.' %
(local_file_basename, local_file_dir))
return
# Get the revision of the master branch.
rev = RunCommand('git.bat', 'rev-parse', 'HEAD', cwd=local_file_dir)
# Get the url of the remote repository.
repo = RunCommand('git.bat', 'config', '--get', 'remote.origin.url',
cwd=local_file_dir)
# If the repository point to a local directory then we need to run this
# command one more time from this directory to get the repository url.
if os.path.isdir(repo):
repo = RunCommand('git.bat', 'config', '--get', 'remote.origin.url',
cwd=repo)
# Don't use the authenticated path.
repo = repo.replace('googlesource.com/a/', 'googlesource.com/')
# Get the relative file path for this file in the git repository.
git_path = RunCommand('git.bat', 'ls-tree', '--full-name', '--name-only',
'HEAD', local_file_basename, cwd=local_file_dir).replace('/','\\')
if not git_path:
return
git_root_path = local_filename.replace(git_path, '')
if repo not in REPO_MAP:
# Automatically adds the project coming from a git GoogleCode or Github
# repository to the repository map.
if urlparse(repo).netloc.endswith('.googlesource.com'):
# The files from these repositories are accessible via gitiles in a
# base64 encoded format.
REPO_MAP[repo] = {
'url': '%s/+/{revision}/{file_path}?format=TEXT' % repo,
'base64': True
}
elif urlparse(repo).netloc.endswith('github.com'):
raw_url = '%s/{revision}/{file_path}' % repo.replace('.git', '').replace(
'github.com', 'raw.githubusercontent.com')
REPO_MAP[repo] = {
'url': raw_url,
'base64': False
}
# Get the list of files coming from this repository.
git_file_list = RunCommand('git.bat', 'ls-tree', '--full-name', '--name-only',
'HEAD', '-r', cwd=git_root_path)
file_list = [x for x in git_file_list.splitlines() if len(x) != 0]
return RevisionInfo(repo=repo, rev=rev, files=file_list,
root_path=git_root_path, path_prefix=None)
def CheckForJunction(filename):
"""Check if a directory containing a file is a junction to another directory.
If so return 3 values:
- The real path to this file.
- The root directory of this checkout relative to |filename| (i.e. not
relative to the real path).
- The sub directory of the repository that has been checked out.
"""
# Process the path of |filename| from right to left until a junction has been
# found.
#
# Here's an example of what this does, for this example
# |filename| = 'C:/a/b/c/d.h' and 'C:/a' is a junction to 'C:/real_a/'.
#
# - We remove the filename part (we're only looking at directory junctions
# here), that left us with 'C:/a/b/c'.
# - During the first iteration we take 'C:/a/b' as our current root value and
# 'c' as the leaf value.
# - We run the 'dir' command on 'C:/a/b' and we look for a junction to 'c'. As
# we don't find any we go up one directory. Now the current root is 'C:/a'
# and the current leaf value is 'b'.
# - We run the 'dir' command on 'C:/a' and we look for a junction to 'b'. This
# time we find one so we return the following triplet:
# - C:/real_a/b/c/d.h # The real file path.
# - C:/a # The root directory containing this junction.
# - b # The name of the junction.
cur_root, cur_leaf = os.path.split(os.path.dirname(filename))
while cur_leaf:
# Run the 'dir' command and look for a junction.
dir_cmd = RunCommand('cmd', '/c', 'dir', cur_root)
for entry in dir_cmd.splitlines():
m = _DIR_JUNCTION_RE.match(entry)
if not m:
continue
if not m.group('dirname') == cur_leaf:
continue
real_path = filename.replace(os.path.join(cur_root, cur_leaf),
m.group('real_path'))
# This should always be the case.
# TODO(sebmarchand): Remove this check if it proves to be useless.
if os.path.exists(real_path):
return real_path, cur_root, cur_leaf
else:
print('Source indexing: error: Unexpected non existing file \'%s\'' %
real_path)
return None, None, None
cur_root, cur_leaf = os.path.split(cur_root)
return None, None, None
def IndexFilesFromRepo(
local_filename, file_list, output_lines, follow_junctions):
"""Checks if a given file is a part of a Git repository and index all the
files from this repository if it's the case.
Args:
local_filename: The filename of the current file.
file_list: The list of files that should be indexed.
output_lines: The source indexing lines that will be appended to the PDB.
follow_junctions: Indicates if we should try to index the files in a
junction.
Returns the number of indexed files.
"""
indexed_files = 0
patch_root = None
# Try to extract the revision info for the current file.
info = ExtractGitInfo(local_filename)
# If we haven't been able to find information for this file it might be
# because its path contains a junction to another directory. It can be the
# case if you do a Git checkout in C:/real_a/ and you're adding a junction to
# one of the subdirectories (lets say 'b') of this checkout in another
# project (e.g. 'C:/a'), so you'll end up with a partial Git checkout in a
# junction, and any Git command in the path of the junction won't work (or
# it'll return information related to 'C:/a' instead of 'C:/real_a').
if not info and follow_junctions:
real_filename, patch_root, patch_leaf = CheckForJunction(local_filename)
if real_filename:
info = ExtractGitInfo(real_filename)
# Don't try to index the internal sources.
if not info or ('internal.googlesource.com' in info.repo):
return 0
repo = info.repo
rev = info.rev
files = info.files
if patch_root:
files = [x for x in files if x.startswith(patch_leaf)]
root_path = patch_root.lower()
else:
root_path = info.root_path.lower()
# Checks if we should index this file and if the source that we'll retrieve
# will be base64 encoded.
should_index = False
base_64 = False
if repo in REPO_MAP:
should_index = True
base_64 = REPO_MAP[repo].get('base64')
else:
repo = None
# Iterates over the files from this repo and index them if needed.
for file_iter in files:
current_filename = file_iter.lower()
full_file_path = os.path.normpath(os.path.join(root_path, current_filename))
# Checks if the file is in the list of files to be indexed.
if full_file_path in file_list:
if should_index:
source_url = ''
current_file = file_iter
# Prefix the filename with the prefix for this repository if needed.
if info.path_prefix:
current_file = os.path.join(info.path_prefix, current_file)
source_url = REPO_MAP[repo].get('url').format(revision=rev,
file_path=os.path.normpath(current_file).replace('\\', '/'))
output_lines.append('%s*%s*%s*%s*%s' % (full_file_path, current_file,
rev, source_url, 'base64.b64decode' if base_64 else ''))
indexed_files += 1
file_list.remove(full_file_path)
# The input file should have been removed from the list of files to index.
if indexed_files and local_filename in file_list:
print('%s shouldn\'t be in the list of files to index anymore.' % \
local_filename)
# TODO(sebmarchand): Turn this into an exception once I've confirmed that
# this doesn't happen on the official builder.
file_list.remove(local_filename)
return indexed_files
def DirectoryIsPartOfPublicGitRepository(local_dir):
# Checks if this directory is from a public Git checkout.
info = RunCommand('git.bat', 'config', '--get', 'remote.origin.url',
cwd=local_dir, raise_on_failure=False)
if info:
if 'internal.googlesource.com' in info:
return False
return True
return False
def UpdatePDB(pdb_filename,
verbose=True,
build_dir=None,
toolchain_dir=None,
exclusion_dirs=None,
follow_junctions=False):
"""Update a pdb file with source information."""
dir_exclusion_list = { }
# We want to exclude files that aren't in git repos. This includes generated
# files, toolchain files, and possibly others.
dirs = [build_dir, toolchain_dir]
if exclusion_dirs:
dirs.extend(exclusion_dirs.split(';'))
for dir in dirs:
if dir:
if not os.path.exists(dir):
print('Warning: Exclusion directory %s does not exist.' % dir)
dir = (os.path.abspath(dir)).lower()
for directory, _, _ in os.walk(dir):
dir_exclusion_list[directory.lower()] = True
dir_exclusion_list[dir.lower()] = True
# Writes the header of the source index stream.
#
# Here's the description of the variables used in the SRC_* macros (those
# variables have to be defined for every source file that we want to index):
# var1: The file path.
# var2: The name of the file without its path.
# var3: The revision or the hash of this file's repository.
# var4: The URL to this file.
# var5: (optional) The python method to call to decode this file, e.g. for
# a base64 encoded file this value should be 'base64.b64decode'.
lines = [
'SRCSRV: ini ------------------------------------------------',
'VERSION=1',
'INDEXVERSION=2',
'VERCTRL=Subversion',
'DATETIME=%s' % time.asctime(),
'SRCSRV: variables ------------------------------------------',
'SRC_EXTRACT_TARGET_DIR=%targ%\\%fnbksl%(%var2%)\\%var3%',
'SRC_EXTRACT_TARGET=%SRC_EXTRACT_TARGET_DIR%\\%fnfile%(%var1%)',
'SRC_EXTRACT_CMD=cmd /c "mkdir "%SRC_EXTRACT_TARGET_DIR%" & python3 -c '
'"import urllib.request, base64;'
'url = \\\"%var4%\\\";'
'u = urllib.request.urlopen(url);'
'open(r\\\"%SRC_EXTRACT_TARGET%\\\", \\\"wb\\\").write(%var5%('
'u.read()))"',
'SRCSRVTRG=%SRC_EXTRACT_TARGET%',
'SRCSRVCMD=%SRC_EXTRACT_CMD%',
'SRCSRV: source files ---------------------------------------',
]
if ReadSourceStream(pdb_filename, toolchain_dir):
raise Exception("PDB already has source indexing information!")
filelist = ExtractSourceFiles(pdb_filename, toolchain_dir)
number_of_files = len(filelist)
indexed_files_total = 0
t_init = time.time()
t1 = t_init
while filelist:
filename = next(iter(filelist))
filedir = os.path.dirname(filename)
if verbose:
print("[%d / %d] Processing: %s" % (number_of_files - len(filelist),
number_of_files, filename))
# Print a message every 60 seconds to make sure that the process doesn't
# time out.
if time.time() - t1 > 60:
t1 = time.time()
print("Still working, %d / %d files have been processed." %
(number_of_files - len(filelist), number_of_files))
# This directory is in the exclusion listed, either because it's not part of
# a repository, or from one we're not interested in indexing.
if dir_exclusion_list.get(filedir, False):
if verbose:
print(" skipping, directory is excluded.")
filelist.remove(filename)
continue
# Skip the files that don't exist on the current machine.
if not os.path.exists(filename):
filelist.remove(filename)
continue
# Try to index the current file and all the ones coming from the same
# repository.
indexed_files = IndexFilesFromRepo(
filename, filelist, lines, follow_junctions)
if not indexed_files:
if not DirectoryIsPartOfPublicGitRepository(filedir):
dir_exclusion_list[filedir] = True
if verbose:
print("Adding %s to the exclusion list." % filedir)
filelist.remove(filename)
continue
indexed_files_total += indexed_files
if verbose:
print(" %d files have been indexed." % indexed_files)
print('Indexing took %d seconds' % (time.time() - t_init))
lines.append('SRCSRV: end ------------------------------------------------')
WriteSourceStream(pdb_filename, '\r\n'.join(lines), toolchain_dir)
if verbose:
print("%d / %d files have been indexed." % (indexed_files_total,
number_of_files))
def main():
parser = optparse.OptionParser()
parser.add_option('-v', '--verbose', action='store_true', default=False)
parser.add_option('--build-dir', help='The original build directory, if set '
'all the files present in this directory (or one of its subdirectories) '
'will be skipped.')
parser.add_option('--toolchain-dir', help='The directory containing the VS '
'toolchain that has been used for this build. All the files present in '
'this directory (or one of its subdirectories) will be skipped.')
parser.add_option(
'--exclusion-dirs',
help='A semicolon separated list of '
'directories containing files that should be excluded from looking up '
'source control information. Note that the build-dir and toolchain-dir '
'are automatically excluded.')
parser.add_option('--follow-junctions', action='store_true',help='Indicates '
'if the junctions should be followed while doing the indexing.',
default=False)
options, args = parser.parse_args()
if not args:
parser.error('Specify a pdb.')
if not options.toolchain_dir:
parser.error('The toolchain directory should be specified.')
for pdb in args:
UpdatePDB(pdb, options.verbose, options.build_dir, options.toolchain_dir,
options.exclusion_dirs, options.follow_junctions)
return 0
if __name__ == '__main__':
sys.exit(main())
人为什么会说梦话 油耳是什么意思 9月10日是什么节 什么叫血栓 感统失调挂什么科
眼睛感染用什么眼药水 总感觉自己有病是什么心理病 ir是什么意思 iga肾病是什么意思 肝硬化适合吃什么食物
行经是什么意思 白菜是什么颜色 路政属于什么单位 吃的少还胖什么原因 柏拉图之恋是什么意思
天池为什么没有鱼 路由器什么牌子好 白带带血丝是什么原因 油面筋是什么做的 吃什么养胃又补胃
2024什么年hcv8jop0ns1r.cn 一龙一什么填十二生肖hcv8jop9ns8r.cn 腺癌是什么原因引起的hcv9jop7ns2r.cn 黄皮是什么水果hcv8jop2ns8r.cn 唐玄宗叫什么bjcbxg.com
脱线是什么意思hcv9jop8ns0r.cn 无纺布是什么材料做的hcv7jop5ns3r.cn 流连忘返的返是什么意思hcv8jop1ns2r.cn 复刻鞋是什么意思hcv8jop7ns3r.cn 老夫聊发少年狂什么意思hcv7jop9ns6r.cn
梦见怀孕是什么征兆hcv8jop2ns9r.cn 眼睛干涩发痒用什么药hcv8jop1ns2r.cn 水垢是什么hcv8jop6ns8r.cn 为什么拉屎会出血hcv8jop4ns3r.cn gree是什么牌子hcv9jop3ns3r.cn
梦到鱼是什么意思hcv8jop3ns9r.cn 痛风忌口不能吃什么东西hcv8jop8ns3r.cn 什么方什么计hcv9jop4ns8r.cn 狗的胡须有什么用xianpinbao.com 五七干校是什么意思hcv8jop9ns4r.cn
百度