Skip to content

Commit c19cc87

Browse files
Build Breakpad from source for mac build
Previously official build (--branding=GoogleJapaneseInput) for macOS build has relied on prebuilt Breakpad binaries on macOS. With this CL, Breakpad is always built from source code, including OSS (--branding=Mozc) build. Note that unless --branding=GoogleJapaneseInput is specified - |mozc::config::StatsConfigUtil::IsEnabled()| always returns false. - Crash dumps are stored in $TMPDIR/Mozc/CrashReports. - The URL of crash server is pointed to file:///dev/null, as an invalid parameter. Now Breakpad is copied to each application, which slightly increases the size of package. Here we relax the size limit of dmg file to 70MB. BUG= TEST= REF_BUG=31891161 REF_CL=135875361,136678890,136686011,136689657,136987935,137123863,137673918,137777808,139689028 REF_TIME=2016-10-20T16:30:11+09:00 REF_TIME_RAW=1476948611 +0900
1 parent f5dcadf commit c19cc87

17 files changed

+298
-171
lines changed

src/base/base.gyp

+33-1
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,16 @@
428428
],
429429
}],
430430
['OS=="mac"', {
431+
'hard_dependency': 1,
431432
'sources': [
432433
'crash_report_handler_mac.mm',
433434
],
434435
'sources!': [
435436
'crash_report_handler.cc',
436-
]
437+
],
438+
'dependencies': [
439+
'breakpad',
440+
],
437441
}],
438442
],
439443
},
@@ -534,6 +538,34 @@
534538
],
535539
['OS=="mac"', {
536540
'targets': [
541+
{
542+
'target_name': 'breakpad',
543+
'type': 'none',
544+
'variables': {
545+
'pbdir': '<(third_party_dir)/breakpad',
546+
},
547+
'actions': [{
548+
'action_name': 'build_breakpad',
549+
'inputs': [
550+
'<(pbdir)/src/client/mac/Breakpad.xcodeproj/project.pbxproj',
551+
],
552+
'outputs': [
553+
'<(mac_breakpad_dir)/Breakpad.framework',
554+
'<(mac_breakpad_dir)/Inspector',
555+
'<(mac_breakpad_dir)/dump_syms',
556+
'<(mac_breakpad_dir)/symupload',
557+
],
558+
'action': [
559+
'python', '../build_tools/build_breakpad.py',
560+
'--pbdir', '<(pbdir)', '--outdir', '<(mac_breakpad_dir)',
561+
],
562+
}],
563+
'direct_dependent_settings': {
564+
'mac_framework_dirs': [
565+
'<(mac_breakpad_dir)',
566+
],
567+
},
568+
},
537569
{
538570
'target_name': 'mac_util_main',
539571
'type': 'executable',

src/base/crash_report_handler_mac.mm

+24-20
Original file line numberDiff line numberDiff line change
@@ -31,44 +31,48 @@
3131

3232
#import "base/crash_report_handler.h"
3333

34-
#import <Cocoa/Cocoa.h>
35-
#if defined(GOOGLE_JAPANESE_INPUT_BUILD)
36-
#import <GoogleBreakpad/GoogleBreakpad.h>
37-
#endif // GOOGLE_JAPANESE_INPUT_BUILD
34+
#import "base/const.h"
35+
36+
#import <Breakpad/Breakpad.h>
37+
#import <CoreFoundation/CoreFoundation.h>
3838

3939
namespace mozc {
4040

41-
#if defined(GOOGLE_JAPANESE_INPUT_BUILD)
42-
// The reference count for GoogleBreakpad
41+
// The reference count for Breakpad
4342
int g_reference_count = 0;
4443

45-
GoogleBreakpadRef g_breakpad = nullptr;
46-
#endif // GOOGLE_JAPANESE_INPUT_BUILD
44+
BreakpadRef g_breakpad = nullptr;
4745

4846
bool CrashReportHandler::Initialize(bool check_address) {
49-
#if defined(GOOGLE_JAPANESE_INPUT_BUILD)
5047
++g_reference_count;
51-
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
52-
NSDictionary *plist = [[NSBundle mainBundle] infoDictionary];
53-
if (g_reference_count == 1 && plist != nullptr && g_breakpad == nullptr) {
54-
g_breakpad = GoogleBreakpadCreate(plist);
55-
[pool release];
56-
return true;
48+
@autoreleasepool {
49+
NSMutableDictionary *plist =
50+
[[[NSBundle mainBundle] infoDictionary] mutableCopy];
51+
if (g_reference_count == 1 && plist != nullptr && g_breakpad == nullptr) {
52+
// Create a crash reports directory under tmpdir, and set it to the plist
53+
NSString *tmpDir = NSTemporaryDirectory();
54+
// crashDir will be $TMPDIR/GoogleJapaneseInput/CrashReports
55+
NSString *crashDir = [NSString
56+
pathWithComponents:@[tmpDir, @kProductPrefix, @"CrashReports"]];
57+
[[NSFileManager defaultManager] createDirectoryAtPath:crashDir
58+
withIntermediateDirectories:YES
59+
attributes:nil
60+
error:NULL];
61+
[plist setValue:crashDir forKey:@BREAKPAD_DUMP_DIRECTORY];
62+
g_breakpad = BreakpadCreate(plist);
63+
return true;
64+
}
5765
}
58-
[pool release];
59-
#endif // GOOGLE_JAPANESE_INPUT_BUILD
6066
return false;
6167
}
6268

6369
bool CrashReportHandler::Uninitialize() {
64-
#if defined(GOOGLE_JAPANESE_INPUT_BUILD)
6570
--g_reference_count;
6671
if (g_reference_count == 0 && g_breakpad != nullptr) {
67-
GoogleBreakpadRelease(g_breakpad);
72+
BreakpadRelease(g_breakpad);
6873
g_breakpad = nullptr;
6974
return true;
7075
}
71-
#endif // GOOGLE_JAPANESE_INPUT_BUILD
7276
return false;
7377
}
7478

src/build_tools/binary_size_checker.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
# in Megabytes.
4949
EXPECTED_MAXIMUM_SIZES = {
5050
# Distribution package files:
51-
'GoogleJapaneseInput.dmg': 65,
51+
'GoogleJapaneseInput.dmg': 70,
5252
'GoogleJapaneseInput32.msi': 65,
5353
'GoogleJapaneseInput64.msi': 65,
5454
}

src/build_tools/build_breakpad.py

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright 2010-2016, Google Inc.
3+
# All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without
6+
# modification, are permitted provided that the following conditions are
7+
# met:
8+
#
9+
# * Redistributions of source code must retain the above copyright
10+
# notice, this list of conditions and the following disclaimer.
11+
# * Redistributions in binary form must reproduce the above
12+
# copyright notice, this list of conditions and the following disclaimer
13+
# in the documentation and/or other materials provided with the
14+
# distribution.
15+
# * Neither the name of Google Inc. nor the names of its
16+
# contributors may be used to endorse or promote products derived from
17+
# this software without specific prior written permission.
18+
#
19+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
31+
"""Script building Breakpad for Mozc/Mac.
32+
33+
././tools/build_breakpad.py
34+
--pbdir ./third_party/breakpad --outdir /tmp/breakpad
35+
"""
36+
37+
import optparse
38+
import os
39+
import subprocess
40+
import sys
41+
42+
43+
def ParseOption():
44+
parser = optparse.OptionParser()
45+
parser.add_option('--pbdir', default='./third_party/breakpad')
46+
parser.add_option('--outdir', default='./out_mac/Release/Breakpad')
47+
48+
(opts, _) = parser.parse_args()
49+
return opts
50+
51+
52+
def ProcessCall(command):
53+
try:
54+
subprocess.check_output(command)
55+
except subprocess.CalledProcessError as e:
56+
print e.output
57+
sys.exit(e.returncode)
58+
print 'Done: %s' % ' '.join(command)
59+
60+
61+
def Xcodebuild(projdir, target, arch, outdir):
62+
ProcessCall([
63+
'xcodebuild', '-project', projdir, '-configuration', 'Release',
64+
'-target', target, '-arch', arch, '-sdk', 'macosx10.9',
65+
'GCC_VERSION=com.apple.compilers.llvm.clang.1_0',
66+
'CONFIGURATION_BUILD_DIR=%s' % outdir,
67+
])
68+
69+
70+
def BuildBreakpad(outdir):
71+
projdir = os.path.join(outdir, 'src/client/mac/Breakpad.xcodeproj')
72+
Xcodebuild(projdir, 'Breakpad', 'i386', outdir)
73+
74+
75+
def BuildDumpSyms(outdir):
76+
projdir = os.path.join(outdir, 'src/tools/mac/dump_syms/dump_syms.xcodeproj')
77+
Xcodebuild(projdir, 'dump_syms', 'x86_64', outdir)
78+
79+
80+
def BuildSymupload(outdir):
81+
projdir = os.path.join(outdir, 'src/tools/mac/symupload/symupload.xcodeproj')
82+
# This build fails with Xcode8/i386.
83+
Xcodebuild(projdir, 'symupload', 'x86_64', outdir)
84+
85+
86+
def CreateOutDir(pbdir, outdir):
87+
workdir = os.path.join(outdir, 'src')
88+
if not os.path.isdir(workdir):
89+
os.makedirs(workdir)
90+
ProcessCall(['rsync', '-avH', os.path.join(pbdir, 'src/'), workdir])
91+
92+
93+
def main():
94+
opts = ParseOption()
95+
pbdir = os.path.abspath(opts.pbdir)
96+
outdir = os.path.abspath(opts.outdir)
97+
98+
CreateOutDir(pbdir, outdir)
99+
BuildBreakpad(outdir)
100+
BuildDumpSyms(outdir)
101+
BuildSymupload(outdir)
102+
103+
104+
if __name__ == '__main__':
105+
main()

src/build_tools/change_reference_mac.py

-6
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,6 @@ def main():
113113
'@executable_path/../Frameworks/%s' % toollib_framework,
114114
GetReferenceTo(toollib_framework))
115115

116-
# Change the reference to GoogleBreakpad from the target application
117-
breakpad_framework = GetFrameworkPath('GoogleBreakpad', 'A')
118-
InstallNameTool(target,
119-
'@executable_path/../Frameworks/%s' % breakpad_framework,
120-
GetReferenceTo(breakpad_framework))
121-
122116

123117
if __name__ == '__main__':
124118
main()

src/build_tools/tweak_info_plist.py

+14-5
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,22 @@ def main():
8181

8282
version = mozc_version.MozcVersion(options.version_file)
8383

84-
# \xC2\xA9 is the copyright mark in UTF-8
85-
copyright_message = '\xC2\xA9 %d Google Inc.' % _COPYRIGHT_YEAR
84+
copyright_message = (u'© %d Google Inc.' % _COPYRIGHT_YEAR).encode('utf-8')
8685
long_version = version.GetVersionString()
8786
short_version = version.GetVersionInFormat('@MAJOR@.@MINOR@.@BUILD@')
88-
domain_prefix = 'org.mozc'
89-
product_name = 'Mozc'
87+
9088
if options.branding == 'GoogleJapaneseInput':
9189
domain_prefix = 'com.google'
9290
product_name = 'Google Japanese Input'
91+
breakpad_product = 'Google_Japanese_IME_Mac'
92+
breakpad_url = 'https://clients2.google.com/cr/report'
93+
else:
94+
domain_prefix = 'org.mozc'
95+
product_name = 'Mozc'
96+
breakpad_product = 'Mozc'
97+
# Reports are generated under $TMPDIR, but not sent to a server.
98+
breakpad_url = 'file:///dev/null'
99+
93100
variables = {
94101
'GOOGLE_VERSIONINFO_LONG': long_version,
95102
'GOOGLE_VERSIONINFO_SHORT': short_version,
@@ -98,7 +105,9 @@ def main():
98105
'%s %s, %s' % (product_name, long_version, copyright_message),
99106
'BRANDING': options.branding,
100107
'DOMAIN_PREFIX': domain_prefix,
101-
}
108+
'BREAKPAD_PRODUCT': breakpad_product,
109+
'BREAKPAD_URL': breakpad_url,
110+
}
102111

103112
open(options.output, 'w').write(
104113
tweak_data.ReplaceVariables(open(options.input).read(), variables))

src/data/mac/hidden_mozc_tool_info

+21-19
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,31 @@
2424
<string>${GOOGLE_VERSIONINFO_LONG}</string>
2525
<key>CFBundleShortVersionString</key>
2626
<string>${GOOGLE_VERSIONINFO_SHORT}</string>
27-
<key>CFBundleGetInfoString</key>
28-
<string>${GOOGLE_VERSIONINFO_FINDER}</string>
29-
<key>NSHumanReadableCopyright</key>
30-
<string>${GOOGLE_VERSIONINFO_ABOUT}</string>
31-
<key>CSResourcesFileMapped</key>
27+
<key>CFBundleGetInfoString</key>
28+
<string>${GOOGLE_VERSIONINFO_FINDER}</string>
29+
<key>NSHumanReadableCopyright</key>
30+
<string>${GOOGLE_VERSIONINFO_ABOUT}</string>
31+
<key>CSResourcesFileMapped</key>
3232
<true/>
3333
<key>NSPrincipalClass</key>
3434
<string>NSApplication</string>
3535
<key>LSUIElement</key>
3636
<string>1</string>
37-
<key>GoogleBreakpadProduct</key>
38-
<string>Google_Japanese_IME_Mac</string>
39-
<key>GoogleBreakpadProductDisplay</key>
40-
<string>${PRODUCT_NAME}</string>
41-
<key>GoogleBreakpadVersion</key>
42-
<string>${GOOGLE_VERSIONINFO_LONG}</string>
43-
<key>GoogleBreakpadURL</key>
44-
<string>https://clients2.google.com/cr/report</string>
45-
<key>GoogleBreakpadReportInterval</key>
46-
<string>86400</string>
47-
<key>GoogleBreakpadSkipConfirm</key>
48-
<string>YES</string>
49-
<key>GoogleBreakpadSendAndExit</key>
50-
<string>YES</string>
37+
<key>BreakpadProduct</key>
38+
<string>${BREAKPAD_PRODUCT}</string>
39+
<key>BreakpadProductDisplay</key>
40+
<string>${PRODUCT_NAME}</string>
41+
<key>BreakpadVersion</key>
42+
<string>${GOOGLE_VERSIONINFO_LONG}</string>
43+
<key>BreakpadURL</key>
44+
<string>${BREAKPAD_URL}</string>
45+
<key>BreakpadReportInterval</key>
46+
<string>86400</string>
47+
<key>BreakpadSkipConfirm</key>
48+
<string>YES</string>
49+
<key>BreakpadSendAndExit</key>
50+
<string>YES</string>
51+
<key>BreakpadInProcess</key>
52+
<string>YES</string>
5153
</dict>
5254
</plist>

src/data/mac/mozc_server_info

+11-9
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,21 @@
3636
<string>1</string>
3737
<key>NSPrincipalClass</key>
3838
<string>NSApplication</string>
39-
<key>GoogleBreakpadProduct</key>
40-
<string>Google_Japanese_IME_Mac</string>
41-
<key>GoogleBreakpadProductDisplay</key>
39+
<key>BreakpadProduct</key>
40+
<string>${BREAKPAD_PRODUCT}</string>
41+
<key>BreakpadProductDisplay</key>
4242
<string>${PRODUCT_NAME}</string>
43-
<key>GoogleBreakpadVersion</key>
43+
<key>BreakpadVersion</key>
4444
<string>${GOOGLE_VERSIONINFO_LONG}</string>
45-
<key>GoogleBreakpadURL</key>
46-
<string>https://clients2.google.com/cr/report</string>
47-
<key>GoogleBreakpadReportInterval</key>
45+
<key>BreakpadURL</key>
46+
<string>${BREAKPAD_URL}</string>
47+
<key>BreakpadReportInterval</key>
4848
<string>86400</string>
49-
<key>GoogleBreakpadSkipConfirm</key>
49+
<key>BreakpadSkipConfirm</key>
5050
<string>YES</string>
51-
<key>GoogleBreakpadSendAndExit</key>
51+
<key>BreakpadSendAndExit</key>
52+
<string>YES</string>
53+
<key>BreakpadInProcess</key>
5254
<string>YES</string>
5355
</dict>
5456
</plist>

0 commit comments

Comments
 (0)