Skip to content

Commit

Permalink
Build Breakpad from source for mac build
Browse files Browse the repository at this point in the history
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
  • Loading branch information
hiroyuki-komatsu committed Oct 20, 2016
1 parent f5dcadf commit c19cc87
Show file tree
Hide file tree
Showing 17 changed files with 298 additions and 171 deletions.
34 changes: 33 additions & 1 deletion src/base/base.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,16 @@
],
}],
['OS=="mac"', {
'hard_dependency': 1,
'sources': [
'crash_report_handler_mac.mm',
],
'sources!': [
'crash_report_handler.cc',
]
],
'dependencies': [
'breakpad',
],
}],
],
},
Expand Down Expand Up @@ -534,6 +538,34 @@
],
['OS=="mac"', {
'targets': [
{
'target_name': 'breakpad',
'type': 'none',
'variables': {
'pbdir': '<(third_party_dir)/breakpad',
},
'actions': [{
'action_name': 'build_breakpad',
'inputs': [
'<(pbdir)/src/client/mac/Breakpad.xcodeproj/project.pbxproj',
],
'outputs': [
'<(mac_breakpad_dir)/Breakpad.framework',
'<(mac_breakpad_dir)/Inspector',
'<(mac_breakpad_dir)/dump_syms',
'<(mac_breakpad_dir)/symupload',
],
'action': [
'python', '../build_tools/build_breakpad.py',
'--pbdir', '<(pbdir)', '--outdir', '<(mac_breakpad_dir)',
],
}],
'direct_dependent_settings': {
'mac_framework_dirs': [
'<(mac_breakpad_dir)',
],
},
},
{
'target_name': 'mac_util_main',
'type': 'executable',
Expand Down
44 changes: 24 additions & 20 deletions src/base/crash_report_handler_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -31,44 +31,48 @@

#import "base/crash_report_handler.h"

#import <Cocoa/Cocoa.h>
#if defined(GOOGLE_JAPANESE_INPUT_BUILD)
#import <GoogleBreakpad/GoogleBreakpad.h>
#endif // GOOGLE_JAPANESE_INPUT_BUILD
#import "base/const.h"

#import <Breakpad/Breakpad.h>
#import <CoreFoundation/CoreFoundation.h>

namespace mozc {

#if defined(GOOGLE_JAPANESE_INPUT_BUILD)
// The reference count for GoogleBreakpad
// The reference count for Breakpad
int g_reference_count = 0;

GoogleBreakpadRef g_breakpad = nullptr;
#endif // GOOGLE_JAPANESE_INPUT_BUILD
BreakpadRef g_breakpad = nullptr;

bool CrashReportHandler::Initialize(bool check_address) {
#if defined(GOOGLE_JAPANESE_INPUT_BUILD)
++g_reference_count;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDictionary *plist = [[NSBundle mainBundle] infoDictionary];
if (g_reference_count == 1 && plist != nullptr && g_breakpad == nullptr) {
g_breakpad = GoogleBreakpadCreate(plist);
[pool release];
return true;
@autoreleasepool {
NSMutableDictionary *plist =
[[[NSBundle mainBundle] infoDictionary] mutableCopy];
if (g_reference_count == 1 && plist != nullptr && g_breakpad == nullptr) {
// Create a crash reports directory under tmpdir, and set it to the plist
NSString *tmpDir = NSTemporaryDirectory();
// crashDir will be $TMPDIR/GoogleJapaneseInput/CrashReports
NSString *crashDir = [NSString
pathWithComponents:@[tmpDir, @kProductPrefix, @"CrashReports"]];
[[NSFileManager defaultManager] createDirectoryAtPath:crashDir
withIntermediateDirectories:YES
attributes:nil
error:NULL];
[plist setValue:crashDir forKey:@BREAKPAD_DUMP_DIRECTORY];
g_breakpad = BreakpadCreate(plist);
return true;
}
}
[pool release];
#endif // GOOGLE_JAPANESE_INPUT_BUILD
return false;
}

bool CrashReportHandler::Uninitialize() {
#if defined(GOOGLE_JAPANESE_INPUT_BUILD)
--g_reference_count;
if (g_reference_count == 0 && g_breakpad != nullptr) {
GoogleBreakpadRelease(g_breakpad);
BreakpadRelease(g_breakpad);
g_breakpad = nullptr;
return true;
}
#endif // GOOGLE_JAPANESE_INPUT_BUILD
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/build_tools/binary_size_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
# in Megabytes.
EXPECTED_MAXIMUM_SIZES = {
# Distribution package files:
'GoogleJapaneseInput.dmg': 65,
'GoogleJapaneseInput.dmg': 70,
'GoogleJapaneseInput32.msi': 65,
'GoogleJapaneseInput64.msi': 65,
}
Expand Down
105 changes: 105 additions & 0 deletions src/build_tools/build_breakpad.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
# Copyright 2010-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Script building Breakpad for Mozc/Mac.
././tools/build_breakpad.py
--pbdir ./third_party/breakpad --outdir /tmp/breakpad
"""

import optparse
import os
import subprocess
import sys


def ParseOption():
parser = optparse.OptionParser()
parser.add_option('--pbdir', default='./third_party/breakpad')
parser.add_option('--outdir', default='./out_mac/Release/Breakpad')

(opts, _) = parser.parse_args()
return opts


def ProcessCall(command):
try:
subprocess.check_output(command)
except subprocess.CalledProcessError as e:
print e.output
sys.exit(e.returncode)
print 'Done: %s' % ' '.join(command)


def Xcodebuild(projdir, target, arch, outdir):
ProcessCall([
'xcodebuild', '-project', projdir, '-configuration', 'Release',
'-target', target, '-arch', arch, '-sdk', 'macosx10.9',
'GCC_VERSION=com.apple.compilers.llvm.clang.1_0',
'CONFIGURATION_BUILD_DIR=%s' % outdir,
])


def BuildBreakpad(outdir):
projdir = os.path.join(outdir, 'src/client/mac/Breakpad.xcodeproj')
Xcodebuild(projdir, 'Breakpad', 'i386', outdir)


def BuildDumpSyms(outdir):
projdir = os.path.join(outdir, 'src/tools/mac/dump_syms/dump_syms.xcodeproj')
Xcodebuild(projdir, 'dump_syms', 'x86_64', outdir)


def BuildSymupload(outdir):
projdir = os.path.join(outdir, 'src/tools/mac/symupload/symupload.xcodeproj')
# This build fails with Xcode8/i386.
Xcodebuild(projdir, 'symupload', 'x86_64', outdir)


def CreateOutDir(pbdir, outdir):
workdir = os.path.join(outdir, 'src')
if not os.path.isdir(workdir):
os.makedirs(workdir)
ProcessCall(['rsync', '-avH', os.path.join(pbdir, 'src/'), workdir])


def main():
opts = ParseOption()
pbdir = os.path.abspath(opts.pbdir)
outdir = os.path.abspath(opts.outdir)

CreateOutDir(pbdir, outdir)
BuildBreakpad(outdir)
BuildDumpSyms(outdir)
BuildSymupload(outdir)


if __name__ == '__main__':
main()
6 changes: 0 additions & 6 deletions src/build_tools/change_reference_mac.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,6 @@ def main():
'@executable_path/../Frameworks/%s' % toollib_framework,
GetReferenceTo(toollib_framework))

# Change the reference to GoogleBreakpad from the target application
breakpad_framework = GetFrameworkPath('GoogleBreakpad', 'A')
InstallNameTool(target,
'@executable_path/../Frameworks/%s' % breakpad_framework,
GetReferenceTo(breakpad_framework))


if __name__ == '__main__':
main()
19 changes: 14 additions & 5 deletions src/build_tools/tweak_info_plist.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,22 @@ def main():

version = mozc_version.MozcVersion(options.version_file)

# \xC2\xA9 is the copyright mark in UTF-8
copyright_message = '\xC2\xA9 %d Google Inc.' % _COPYRIGHT_YEAR
copyright_message = (u'© %d Google Inc.' % _COPYRIGHT_YEAR).encode('utf-8')
long_version = version.GetVersionString()
short_version = version.GetVersionInFormat('@MAJOR@.@MINOR@.@BUILD@')
domain_prefix = 'org.mozc'
product_name = 'Mozc'

if options.branding == 'GoogleJapaneseInput':
domain_prefix = 'com.google'
product_name = 'Google Japanese Input'
breakpad_product = 'Google_Japanese_IME_Mac'
breakpad_url = 'https://clients2.google.com/cr/report'
else:
domain_prefix = 'org.mozc'
product_name = 'Mozc'
breakpad_product = 'Mozc'
# Reports are generated under $TMPDIR, but not sent to a server.
breakpad_url = 'file:///dev/null'

variables = {
'GOOGLE_VERSIONINFO_LONG': long_version,
'GOOGLE_VERSIONINFO_SHORT': short_version,
Expand All @@ -98,7 +105,9 @@ def main():
'%s %s, %s' % (product_name, long_version, copyright_message),
'BRANDING': options.branding,
'DOMAIN_PREFIX': domain_prefix,
}
'BREAKPAD_PRODUCT': breakpad_product,
'BREAKPAD_URL': breakpad_url,
}

open(options.output, 'w').write(
tweak_data.ReplaceVariables(open(options.input).read(), variables))
Expand Down
40 changes: 21 additions & 19 deletions src/data/mac/hidden_mozc_tool_info
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,31 @@
<string>${GOOGLE_VERSIONINFO_LONG}</string>
<key>CFBundleShortVersionString</key>
<string>${GOOGLE_VERSIONINFO_SHORT}</string>
<key>CFBundleGetInfoString</key>
<string>${GOOGLE_VERSIONINFO_FINDER}</string>
<key>NSHumanReadableCopyright</key>
<string>${GOOGLE_VERSIONINFO_ABOUT}</string>
<key>CSResourcesFileMapped</key>
<key>CFBundleGetInfoString</key>
<string>${GOOGLE_VERSIONINFO_FINDER}</string>
<key>NSHumanReadableCopyright</key>
<string>${GOOGLE_VERSIONINFO_ABOUT}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>LSUIElement</key>
<string>1</string>
<key>GoogleBreakpadProduct</key>
<string>Google_Japanese_IME_Mac</string>
<key>GoogleBreakpadProductDisplay</key>
<string>${PRODUCT_NAME}</string>
<key>GoogleBreakpadVersion</key>
<string>${GOOGLE_VERSIONINFO_LONG}</string>
<key>GoogleBreakpadURL</key>
<string>https://clients2.google.com/cr/report</string>
<key>GoogleBreakpadReportInterval</key>
<string>86400</string>
<key>GoogleBreakpadSkipConfirm</key>
<string>YES</string>
<key>GoogleBreakpadSendAndExit</key>
<string>YES</string>
<key>BreakpadProduct</key>
<string>${BREAKPAD_PRODUCT}</string>
<key>BreakpadProductDisplay</key>
<string>${PRODUCT_NAME}</string>
<key>BreakpadVersion</key>
<string>${GOOGLE_VERSIONINFO_LONG}</string>
<key>BreakpadURL</key>
<string>${BREAKPAD_URL}</string>
<key>BreakpadReportInterval</key>
<string>86400</string>
<key>BreakpadSkipConfirm</key>
<string>YES</string>
<key>BreakpadSendAndExit</key>
<string>YES</string>
<key>BreakpadInProcess</key>
<string>YES</string>
</dict>
</plist>
20 changes: 11 additions & 9 deletions src/data/mac/mozc_server_info
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,21 @@
<string>1</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>GoogleBreakpadProduct</key>
<string>Google_Japanese_IME_Mac</string>
<key>GoogleBreakpadProductDisplay</key>
<key>BreakpadProduct</key>
<string>${BREAKPAD_PRODUCT}</string>
<key>BreakpadProductDisplay</key>
<string>${PRODUCT_NAME}</string>
<key>GoogleBreakpadVersion</key>
<key>BreakpadVersion</key>
<string>${GOOGLE_VERSIONINFO_LONG}</string>
<key>GoogleBreakpadURL</key>
<string>https://clients2.google.com/cr/report</string>
<key>GoogleBreakpadReportInterval</key>
<key>BreakpadURL</key>
<string>${BREAKPAD_URL}</string>
<key>BreakpadReportInterval</key>
<string>86400</string>
<key>GoogleBreakpadSkipConfirm</key>
<key>BreakpadSkipConfirm</key>
<string>YES</string>
<key>GoogleBreakpadSendAndExit</key>
<key>BreakpadSendAndExit</key>
<string>YES</string>
<key>BreakpadInProcess</key>
<string>YES</string>
</dict>
</plist>
Loading

0 comments on commit c19cc87

Please sign in to comment.