From 58680cec807bec4cbca35cfad74439a7653040c4 Mon Sep 17 00:00:00 2001 From: "evan@chromium.org" Date: Sat, 18 Sep 2010 00:09:15 +0000 Subject: Support for building Chrome using Clang. To build, set the clang=1 gyp_define. This patch is the culmination of many months of effort and many patches. It contains the minimal changes to Chrome that are Clang-specific. With this, I can build the "chrome" target. Once this patch is in, we can incrementally fix bits of Chrome and various tests and remove the Clang-specific workarounds. Review URL: http://codereview.chromium.org/522020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59882 0039d316-1c4b-4281-b951-d872f2087c98 --- base/linked_list.h | 9 ++++++++- build/common.gypi | 23 ++++++++++++++++++++++ chrome/browser/zygote_main_linux.cc | 5 +++-- chrome/nacl/nacl_main_platform_delegate_linux.cc | 3 ++- .../renderer_main_platform_delegate_linux.cc | 3 ++- sandbox/sandbox.gyp | 4 ++-- skia/skia.gyp | 8 ++++++++ testing/gtest.gyp | 14 +++++++++++++ 8 files changed, 62 insertions(+), 7 deletions(-) diff --git a/base/linked_list.h b/base/linked_list.h index 0626025..d91a1f8 100644 --- a/base/linked_list.h +++ b/base/linked_list.h @@ -126,6 +126,13 @@ class LinkNode { return static_cast(this); } + // Work around a Clang bug reported upstream: + // http://llvm.org/bugs/show_bug.cgi?id=7974 + // TODO(evanm): remove this and its sole caller. + void set(LinkNode* prev, LinkNode* next) { + previous_ = prev; next_ = next; + } + private: LinkNode* previous_; LinkNode* next_; @@ -137,7 +144,7 @@ class LinkedList { // The "root" node is self-referential, and forms the basis of a circular // list (root_.next() will point back to the start of the list, // and root_->previous() wraps around to the end of the list). - LinkedList() : root_(&root_, &root_) {} + LinkedList() { root_.set(&root_, &root_); } // Appends |e| to the end of the linked list. void Append(LinkNode* e) { diff --git a/build/common.gypi b/build/common.gypi index 0f721ed..d81c567 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -251,6 +251,12 @@ # Set this to true to enable SELinux support. 'selinux%': 0, + # Set this to true when building with Clang. + # See http://code.google.com/p/chromium/wiki/Clang for details. + # TODO: eventually clang should behave identically to gcc, and this + # won't be necessary. + 'clang%': 0, + # Override whether we should use Breakpad on Linux. I.e. for Chrome bot. 'linux_breakpad%': 0, # And if we want to dump symbols for Breakpad-enabled builds. @@ -1114,6 +1120,23 @@ ], }]] }], + ['clang==1', { + 'cflags': [ + # Don't warn about unused variables, due to a common pattern: + # scoped_deleter unused_variable(&thing_to_delete); + '-Wno-unused-variable', + # Clang spots more unused functions. + '-Wno-unused-function', + # gtest confuses clang. + '-Wno-bool-conversions', + # Don't die on dtoa code that uses a char as an array index. + '-Wno-char-subscripts', + ], + 'cflags!': [ + # Clang doesn't seem to know know this flag. + '-mfpmath=sse', + ], + }], ['no_strict_aliasing==1', { 'cflags': [ '-fno-strict-aliasing', diff --git a/chrome/browser/zygote_main_linux.cc b/chrome/browser/zygote_main_linux.cc index 20b0352..b4dd7be 100644 --- a/chrome/browser/zygote_main_linux.cc +++ b/chrome/browser/zygote_main_linux.cc @@ -50,9 +50,10 @@ #include "unicode/timezone.h" -#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX) +#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX) && \ + !defined(__clang__) // The seccomp sandbox is enabled on all ia32 and x86-64 processor as long as -// we aren't using SELinux. +// we aren't using SELinux or clang. #define SECCOMP_SANDBOX #endif diff --git a/chrome/nacl/nacl_main_platform_delegate_linux.cc b/chrome/nacl/nacl_main_platform_delegate_linux.cc index 0932c08..9e3acef 100644 --- a/chrome/nacl/nacl_main_platform_delegate_linux.cc +++ b/chrome/nacl/nacl_main_platform_delegate_linux.cc @@ -34,7 +34,8 @@ void NaClMainPlatformDelegate::EnableSandbox() { // // The seccomp sandbox is started in the renderer. // http://code.google.com/p/seccompsandbox/ -#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX) +#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX) && \ + !defined(__clang__) // N.b. SupportsSeccompSandbox() returns a cached result, as we already // called it earlier in the zygote. Thus, it is OK for us to not pass in // a file descriptor for "/proc". diff --git a/chrome/renderer/renderer_main_platform_delegate_linux.cc b/chrome/renderer/renderer_main_platform_delegate_linux.cc index a965ede..ad43330 100644 --- a/chrome/renderer/renderer_main_platform_delegate_linux.cc +++ b/chrome/renderer/renderer_main_platform_delegate_linux.cc @@ -36,7 +36,8 @@ bool RendererMainPlatformDelegate::EnableSandbox() { // // The seccomp sandbox is started in the renderer. // http://code.google.com/p/seccompsandbox/ -#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX) +#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX) && \ + !defined(__clang__) // N.b. SupportsSeccompSandbox() returns a cached result, as we already // called it earlier in the zygote. Thus, it is OK for us to not pass in // a file descriptor for "/proc". diff --git a/sandbox/sandbox.gyp b/sandbox/sandbox.gyp index 1150261..692e526 100644 --- a/sandbox/sandbox.gyp +++ b/sandbox/sandbox.gyp @@ -135,7 +135,7 @@ }, ], }], - [ 'OS=="linux" and selinux==0', { + [ 'OS=="linux" and selinux==0 and clang==0', { 'targets': [ { 'target_name': 'chrome_sandbox', @@ -168,7 +168,7 @@ }, ], }], - [ 'OS=="linux" and selinux==1', { + [ 'OS=="linux" and (selinux==1 or clang==1)', { # GYP requires that each file have at least one target defined. 'targets': [ { diff --git a/skia/skia.gyp b/skia/skia.gyp index c627925..20e593d 100644 --- a/skia/skia.gyp +++ b/skia/skia.gyp @@ -592,6 +592,14 @@ '../third_party/skia/src/opts/opts_check_SSE2.cpp' ], }], + ['clang==1', { + 'defines': [ + # Remove all use of __restrict__ -- skia uses it incorrectly, + # and clang is more strict about it. + # http://code.google.com/p/skia/issues/detail?id=63 + 'SK_RESTRICT=', + ], + }], [ 'OS == "linux" or OS == "freebsd" or OS == "openbsd" or OS == "solaris"', { 'dependencies': [ '../build/linux/system.gyp:gdk', diff --git a/testing/gtest.gyp b/testing/gtest.gyp index e813b49..da95f42 100644 --- a/testing/gtest.gyp +++ b/testing/gtest.gyp @@ -79,6 +79,20 @@ ], }, }], + ['clang==1', { + # We want gtest features that use tr1::tuple, but clang currently + # doesn't support the variadic templates used by libstdc++'s + # implementation. gtest supports this scenario by providing its + # own implementation but we must opt in to it. + 'defines': [ + 'GTEST_USE_OWN_TR1_TUPLE=1', + ], + 'direct_dependent_settings': { + 'defines': [ + 'GTEST_USE_OWN_TR1_TUPLE=1', + ], + }, + }], ], 'direct_dependent_settings': { 'defines': [ -- cgit v1.1