diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-07-14 17:41:05 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2016-08-04 12:37:36 +0000 |
commit | 399c965b6064c440ddcf4015f5f8e9d131c7a0a6 (patch) | |
tree | 6b06b60ff365abef0e13b3503d593a0df48d20e8 /chromium/tools | |
parent | 7366110654eec46f21b6824f302356426f48cd74 (diff) | |
download | qtwebengine-chromium-399c965b6064c440ddcf4015f5f8e9d131c7a0a6.tar.gz |
BASELINE: Update Chromium to 52.0.2743.76 and Ninja to 1.7.1
Change-Id: I382f51b959689505a60f8b707255ecb344f7d8b4
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/tools')
211 files changed, 7539 insertions, 9186 deletions
diff --git a/chromium/tools/battor_agent/BUILD.gn b/chromium/tools/battor_agent/BUILD.gn index 41f89e7dafa..bba270ec0c0 100644 --- a/chromium/tools/battor_agent/BUILD.gn +++ b/chromium/tools/battor_agent/BUILD.gn @@ -14,6 +14,7 @@ executable("battor_agent") { deps = [ ":battor_agent_lib", "//base", + "//build/win:default_exe_manifest", "//device/serial", "//mojo/public/c/system:for_shared_library", ] @@ -33,6 +34,8 @@ source_set("battor_agent_lib") { "battor_finder.h", "battor_sample_converter.cc", "battor_sample_converter.h", + "serial_utils.cc", + "serial_utils.h", ] deps = [ "//base", @@ -47,6 +50,7 @@ test("battor_agent_unittests") { "battor_connection_impl_unittest.cc", "battor_protocol_types_unittest.cc", "battor_sample_converter_unittest.cc", + "serial_utils_unittest.cc", ] deps = [ ":battor_agent_lib", diff --git a/chromium/tools/battor_agent/battor_agent.cc b/chromium/tools/battor_agent/battor_agent.cc index 323da5175e4..708192d1791 100644 --- a/chromium/tools/battor_agent/battor_agent.cc +++ b/chromium/tools/battor_agent/battor_agent.cc @@ -7,7 +7,7 @@ #include <iomanip> #include "base/bind.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "tools/battor_agent/battor_connection_impl.h" #include "tools/battor_agent/battor_sample_converter.h" diff --git a/chromium/tools/battor_agent/battor_agent.gyp b/chromium/tools/battor_agent/battor_agent.gyp index 974fbdefcf2..e726b9a5d4e 100644 --- a/chromium/tools/battor_agent/battor_agent.gyp +++ b/chromium/tools/battor_agent/battor_agent.gyp @@ -39,6 +39,8 @@ 'battor_finder.h', 'battor_sample_converter.cc', 'battor_sample_converter.h', + 'serial_utils.cc', + 'serial_utils.h', ], 'dependencies': [ '../../base/base.gyp:base', @@ -65,6 +67,7 @@ 'battor_connection_impl_unittest.cc', 'battor_protocol_types_unittest.cc', 'battor_sample_converter_unittest.cc', + 'serial_utils_unittest.cc', ], }, ], diff --git a/chromium/tools/battor_agent/battor_agent_bin.cc b/chromium/tools/battor_agent/battor_agent_bin.cc index 7424d1ddb46..a4d783efa52 100644 --- a/chromium/tools/battor_agent/battor_agent_bin.cc +++ b/chromium/tools/battor_agent/battor_agent_bin.cc @@ -42,9 +42,11 @@ #include "base/command_line.h" #include "base/location.h" #include "base/logging.h" +#include "base/run_loop.h" #include "base/strings/string_tokenizer.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread.h" +#include "base/threading/thread_task_runner_handle.h" #include "tools/battor_agent/battor_agent.h" #include "tools/battor_agent/battor_error.h" #include "tools/battor_agent/battor_finder.h" @@ -57,7 +59,6 @@ namespace { const char kIoThreadName[] = "BattOr IO Thread"; const char kFileThreadName[] = "BattOr File Thread"; -const char kUiThreadName[] = "BattOr UI Thread"; const char kUsage[] = "Start the battor_agent shell with:\n" @@ -107,11 +108,7 @@ std::vector<std::string> TokenizeString(std::string cmd) { // use a BattOrAgent to communicate with a BattOr. class BattOrAgentBin : public BattOrAgent::Listener { public: - BattOrAgentBin() - : done_(false, false), - io_thread_(kIoThreadName), - file_thread_(kFileThreadName), - ui_thread_(kUiThreadName) {} + BattOrAgentBin() : io_thread_(kIoThreadName), file_thread_(kFileThreadName) {} ~BattOrAgentBin() { DCHECK(!agent_); } @@ -127,43 +124,10 @@ class BattOrAgentBin : public BattOrAgent::Listener { SetUp(path); - std::string cmd; - for (;;) { - std::getline(std::cin, cmd); - - if (cmd == "StartTracing") { - StartTracing(); - } else if (cmd.find("StopTracing") != std::string::npos) { - std::vector<std::string> tokens = TokenizeString(cmd); - if (tokens.size() == 1 && tokens[0] == "StopTracing") { - // No path given. - StopTracing(); - } else if (tokens.size() == 2 && tokens[0] == "StopTracing") { - // Path given. - StopTracing(tokens[1]); - } else { - std::cout << "Invalid StopTracing command." << endl; - std::cout << kUsage << endl; - continue; - } - break; - } else if (cmd == "SupportsExplicitClockSync") { - PrintSupportsExplicitClockSync(); - } else if (cmd.find("RecordClockSyncMarker") != std::string::npos) { - std::vector<std::string> tokens = TokenizeString(cmd); - if (tokens.size() != 2 || tokens[0] != "RecordClockSyncMarker") { - std::cout << "Invalid RecordClockSyncMarker command." << endl; - std::cout << kUsage << endl; - continue; - } - - RecordClockSyncMarker(tokens[1]); - } else if (cmd == "Exit") { - break; - } else { - std::cout << kUsage << endl; - } - } + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(&BattOrAgentBin::RunNextCommand, base::Unretained(this))); + ui_thread_run_loop_.Run(); TearDown(); return 0; @@ -171,8 +135,6 @@ class BattOrAgentBin : public BattOrAgent::Listener { // Performs any setup necessary for the BattOr binary to run. void SetUp(const std::string& path) { - // TODO(charliea): Investigate whether it's possible to replace this - // separate thread with a combination of MessageLoopForIO and RunLoop. base::Thread::Options io_thread_options; io_thread_options.message_loop_type = base::MessageLoopForIO::TYPE_IO; if (!io_thread_.StartWithOptions(io_thread_options)) { @@ -181,23 +143,73 @@ class BattOrAgentBin : public BattOrAgent::Listener { io_thread_.task_runner()->PostTask( FROM_HERE, - base::Bind(&BattOrAgentBin::CreateAgent, base::Unretained(this), path)); - done_.Wait(); + base::Bind(&BattOrAgentBin::CreateAgent, base::Unretained(this), path, + base::ThreadTaskRunnerHandle::Get())); } // Performs any cleanup necessary after the BattOr binary is done running. void TearDown() { + base::WaitableEvent done(false, false); io_thread_.task_runner()->PostTask( + FROM_HERE, base::Bind(&BattOrAgentBin::DeleteAgent, + base::Unretained(this), &done)); + done.Wait(); + } + + void RunNextCommand() { + std::string cmd; + std::getline(std::cin, cmd); + + if (cmd == "StartTracing") { + StartTracing(); + } else if (cmd.find("StopTracing") != std::string::npos) { + std::vector<std::string> tokens = TokenizeString(cmd); + + if (tokens[0] != "StopTracing" || tokens.size() > 2) { + std::cout << "Invalid StopTracing command." << endl; + std::cout << kUsage << endl; + PostRunNextCommand(); + return; + } + + // tokens[1] contains the optional output file argument, which allows + // users to dump the trace to a file instead instead of to STDOUT. + std::string trace_output_file = + tokens.size() == 2 ? tokens[1] : std::string(); + + StopTracing(trace_output_file); + } else if (cmd == "SupportsExplicitClockSync") { + PrintSupportsExplicitClockSync(); + PostRunNextCommand(); + } else if (cmd.find("RecordClockSyncMarker") != std::string::npos) { + std::vector<std::string> tokens = TokenizeString(cmd); + if (tokens.size() != 2 || tokens[0] != "RecordClockSyncMarker") { + std::cout << "Invalid RecordClockSyncMarker command." << endl; + std::cout << kUsage << endl; + PostRunNextCommand(); + return; + } + + RecordClockSyncMarker(tokens[1]); + } else if (cmd == "Exit" || std::cin.eof()) { + ui_thread_message_loop_.task_runner()->PostTask( + FROM_HERE, ui_thread_run_loop_.QuitClosure()); + } else { + std::cout << kUsage << endl; + PostRunNextCommand(); + } + } + + void PostRunNextCommand() { + ui_thread_message_loop_.task_runner()->PostTask( FROM_HERE, - base::Bind(&BattOrAgentBin::DeleteAgent, base::Unretained(this))); - done_.Wait(); + base::Bind(&BattOrAgentBin::RunNextCommand, base::Unretained(this))); } void StartTracing() { io_thread_.task_runner()->PostTask( FROM_HERE, base::Bind(&BattOrAgent::StartTracing, base::Unretained(agent_.get()))); - done_.Wait(); } void OnStartTracingComplete(BattOrError error) override { @@ -206,16 +218,14 @@ class BattOrAgentBin : public BattOrAgent::Listener { else HandleError(error); - done_.Signal(); + PostRunNextCommand(); } - void StopTracing(const std::string& path = "") { - trace_output_file_ = path; + void StopTracing(const std::string& trace_output_file) { + trace_output_file_ = trace_output_file; io_thread_.task_runner()->PostTask( FROM_HERE, base::Bind(&BattOrAgent::StopTracing, base::Unretained(agent_.get()))); - done_.Wait(); - trace_output_file_ = std::string(); } void OnStopTracingComplete(const std::string& trace, @@ -223,8 +233,7 @@ class BattOrAgentBin : public BattOrAgent::Listener { if (error == BATTOR_ERROR_NONE) { if (trace_output_file_.empty()) { std::cout << trace; - } - else { + } else { std::ofstream trace_stream(trace_output_file_); if (!trace_stream.is_open()) { std::cout << "Tracing output file could not be opened." << endl; @@ -238,14 +247,14 @@ class BattOrAgentBin : public BattOrAgent::Listener { HandleError(error); } - done_.Signal(); + ui_thread_message_loop_.task_runner()->PostTask( + FROM_HERE, ui_thread_run_loop_.QuitClosure()); } void RecordClockSyncMarker(const std::string& marker) { io_thread_.task_runner()->PostTask( FROM_HERE, base::Bind(&BattOrAgent::RecordClockSyncMarker, base::Unretained(agent_.get()), marker)); - done_.Wait(); } void OnRecordClockSyncMarkerComplete(BattOrError error) override { @@ -254,51 +263,46 @@ class BattOrAgentBin : public BattOrAgent::Listener { else HandleError(error); - done_.Signal(); + PostRunNextCommand(); } // Postable task for creating the BattOrAgent. Because the BattOrAgent has // uber thread safe dependencies, all interactions with it, including creating // and deleting it, MUST happen on the IO thread. - void CreateAgent(const std::string& path) { - // In Chrome, we already have file and UI threads running. Because the - // Chrome serial libraries rely on having those threads available, we have - // to spin up our own because we're in a separate binary. + void CreateAgent( + const std::string& path, + scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) { + // In Chrome, we already have a file thread running. Because the Chrome + // serial library relies on having it available, we have to spin up our own. if (!file_thread_.Start()) ExitFromThreadStartFailure(kFileThreadName); - base::Thread::Options ui_thread_options; - ui_thread_options.message_loop_type = base::MessageLoopForIO::TYPE_UI; - if (!ui_thread_.StartWithOptions(ui_thread_options)) { - ExitFromThreadStartFailure(kUiThreadName); - } - agent_.reset(new BattOrAgent(path, this, file_thread_.task_runner(), - ui_thread_.task_runner())); - done_.Signal(); + ui_thread_task_runner)); } // Postable task for deleting the BattOrAgent. See the comment for // CreateAgent() above regarding why this is necessary. - void DeleteAgent() { - agent_.reset(nullptr); - done_.Signal(); + void DeleteAgent(base::WaitableEvent* done) { + agent_.reset(); + done->Signal(); } private: - // Event signaled when an async task has finished executing. - base::WaitableEvent done_; + // NOTE: ui_thread_message_loop_ must appear before ui_thread_run_loop_ here + // because ui_thread_run_loop_ checks for the current MessageLoop during + // initialization. + base::MessageLoopForUI ui_thread_message_loop_; + base::RunLoop ui_thread_run_loop_; // Threads needed for serial communication. base::Thread io_thread_; base::Thread file_thread_; - base::Thread ui_thread_; // The agent capable of asynchronously communicating with the BattOr. std::unique_ptr<BattOrAgent> agent_; std::string trace_output_file_; - }; } // namespace battor diff --git a/chromium/tools/battor_agent/battor_agent_unittest.cc b/chromium/tools/battor_agent/battor_agent_unittest.cc index 3b6c54338a1..008877514f0 100644 --- a/chromium/tools/battor_agent/battor_agent_unittest.cc +++ b/chromium/tools/battor_agent/battor_agent_unittest.cc @@ -5,7 +5,7 @@ #include "tools/battor_agent/battor_agent.h" #include "base/test/test_simple_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "tools/battor_agent/battor_protocol_types.h" diff --git a/chromium/tools/battor_agent/battor_connection_impl.cc b/chromium/tools/battor_agent/battor_connection_impl.cc index cce643a6e18..357ad6c3a99 100644 --- a/chromium/tools/battor_agent/battor_connection_impl.cc +++ b/chromium/tools/battor_agent/battor_connection_impl.cc @@ -6,18 +6,26 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/command_line.h" #include "base/memory/ptr_util.h" -#include "base/thread_task_runner_handle.h" +#include "base/strings/stringprintf.h" +#include "base/threading/thread_task_runner_handle.h" #include "device/serial/buffer.h" #include "device/serial/serial_io_handler.h" #include "net/base/io_buffer.h" +#include "tools/battor_agent/serial_utils.h" +using base::StringPrintf; using std::vector; namespace battor { namespace { +// The command line switch used to specify a file to which serial communication +// is logged. +const char kSerialLogPathSwitch[] = "battor-serial-log"; + // Serial configuration parameters for the BattOr. const uint32_t kBattOrBitrate = 2000000; const device::serial::DataBits kBattOrDataBits = @@ -58,7 +66,15 @@ BattOrConnectionImpl::BattOrConnectionImpl( : BattOrConnection(listener), path_(path), file_thread_task_runner_(file_thread_task_runner), - ui_thread_task_runner_(ui_thread_task_runner) {} + ui_thread_task_runner_(ui_thread_task_runner) { + std::string serial_log_path = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + kSerialLogPathSwitch); + if (!serial_log_path.empty()) { + serial_log_.open(serial_log_path.c_str(), + std::fstream::out | std::fstream::trunc); + } +} BattOrConnectionImpl::~BattOrConnectionImpl() {} @@ -78,11 +94,15 @@ void BattOrConnectionImpl::Open() { options.cts_flow_control = kBattOrCtsFlowControl; options.has_cts_flow_control = kBattOrHasCtsFlowControl; + LogSerial("Opening serial connection."); io_handler_->Open(path_, options, base::Bind(&BattOrConnectionImpl::OnOpened, AsWeakPtr())); } void BattOrConnectionImpl::OnOpened(bool success) { + LogSerial(StringPrintf("Serial connection open finished with success: %d.", + success)); + if (!success) Close(); @@ -92,6 +112,7 @@ void BattOrConnectionImpl::OnOpened(bool success) { } void BattOrConnectionImpl::Close() { + LogSerial("Serial connection closed."); io_handler_ = nullptr; } @@ -119,6 +140,8 @@ void BattOrConnectionImpl::SendBytes(BattOrMessageType type, data.push_back(BATTOR_CONTROL_BYTE_END); + LogSerial(StringPrintf("Bytes sent: %s.", CharVectorToString(data).c_str())); + pending_write_length_ = data.size(); io_handler_->Write(base::WrapUnique(new device::SendBuffer( data, base::Bind(&BattOrConnectionImpl::OnBytesSent, AsWeakPtr())))); @@ -134,7 +157,9 @@ void BattOrConnectionImpl::ReadMessage(BattOrMessageType type) { std::unique_ptr<vector<char>> bytes(new vector<char>()); bytes->reserve(max_bytes_to_read); + LogSerial("Checking if a complete message is in the 'already read' buffer."); if (ParseMessage(&parsed_type, bytes.get())) { + LogSerial("Complete message found."); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&Listener::OnMessageRead, base::Unretained(listener_), true, @@ -142,6 +167,7 @@ void BattOrConnectionImpl::ReadMessage(BattOrMessageType type) { return; } + LogSerial("No complete message found."); BeginReadBytes(max_bytes_to_read - already_read_buffer_.size()); } @@ -156,6 +182,9 @@ scoped_refptr<device::SerialIoHandler> BattOrConnectionImpl::CreateIoHandler() { } void BattOrConnectionImpl::BeginReadBytes(size_t max_bytes_to_read) { + LogSerial( + StringPrintf("Starting read of up to %zu bytes.", max_bytes_to_read)); + pending_read_buffer_ = make_scoped_refptr(new net::IOBuffer(max_bytes_to_read)); @@ -169,13 +198,25 @@ void BattOrConnectionImpl::BeginReadBytes(size_t max_bytes_to_read) { void BattOrConnectionImpl::OnBytesRead(int bytes_read, device::serial::ReceiveError error) { - if (bytes_read == 0 || error != device::serial::ReceiveError::NONE) { + if (error != device::serial::ReceiveError::NONE) { + LogSerial(StringPrintf("Read failed with error code: %d.", + static_cast<int>(error))); + EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); + return; + } + + if (bytes_read == 0) { // If we didn't have a message before, and we weren't able to read any // additional bytes, then there's no valid message available. + LogSerial("Read failed due to no bytes being read."); EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); return; } + LogSerial(StringPrintf( + "%d more bytes read: %s.", bytes_read, + CharArrayToString(pending_read_buffer_->data(), bytes_read).c_str())); + already_read_buffer_.insert(already_read_buffer_.end(), pending_read_buffer_->data(), pending_read_buffer_->data() + bytes_read); @@ -185,14 +226,14 @@ void BattOrConnectionImpl::OnBytesRead(int bytes_read, bytes->reserve(GetMaxBytesForMessageType(pending_read_message_type_)); if (!ParseMessage(&type, bytes.get())) { - // Even after reading the max number of bytes, we still don't have a valid - // message. + LogSerial( + "Read failed due to having no complete message after max read length."); EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); return; } if (type != pending_read_message_type_) { - // We received a complete message, but it wasn't the type we were expecting. + LogSerial("Read failed due to receiving a message of the wrong type."); EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); return; } @@ -200,10 +241,11 @@ void BattOrConnectionImpl::OnBytesRead(int bytes_read, EndReadBytes(true, type, std::move(bytes)); } -void BattOrConnectionImpl::EndReadBytes( - bool success, - BattOrMessageType type, - std::unique_ptr<std::vector<char>> bytes) { +void BattOrConnectionImpl::EndReadBytes(bool success, + BattOrMessageType type, + std::unique_ptr<vector<char>> bytes) { + LogSerial(StringPrintf("Read finished with success: %d.", success)); + pending_read_buffer_ = nullptr; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, @@ -273,4 +315,8 @@ void BattOrConnectionImpl::OnBytesSent(int bytes_sent, base::Bind(&Listener::OnBytesSent, base::Unretained(listener_), success)); } +void BattOrConnectionImpl::LogSerial(const std::string& str) { + serial_log_ << str << std::endl << std::endl; +} + } // namespace battor diff --git a/chromium/tools/battor_agent/battor_connection_impl.h b/chromium/tools/battor_agent/battor_connection_impl.h index e0ce5a20ffa..0631451beda 100644 --- a/chromium/tools/battor_agent/battor_connection_impl.h +++ b/chromium/tools/battor_agent/battor_connection_impl.h @@ -5,6 +5,7 @@ #ifndef TOOLS_BATTOR_AGENT_BATTOR_CONNECTION_IMPL_H_ #define TOOLS_BATTOR_AGENT_BATTOR_CONNECTION_IMPL_H_ +#include <fstream> #include <vector> #include "base/callback_forward.h" @@ -75,6 +76,9 @@ class BattOrConnectionImpl // Internal callback for when bytes are sent. void OnBytesSent(int bytes_sent, device::serial::SendError error); + // Appends |str| to the serial log file if it exists. + void LogSerial(const std::string& str); + // The path of the BattOr. std::string path_; @@ -93,6 +97,8 @@ class BattOrConnectionImpl scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_; + std::fstream serial_log_; + DISALLOW_COPY_AND_ASSIGN(BattOrConnectionImpl); }; diff --git a/chromium/tools/battor_agent/battor_connection_impl_unittest.cc b/chromium/tools/battor_agent/battor_connection_impl_unittest.cc index 233e7e66db4..4e19ee123c5 100644 --- a/chromium/tools/battor_agent/battor_connection_impl_unittest.cc +++ b/chromium/tools/battor_agent/battor_connection_impl_unittest.cc @@ -9,7 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/test/test_simple_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "device/serial/serial.mojom.h" #include "device/serial/test_serial_io_handler.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/tools/battor_agent/battor_protocol_types_unittest.cc b/chromium/tools/battor_agent/battor_protocol_types_unittest.cc index 46416cdd44b..cdd9ec109a2 100644 --- a/chromium/tools/battor_agent/battor_protocol_types_unittest.cc +++ b/chromium/tools/battor_agent/battor_protocol_types_unittest.cc @@ -8,6 +8,7 @@ #include <string> #include "testing/gtest/include/gtest/gtest.h" +#include "tools/battor_agent/serial_utils.h" using namespace testing; @@ -15,22 +16,6 @@ namespace battor { namespace { -// Prints the character array as hex to a comma-separated list. -std::string CharArrayToFormattedString(const unsigned char* arr, - size_t length) { - std::string s; - - char num_buff[6]; - for (size_t i = 0; i < length; ++i) { - // We use sprintf because stringstream's hex support wants to print our - // characters as signed. - sprintf(num_buff, "0x%02hhx,", arr[i]); - s += num_buff; - } - - return s; -} - const BattOrEEPROM kUnserializedEEPROM{ {0, 0, 0, 1}, 2, "serialno", 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, @@ -55,12 +40,12 @@ TEST(BattOrProtocolTypeTest, EEPROMSerializesCorrectly) { // the EEPROM will change in the future and we'll need to update the // serialized version when it does, it makes sense to print the bytes as a // string that can just be copied and pasted into kSerializedEEPROM. - const unsigned char* eeprom_bytes = - reinterpret_cast<const unsigned char*>(&kUnserializedEEPROM); + const char* eeprom_bytes = + reinterpret_cast<const char*>(&kUnserializedEEPROM); - ASSERT_EQ( - CharArrayToFormattedString(kSerializedEEPROM, sizeof(kSerializedEEPROM)), - CharArrayToFormattedString(eeprom_bytes, sizeof(kUnserializedEEPROM))); + ASSERT_EQ(CharArrayToString(reinterpret_cast<const char*>(kSerializedEEPROM), + sizeof(kSerializedEEPROM)), + CharArrayToString(eeprom_bytes, sizeof(kUnserializedEEPROM))); } } // namespace battor diff --git a/chromium/tools/battor_agent/serial_utils.cc b/chromium/tools/battor_agent/serial_utils.cc new file mode 100644 index 00000000000..a40a333dac1 --- /dev/null +++ b/chromium/tools/battor_agent/serial_utils.cc @@ -0,0 +1,29 @@ +// Copyright 2016 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. + +#include "tools/battor_agent/serial_utils.h" + +namespace battor { + +std::string CharVectorToString(const std::vector<char> data) { + std::string s; + + // Reserve enough bytes for '0x', the two data characters, a space, and a null + // terminating byte. + char num_buff[6]; + for (char d : data) { + // We use sprintf because stringstream's hex support wants to print our + // characters as signed. + sprintf(num_buff, "0x%02hhx ", d); + s += num_buff; + } + + return s.substr(0, s.size() - 1); +} + +std::string CharArrayToString(const char* bytes, size_t len) { + return CharVectorToString(std::vector<char>(bytes, bytes + len)); +} + +} // namespace battor diff --git a/chromium/tools/battor_agent/serial_utils.h b/chromium/tools/battor_agent/serial_utils.h new file mode 100644 index 00000000000..ae1e6cc7944 --- /dev/null +++ b/chromium/tools/battor_agent/serial_utils.h @@ -0,0 +1,20 @@ +// Copyright 2016 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. + +#ifndef TOOLS_BATTOR_AGENT_SERIAL_UTILS_H_ +#define TOOLS_BATTOR_AGENT_SERIAL_UTILS_H_ + +#include <string> +#include <vector> + +namespace battor { + +// Prints |bytes| as a space separated list of hex numbers (e.g. {'A', 'J'} +// would return "0x41 0x4A"). +std::string CharArrayToString(const char* bytes, size_t len); +std::string CharVectorToString(const std::vector<char> bytes); + +} // namespace battor + +#endif // TOOLS_BATTOR_AGENT_SERIAL_UTILS_H_ diff --git a/chromium/tools/battor_agent/serial_utils_unittest.cc b/chromium/tools/battor_agent/serial_utils_unittest.cc new file mode 100644 index 00000000000..608b52fff2d --- /dev/null +++ b/chromium/tools/battor_agent/serial_utils_unittest.cc @@ -0,0 +1,36 @@ +// Copyright 2016 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. + +#include "tools/battor_agent/serial_utils.h" + +#include "testing/gtest/include/gtest/gtest.h" + +using namespace testing; + +namespace battor { + +TEST(SerialUtilsTest, CharVectorToStringLengthZero) { + EXPECT_EQ("", CharVectorToString(std::vector<char>())); +} + +TEST(SerialUtilsTest, CharVectorToStringLengthOne) { + EXPECT_EQ("0x41", CharVectorToString(std::vector<char>({'A'}))); +} + +TEST(SerialUtilsTest, CharVectorToStringLengthTwo) { + EXPECT_EQ("0x41 0x4a", + CharVectorToString(std::vector<char>({'A', 'J'}))); +} + +TEST(SerialUtilsTest, CharArrayToStringLengthOne) { + const char arr[] = {'A'}; + EXPECT_EQ("0x41", CharArrayToString(arr, sizeof(arr))); +} + +TEST(SerialUtilsTest, CharArrayToStringLengthTwo) { + const char arr[] = {'A', 'J'}; + EXPECT_EQ("0x41 0x4a", CharArrayToString(arr, sizeof(arr))); +} + +} // namespace battor diff --git a/chromium/tools/cfi/blacklist.txt b/chromium/tools/cfi/blacklist.txt index ab60ab63256..cb0b24f1305 100644 --- a/chromium/tools/cfi/blacklist.txt +++ b/chromium/tools/cfi/blacklist.txt @@ -18,22 +18,6 @@ type:*SkBlockComRef* # https://crbug.com/517959 type:*NoAddRefRelease* -# All mojo::test:: types. -# They are loaded from libmojo_public_test_support.so -# https://crbug.com/515347 -type:mojo::test::* - -# All types and sources from libclearkeycdm.so. -# See https://crbug.com/557969 -type:media::CdmVideoDecoder -type:media::ClearKeyCdm -type:media::FakeCdmVideoDecoder -type:media::FFmpegCdmAudioDecoder -type:media::FFmpegCdmVideoDecoder -type:media::LibvpxCdmVideoDecoder -src:*external_clear_key* -type:cdm::* - # invalid downcasts for IPC messages # https://crbug.com/520760 src:*nacl_message_scanner.cc* diff --git a/chromium/tools/checkbins/checkbins.py b/chromium/tools/checkbins/checkbins.py index 74ed0ae821a..ec955781b0b 100755 --- a/chromium/tools/checkbins/checkbins.py +++ b/chromium/tools/checkbins/checkbins.py @@ -31,6 +31,7 @@ MACHINE_TYPE_AMD64 = 0x8664 # Windows guru for advice. EXCLUDED_FILES = ['chrome_frame_mini_installer.exe', 'mini_installer.exe', + 'next_version_mini_installer.exe', 'wow_helper.exe' ] diff --git a/chromium/tools/checklicenses/checklicenses.py b/chromium/tools/checklicenses/checklicenses.py index cfd418b2e7f..94611a901da 100755 --- a/chromium/tools/checklicenses/checklicenses.py +++ b/chromium/tools/checklicenses/checklicenses.py @@ -37,6 +37,7 @@ WHITELISTED_LICENSES = [ 'Apache (v2.0) BSD (2 clause)', 'Apache (v2.0) BSD-like', 'Apache (v2.0) GPL (v2)', + 'Apache (v2.0) ISC', 'Apache (v2.0)', 'Apple MIT', # https://fedoraproject.org/wiki/Licensing/Apple_MIT_License 'BSD (2 clause) ISC', @@ -76,6 +77,7 @@ WHITELISTED_LICENSES = [ 'LGPL (v3 or later)', 'MIT/X11 (BSD like) LGPL (v2.1 or later)', 'MIT/X11 (BSD like)', + 'MIT/X11 (BSD like) Public domain MIT/X11 (BSD like)', 'MPL (v1.0) LGPL (v2 or later)', 'MPL (v1.1) BSD (3 clause) GPL (v2) LGPL (v2.1 or later)', 'MPL (v1.1) BSD (3 clause) LGPL (v2.1 or later)', @@ -143,10 +145,10 @@ PATH_SPECIFIC_WHITELISTED_LICENSES = { 'chrome/common/extensions/docs/server2/third_party': [ 'UNKNOWN', ], - 'courgette/third_party/bsdiff_create.cc': [ # http://crbug.com/98095 + 'courgette/third_party/bsdiff/bsdiff_create.cc': [ # http://crbug.com/98095 'UNKNOWN', ], - 'courgette/third_party/qsufsort.h': [ # http://crbug.com/98095 + 'courgette/third_party/bsdiff/qsufsort.h': [ # http://crbug.com/98095 'UNKNOWN', ], 'native_client': [ # http://crbug.com/98099 @@ -184,18 +186,46 @@ PATH_SPECIFIC_WHITELISTED_LICENSES = { 'UNKNOWN', ], + # http://crbug.com/603946 + # https://github.com/google/oauth2client/issues/331 + # Just imports googleapiclient. Chromite is not shipped. + 'third_party/chromite/third_party/apiclient': [ + 'UNKNOWN', + ], + + # http://crbug.com/603946 + # https://github.com/google/google-api-python-client/issues/216 + # Apache (v2.0) license. Chromite is not shipped. + 'third_party/chromite/third_party/googleapiclient/channel.py': [ + 'UNKNOWN', + ], + # http://crbug.com/222828 # http://bugs.python.org/issue17514 'third_party/chromite/third_party/argparse.py': [ 'UNKNOWN', ], + # http://crbug.com/603939 + # https://github.com/jcgregorio/httplib2/issues/307 + # MIT license. Chromite is not shipped. + 'third_party/chromite/third_party/httplib2': [ + 'UNKNOWN', + ], + # http://crbug.com/326117 # https://bitbucket.org/chrisatlee/poster/issue/21 'third_party/chromite/third_party/poster': [ 'UNKNOWN', ], + # http://crbug.com/603944 + # https://github.com/kennethreitz/requests/issues/1610 + # Apache (v2.0) license. Chromite is not shipped + 'third_party/chromite/third_party/requests': [ + 'UNKNOWN', + ], + # http://crbug.com/333508 'buildtools/clang_format/script': [ 'UNKNOWN', @@ -346,6 +376,10 @@ PATH_SPECIFIC_WHITELISTED_LICENSES = { 'GPL (v3 or later)', 'UNKNOWN', # http://crbug.com/98123 ], + 'third_party/flatbuffers': [ + # https://github.com/google/flatbuffers/issues/3872 + 'UNKNOWN', + ], 'third_party/fontconfig': [ # https://bugs.freedesktop.org/show_bug.cgi?id=73401 'UNKNOWN', @@ -385,9 +419,6 @@ PATH_SPECIFIC_WHITELISTED_LICENSES = { 'third_party/lcov/contrib/galaxy/genflat.pl': [ 'GPL (v2 or later)', ], - 'third_party/libjingle/source/talk': [ # http://crbug.com/98310 - 'UNKNOWN', - ], 'third_party/libjpeg_turbo': [ # http://crbug.com/98314 'UNKNOWN', ], @@ -492,12 +523,14 @@ PATH_SPECIFIC_WHITELISTED_LICENSES = { 'UNKNOWN', ], + # https://github.com/google/google-api-python-client/issues/216 # Apache v2.0. 'tools/swarming_client/third_party/googleapiclient': [ 'UNKNOWN', ], # http://crbug.com/334668 + # https://github.com/jcgregorio/httplib2/issues/307 # MIT license. 'tools/swarming_client/third_party/httplib2': [ 'UNKNOWN', @@ -616,6 +649,25 @@ PATH_SPECIFIC_WHITELISTED_LICENSES = { # https://sourceforge.net/p/pyserial/feature-requests/35/ 'UNKNOWN', ], + # Not shipped, GPL license but some header files contain no licensing info. + 'third_party/logilab/logilab/astroid': [ + 'GPL (v2 or later)', + # https://github.com/PyCQA/astroid/issues/336 + 'UNKNOWN', + ], + # Not shipped, GPL license but some header files contain no licensing info. + 'third_party/logilab/logilab/common': [ + 'GPL (v2 or later)', + # Look for email by nednguyen@google.com in May 5th in + # https://lists.logilab.org/pipermail/python-projects/ + 'UNKNOWN', + ], + # Not shipped, GPL license but some header files contain no licensing info. + 'third_party/pylint': [ + 'GPL (v2 or later)', + # https://github.com/PyCQA/pylint/issues/894 + 'UNKNOWN', + ], } EXCLUDED_PATHS = [ diff --git a/chromium/tools/chrome_proxy/common/chrome_proxy_measurements.py b/chromium/tools/chrome_proxy/common/chrome_proxy_measurements.py index 097c3273c1b..21a3f5587c3 100644 --- a/chromium/tools/chrome_proxy/common/chrome_proxy_measurements.py +++ b/chromium/tools/chrome_proxy/common/chrome_proxy_measurements.py @@ -67,20 +67,33 @@ class ChromeProxyValidation(page_test.PageTest): # Value of the extra via header. |None| if no extra via header is expected. extra_via_header = None - def __init__(self, restart_after_each_page=False, metrics=None): + def __init__(self, restart_after_each_page=False, metrics=None, + clear_cache_before_each_run=True): super(ChromeProxyValidation, self).__init__( - needs_browser_restart_after_each_page=restart_after_each_page) + needs_browser_restart_after_each_page=restart_after_each_page, + clear_cache_before_each_run=clear_cache_before_each_run) self._metrics = metrics self._page = None def CustomizeBrowserOptions(self, options): # Enable the chrome proxy (data reduction proxy). options.AppendExtraBrowserArgs('--enable-spdy-proxy-auth') + self._is_chrome_proxy_enabled = True + + # Disable quic option, otherwise request headers won't be visible. + options.AppendExtraBrowserArgs('--disable-quic') + + def DisableChromeProxy(self): + self.options.browser_options.extra_browser_args.discard( + '--enable-spdy-proxy-auth') + self._is_chrome_proxy_enabled = False def WillNavigateToPage(self, page, tab): - WaitForViaHeader(tab) + if self._is_chrome_proxy_enabled: + WaitForViaHeader(tab) - tab.ClearCache(force=True) + if self.clear_cache_before_each_run: + tab.ClearCache(force=True) assert self._metrics self._metrics.Start(page, tab) diff --git a/chromium/tools/chrome_proxy/common/inspector_network.py b/chromium/tools/chrome_proxy/common/inspector_network.py index 051a8fb909d..dee22d37269 100644 --- a/chromium/tools/chrome_proxy/common/inspector_network.py +++ b/chromium/tools/chrome_proxy/common/inspector_network.py @@ -158,7 +158,7 @@ class InspectorNetwork(object): 'method': 'Network.clearBrowserCache' }, timeout) - def StartMonitoringNetwork(self): + def StartMonitoringNetwork(self, timeout=60): """Starts monitoring network notifications and recording HTTP responses.""" self.ClearResponseData() self._inspector_websocket.RegisterDomain( @@ -167,14 +167,14 @@ class InspectorNetwork(object): request = { 'method': 'Network.enable' } - self._inspector_websocket.SyncRequest(request) + self._inspector_websocket.SyncRequest(request, timeout) - def StopMonitoringNetwork(self): + def StopMonitoringNetwork(self, timeout=60): """Stops monitoring network notifications and recording HTTP responses.""" request = { 'method': 'Network.disable' } - self._inspector_websocket.SyncRequest(request) + self._inspector_websocket.SyncRequest(request, timeout) # There may be queued messages that don't appear until the SyncRequest # happens. Wait to unregister until after sending the disable command. self._inspector_websocket.UnregisterDomain('Network') diff --git a/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_benchmark.py b/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_benchmark.py index 8129f4dc81e..875e1143f3b 100644 --- a/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_benchmark.py +++ b/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_benchmark.py @@ -32,6 +32,28 @@ class ChromeProxyLoFi(ChromeProxyBenchmark): @benchmark.Disabled(*WEBVIEW_PLATFORMS) +class ChromeProxyCacheLoFiDisabled(ChromeProxyBenchmark): + tag = 'cache_lo_fi_disabled' + test = measurements.ChromeProxyCacheLoFiDisabled + page_set = pagesets.LoFiCacheStorySet + + @classmethod + def Name(cls): + return 'chrome_proxy_benchmark.lo_fi.cache_lo_fi_disabled' + + +@benchmark.Disabled(*WEBVIEW_PLATFORMS) +class ChromeProxyCacheProxyDisabled(ChromeProxyBenchmark): + tag = 'cache_proxy_disabled' + test = measurements.ChromeProxyCacheProxyDisabled + page_set = pagesets.LoFiCacheStorySet + + @classmethod + def Name(cls): + return 'chrome_proxy_benchmark.lo_fi.cache_proxy_disabled' + + +@benchmark.Disabled(*WEBVIEW_PLATFORMS) class ChromeProxyPreviewLoFi(ChromeProxyBenchmark): tag = 'lo_fi_preview' test = measurements.ChromeProxyLoFiPreview @@ -285,4 +307,3 @@ class ChromeProxyVideoAudio(benchmark.Benchmark): @classmethod def Name(cls): return 'chrome_proxy_benchmark.video.audio' - diff --git a/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py b/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py index 2af7ec70b37..c9ce789fca3 100644 --- a/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py +++ b/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py @@ -10,7 +10,7 @@ from common import chrome_proxy_measurements as measurements from common.chrome_proxy_measurements import ChromeProxyValidation from integration_tests import chrome_proxy_metrics as metrics from metrics import loading -from telemetry.core import exceptions +from telemetry.core import exceptions, util from telemetry.page import page_test @@ -279,6 +279,94 @@ class ChromeProxyLoFi(ChromeProxyValidation): def AddResults(self, tab, results): self._metrics.AddResultsForLoFi(tab, results) +class ChromeProxyCacheLoFiDisabled(ChromeProxyValidation): + """ + Correctness measurement for Lo-Fi placeholder is not loaded from cache when a + page is reloaded with LoFi disabled. First a test page is opened with LoFi and + chrome proxy enabled. This allows Chrome to cache the LoFi placeholder image. + The browser is restarted with LoFi disabled and the same test page is loaded. + This second page load should not pick the LoFi placeholder from cache and + original image should be loaded. This test should be run with + --profile-type=default command line for the same user profile and cache to be + used across the two page loads. + """ + + def __init__(self): + super(ChromeProxyCacheLoFiDisabled, self).__init__( + restart_after_each_page=True, + metrics=metrics.ChromeProxyMetric(), + clear_cache_before_each_run=False) + + def AddResults(self, tab, results): + self._metrics.AddResultsForLoFiCache(tab, results, self._is_lo_fi_enabled) + + def WillStartBrowser(self, platform): + super(ChromeProxyCacheLoFiDisabled, self).WillStartBrowser(platform) + if not self._page: + # First page load, enable LoFi and chrome proxy. + self.options.AppendExtraBrowserArgs( + '--data-reduction-proxy-lo-fi=always-on') + self._is_lo_fi_enabled = True + else: + # Second page load, disable LoFi. Chrome proxy is still enabled. + self.options.browser_options.extra_browser_args.discard( + '--data-reduction-proxy-lo-fi=always-on') + self._is_lo_fi_enabled = False + + def WillNavigateToPage(self, page, tab): + super(ChromeProxyCacheLoFiDisabled, self).WillNavigateToPage(page, tab) + if self._is_lo_fi_enabled: + # Clear cache for the first page to pick LoFi image from server. + tab.ClearCache(force=True) + + def DidNavigateToPage(self, page, tab): + if not self._is_lo_fi_enabled: + tab.ExecuteJavaScript('window.location.reload()') + util.WaitFor(tab.HasReachedQuiescence, 3) + +class ChromeProxyCacheProxyDisabled(ChromeProxyValidation): + """ + Correctness measurement for Lo-Fi placeholder is not loaded from cache when a + page is reloaded with data reduction proxy disabled. First a test page is + opened with LoFi and chrome proxy enabled. This allows Chrome to cache the + LoFi placeholder image. The browser is restarted with chrome proxy disabled + and the same test page is loaded. This second page load should not pick the + LoFi placeholder from cache and original image should be loaded. This test + should be run with --profile-type=default command line for the same user + profile and cache to be used across the two page loads. + """ + + def __init__(self): + super(ChromeProxyCacheProxyDisabled, self).__init__( + restart_after_each_page=True, + metrics=metrics.ChromeProxyMetric(), + clear_cache_before_each_run=False) + + def AddResults(self, tab, results): + self._metrics.AddResultsForLoFiCache(tab, results, + self._is_chrome_proxy_enabled) + + def WillStartBrowser(self, platform): + super(ChromeProxyCacheProxyDisabled, self).WillStartBrowser(platform) + if not self._page: + # First page load, enable LoFi and chrome proxy. + self.options.AppendExtraBrowserArgs( + '--data-reduction-proxy-lo-fi=always-on') + else: + # Second page load, disable chrome proxy. LoFi is still enabled. + self.DisableChromeProxy() + + def WillNavigateToPage(self, page, tab): + super(ChromeProxyCacheProxyDisabled, self).WillNavigateToPage(page, tab) + if self._is_chrome_proxy_enabled: + # Clear cache for the first page to pick LoFi image from server. + tab.ClearCache(force=True) + + def DidNavigateToPage(self, page, tab): + if not self._is_chrome_proxy_enabled: + tab.ExecuteJavaScript('window.location.reload()') + util.WaitFor(tab.HasReachedQuiescence, 3) + class ChromeProxyLoFiPreview(ChromeProxyValidation): """Correctness measurement for Lo-Fi preview in Chrome-Proxy header.""" diff --git a/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py b/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py index 4dd4846f52e..ed543e6cb63 100644 --- a/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py +++ b/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py @@ -256,6 +256,48 @@ class ChromeProxyMetric(network_metrics.NetworkMetric): results.current_page, 'lo_fi_response', 'count', lo_fi_response_count)) super(ChromeProxyMetric, self).AddResults(tab, results) + + def AddResultsForLoFiCache(self, tab, results, is_lo_fi): + request_count = 0 + response_count = 0 + + for resp in self.IterResponses(tab): + if not resp.response.url.endswith('png'): + continue + if not resp.response.request_headers: + continue + + if is_lo_fi != resp.HasChromeProxyLoFiRequest(): + raise ChromeProxyMetricException, ( + '%s: LoFi %s expected in request header.' % (resp.response.url, + '' if is_lo_fi else 'not')) + else: + request_count += 1 + + if is_lo_fi != resp.HasChromeProxyLoFiResponse(): + raise ChromeProxyMetricException, ( + '%s: LoFi %s expected in response header.' % (resp.response.url, + '' if is_lo_fi else 'not')) + else: + response_count += 1 + + if is_lo_fi != (resp.content_length < 100): + raise ChromeProxyMetricException, ( + 'Image %s is %d bytes. Expecting %s than 100 bytes.' % + (resp.response.url, resp.content_length, + 'less' if is_lo_fi else 'more')) + + if request_count == 0: + raise ChromeProxyMetricException, ( + 'Expected at least one %s LoFi request, but zero such requests were ' + 'sent.' % ('' if is_lo_fi else 'non')) + if response_count == 0: + raise ChromeProxyMetricException, ( + 'Expected at least one %s LoFi response, but zero such responses ' + 'were received.' % ('' if is_lo_fi else 'non')) + + super(ChromeProxyMetric, self).AddResults(tab, results) + def AddResultsForLoFiPreview(self, tab, results): lo_fi_preview_request_count = 0 lo_fi_preview_exp_request_count = 0 diff --git a/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/lo_fi_cache.py b/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/lo_fi_cache.py new file mode 100644 index 00000000000..2cfa341da19 --- /dev/null +++ b/chromium/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/lo_fi_cache.py @@ -0,0 +1,32 @@ +# Copyright 2015 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. + +from telemetry.page import page as page_module +from telemetry import story + + +class LoFiPageCache(page_module.Page): + """ + A test page for the chrome proxy Lo-Fi cache tests. + Checks that LoFi placeholder images are not loaded from cache on page reloads + when LoFi mode is disabled or data reduction proxy is disabled. + """ + + def __init__(self, url, page_set): + super(LoFiPageCache, self).__init__(url=url, page_set=page_set) + + +class LoFiCacheStorySet(story.StorySet): + """ Chrome proxy test sites """ + + def __init__(self): + super(LoFiCacheStorySet, self).__init__() + + urls_list = [ + 'http://check.googlezip.net/cacheable/test.html', + 'http://check.googlezip.net/cacheable/test.html', + ] + + for url in urls_list: + self.AddStory(LoFiPageCache(url, self)) diff --git a/chromium/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/chromium/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp index b8d0a44573f..d60d73f9d6b 100644 --- a/chromium/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp +++ b/chromium/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp @@ -29,26 +29,19 @@ class BlinkGCPluginAction : public PluginASTAction { return llvm::make_unique<BlinkGCPluginConsumer>(instance, options_); } - virtual bool ParseArgs(const CompilerInstance& instance, + virtual bool ParseArgs(const CompilerInstance&, const std::vector<std::string>& args) { - bool parsed = true; - - for (size_t i = 0; i < args.size() && parsed; ++i) { - if (args[i] == "enable-oilpan") { - options_.enable_oilpan = true; - } else if (args[i] == "dump-graph") { + for (const auto& arg : args) { + if (arg == "dump-graph") { options_.dump_graph = true; - } else if (args[i] == "warn-raw-ptr") { - options_.warn_raw_ptr = true; - } else if (args[i] == "warn-unneeded-finalizer") { + } else if (arg == "warn-unneeded-finalizer") { options_.warn_unneeded_finalizer = true; } else { - parsed = false; - llvm::errs() << "Unknown blink-gc-plugin argument: " << args[i] << "\n"; + llvm::errs() << "Unknown blink-gc-plugin argument: " << arg << "\n"; + return false; } } - - return parsed; + return true; } private: diff --git a/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp b/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp index 7c90ddd3504..1a32defcc42 100644 --- a/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp +++ b/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp @@ -8,6 +8,9 @@ #include <set> #include "CheckDispatchVisitor.h" +#include "CheckFieldsVisitor.h" +#include "CheckFinalizerVisitor.h" +#include "CheckGCRootsVisitor.h" #include "CheckTraceVisitor.h" #include "CollectVisitor.h" #include "JsonWriter.h" @@ -19,136 +22,6 @@ using namespace clang; namespace { -const char kClassMustLeftMostlyDeriveGC[] = - "[blink-gc] Class %0 must derive its GC base in the left-most position."; - -const char kClassRequiresTraceMethod[] = - "[blink-gc] Class %0 requires a trace method."; - -const char kBaseRequiresTracing[] = - "[blink-gc] Base class %0 of derived class %1 requires tracing."; - -const char kBaseRequiresTracingNote[] = - "[blink-gc] Untraced base class %0 declared here:"; - -const char kFieldsRequireTracing[] = - "[blink-gc] Class %0 has untraced fields that require tracing."; - -const char kFieldRequiresTracingNote[] = - "[blink-gc] Untraced field %0 declared here:"; - -const char kClassContainsInvalidFields[] = - "[blink-gc] Class %0 contains invalid fields."; - -const char kClassContainsGCRoot[] = - "[blink-gc] Class %0 contains GC root in field %1."; - -const char kClassRequiresFinalization[] = - "[blink-gc] Class %0 requires finalization."; - -const char kClassDoesNotRequireFinalization[] = - "[blink-gc] Class %0 may not require finalization."; - -const char kFinalizerAccessesFinalizedField[] = - "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; - -const char kFinalizerAccessesEagerlyFinalizedField[] = - "[blink-gc] Finalizer %0 accesses eagerly finalized field %1."; - -const char kRawPtrToGCManagedClassNote[] = - "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; - -const char kRefPtrToGCManagedClassNote[] = - "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; - -const char kReferencePtrToGCManagedClassNote[] = - "[blink-gc] Reference pointer field %0 to a GC managed class" - " declared here:"; - -const char kOwnPtrToGCManagedClassNote[] = - "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; - -const char kMemberToGCUnmanagedClassNote[] = - "[blink-gc] Member field %0 to non-GC managed class declared here:"; - -const char kStackAllocatedFieldNote[] = - "[blink-gc] Stack-allocated field %0 declared here:"; - -const char kMemberInUnmanagedClassNote[] = - "[blink-gc] Member field %0 in unmanaged class declared here:"; - -const char kPartObjectToGCDerivedClassNote[] = - "[blink-gc] Part-object field %0 to a GC derived class declared here:"; - -const char kPartObjectContainsGCRootNote[] = - "[blink-gc] Field %0 with embedded GC root in %1 declared here:"; - -const char kFieldContainsGCRootNote[] = - "[blink-gc] Field %0 defining a GC root declared here:"; - -const char kOverriddenNonVirtualTrace[] = - "[blink-gc] Class %0 overrides non-virtual trace of base class %1."; - -const char kOverriddenNonVirtualTraceNote[] = - "[blink-gc] Non-virtual trace method declared here:"; - -const char kMissingTraceDispatchMethod[] = - "[blink-gc] Class %0 is missing manual trace dispatch."; - -const char kMissingFinalizeDispatchMethod[] = - "[blink-gc] Class %0 is missing manual finalize dispatch."; - -const char kVirtualAndManualDispatch[] = - "[blink-gc] Class %0 contains or inherits virtual methods" - " but implements manual dispatching."; - -const char kMissingTraceDispatch[] = - "[blink-gc] Missing dispatch to class %0 in manual trace dispatch."; - -const char kMissingFinalizeDispatch[] = - "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch."; - -const char kFinalizedFieldNote[] = - "[blink-gc] Potentially finalized field %0 declared here:"; - -const char kEagerlyFinalizedFieldNote[] = - "[blink-gc] Field %0 having eagerly finalized value, declared here:"; - -const char kUserDeclaredDestructorNote[] = - "[blink-gc] User-declared destructor declared here:"; - -const char kUserDeclaredFinalizerNote[] = - "[blink-gc] User-declared finalizer declared here:"; - -const char kBaseRequiresFinalizationNote[] = - "[blink-gc] Base class %0 requiring finalization declared here:"; - -const char kFieldRequiresFinalizationNote[] = - "[blink-gc] Field %0 requiring finalization declared here:"; - -const char kManualDispatchMethodNote[] = - "[blink-gc] Manual dispatch %0 declared here:"; - -const char kDerivesNonStackAllocated[] = - "[blink-gc] Stack-allocated class %0 derives class %1" - " which is not stack allocated."; - -const char kClassOverridesNew[] = - "[blink-gc] Garbage collected class %0" - " is not permitted to override its new operator."; - -const char kClassDeclaresPureVirtualTrace[] = - "[blink-gc] Garbage collected class %0" - " is not permitted to declare a pure-virtual trace method."; - -const char kLeftMostBaseMustBePolymorphic[] = - "[blink-gc] Left-most base class %0 of derived class %1" - " must be polymorphic."; - -const char kBaseClassMustDeclareVirtualTrace[] = - "[blink-gc] Left-most base class %0 of derived class %1" - " must define a virtual trace method."; - // Use a local RAV implementation to simply collect all FunctionDecls marked for // late template parsing. This happens with the flag -fdelayed-template-parsing, // which is on by default in MSVC-compatible mode. @@ -193,7 +66,7 @@ BlinkGCPluginConsumer::BlinkGCPluginConsumer( clang::CompilerInstance& instance, const BlinkGCPluginOptions& options) : instance_(instance), - diagnostic_(instance.getDiagnostics()), + reporter_(instance), options_(options), json_(0) { // Only check structures in the blink and WebKit namespaces. @@ -201,99 +74,11 @@ BlinkGCPluginConsumer::BlinkGCPluginConsumer( // Ignore GC implementation files. options_.ignored_directories.push_back("/heap/"); - - // Register warning/error messages. - diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kClassMustLeftMostlyDeriveGC); - diag_class_requires_trace_method_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod); - diag_base_requires_tracing_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing); - diag_fields_require_tracing_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing); - diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kClassContainsInvalidFields); - diag_class_contains_invalid_fields_warning_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kClassContainsInvalidFields); - diag_class_contains_gc_root_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); - diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kClassRequiresFinalization); - diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization); - diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kFinalizerAccessesFinalizedField); - diag_finalizer_eagerly_finalized_field_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kFinalizerAccessesEagerlyFinalizedField); - diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kOverriddenNonVirtualTrace); - diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kMissingTraceDispatchMethod); - diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kMissingFinalizeDispatchMethod); - diag_virtual_and_manual_dispatch_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); - diag_missing_trace_dispatch_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch); - diag_missing_finalize_dispatch_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kMissingFinalizeDispatch); - diag_derives_non_stack_allocated_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated); - diag_class_overrides_new_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew); - diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kClassDeclaresPureVirtualTrace); - diag_left_most_base_must_be_polymorphic_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kLeftMostBaseMustBePolymorphic); - diag_base_class_must_declare_virtual_trace_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kBaseClassMustDeclareVirtualTrace); - - // Register note messages. - diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kBaseRequiresTracingNote); - diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kFieldRequiresTracingNote); - diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); - diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); - diag_reference_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kReferencePtrToGCManagedClassNote); - diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); - diag_member_to_gc_unmanaged_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kMemberToGCUnmanagedClassNote); - diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kStackAllocatedFieldNote); - diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); - diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); - diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); - diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kFieldContainsGCRootNote); - diag_finalized_field_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kFinalizedFieldNote); - diag_eagerly_finalized_field_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kEagerlyFinalizedFieldNote); - diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kUserDeclaredDestructorNote); - diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); - diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); - diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kFieldRequiresFinalizationNote); - diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote); - diag_manual_dispatch_method_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kManualDispatchMethodNote); } void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) { // Don't run the plugin if the compilation unit is already invalid. - if (diagnostic_.hasErrorOccurred()) + if (reporter_.hasErrorOccurred()) return; ParseFunctionTemplates(context.getTranslationUnitDecl()); @@ -395,14 +180,14 @@ void BlinkGCPluginConsumer::CheckClass(RecordInfo* info) { if (info->IsStackAllocated()) { for (auto& base : info->GetBases()) if (!base.second.info()->IsStackAllocated()) - ReportDerivesNonStackAllocated(info, &base.second); + reporter_.DerivesNonStackAllocated(info, &base.second); } if (CXXMethodDecl* trace = info->GetTraceMethod()) { if (trace->isPure()) - ReportClassDeclaresPureVirtualTrace(info, trace); + reporter_.ClassDeclaresPureVirtualTrace(info, trace); } else if (info->RequiresTraceMethod()) { - ReportClassRequiresTraceMethod(info); + reporter_.ClassRequiresTraceMethod(info); } // Check polymorphic classes that are GC-derived or have a trace method. @@ -414,9 +199,9 @@ void BlinkGCPluginConsumer::CheckClass(RecordInfo* info) { } { - CheckFieldsVisitor visitor(options_); + CheckFieldsVisitor visitor; if (visitor.ContainsInvalidFields(info)) - ReportClassContainsInvalidFields(info, visitor.invalid_fields()); + reporter_.ClassContainsInvalidFields(info, visitor.invalid_fields()); } if (info->IsGCDerived()) { @@ -425,13 +210,13 @@ void BlinkGCPluginConsumer::CheckClass(RecordInfo* info) { CheckDispatch(info); if (CXXMethodDecl* newop = info->DeclaresNewOperator()) if (!Config::IsIgnoreAnnotated(newop)) - ReportClassOverridesNew(info, newop); + reporter_.ClassOverridesNew(info, newop); } { CheckGCRootsVisitor visitor; if (visitor.ContainsGCRoots(info)) - ReportClassContainsGCRoots(info, visitor.gc_roots()); + reporter_.ClassContainsGCRoots(info, visitor.gc_roots()); } if (info->NeedsFinalization()) @@ -515,7 +300,7 @@ void BlinkGCPluginConsumer::CheckPolymorphicClass( if (trace->isVirtual()) return; } - ReportBaseClassMustDeclareVirtualTrace(info, left_most); + reporter_.BaseClassMustDeclareVirtualTrace(info, left_most); return; } @@ -531,13 +316,13 @@ void BlinkGCPluginConsumer::CheckPolymorphicClass( if (CXXRecordDecl* next_left_most = GetLeftMostBase(next_base)) { if (DeclaresVirtualMethods(next_left_most)) return; - ReportLeftMostBaseMustBePolymorphic(info, next_left_most); + reporter_.LeftMostBaseMustBePolymorphic(info, next_left_most); return; } } } } - ReportLeftMostBaseMustBePolymorphic(info, left_most); + reporter_.LeftMostBaseMustBePolymorphic(info, left_most); } } @@ -569,7 +354,7 @@ void BlinkGCPluginConsumer::CheckLeftMostDerived(RecordInfo* info) { if (!left_most) return; if (!Config::IsGCBase(left_most->getName())) - ReportClassMustLeftMostlyDeriveGC(info); + reporter_.ClassMustLeftMostlyDeriveGC(info); } void BlinkGCPluginConsumer::CheckDispatch(RecordInfo* info) { @@ -585,18 +370,18 @@ void BlinkGCPluginConsumer::CheckDispatch(RecordInfo* info) { // Check that dispatch methods are defined at the base. if (base == info->record()) { if (!trace_dispatch) - ReportMissingTraceDispatchMethod(info); + reporter_.MissingTraceDispatchMethod(info); if (finalized && !finalize_dispatch) - ReportMissingFinalizeDispatchMethod(info); + reporter_.MissingFinalizeDispatchMethod(info); if (!finalized && finalize_dispatch) { - ReportClassRequiresFinalization(info); - NoteUserDeclaredFinalizer(finalize_dispatch); + reporter_.ClassRequiresFinalization(info); + reporter_.NoteUserDeclaredFinalizer(finalize_dispatch); } } // Check that classes implementing manual dispatch do not have vtables. if (info->record()->isPolymorphic()) { - ReportVirtualAndManualDispatch( + reporter_.VirtualAndManualDispatch( info, trace_dispatch ? trace_dispatch : finalize_dispatch); } @@ -612,14 +397,14 @@ void BlinkGCPluginConsumer::CheckDispatch(RecordInfo* info) { CheckDispatchVisitor visitor(info); visitor.TraverseStmt(defn->getBody()); if (!visitor.dispatched_to_receiver()) - ReportMissingTraceDispatch(defn, info); + reporter_.MissingTraceDispatch(defn, info); } if (finalized && finalize_dispatch && finalize_dispatch->isDefined(defn)) { CheckDispatchVisitor visitor(info); visitor.TraverseStmt(defn->getBody()); if (!visitor.dispatched_to_receiver()) - ReportMissingFinalizeDispatch(defn, info); + reporter_.MissingFinalizeDispatch(defn, info); } } @@ -633,7 +418,7 @@ void BlinkGCPluginConsumer::CheckFinalization(RecordInfo* info) { CheckFinalizerVisitor visitor(&cache_, info->IsEagerlyFinalized()); visitor.TraverseCXXMethodDecl(dtor); if (!visitor.finalized_fields().empty()) { - ReportFinalizerAccessesFinalizedFields( + reporter_.FinalizerAccessesFinalizedFields( dtor, visitor.finalized_fields()); } } @@ -646,31 +431,57 @@ void BlinkGCPluginConsumer::CheckFinalization(RecordInfo* info) { // Report the finalization error, and proceed to print possible causes for // the finalization requirement. - ReportClassRequiresFinalization(info); + reporter_.ClassRequiresFinalization(info); if (dtor && dtor->isUserProvided()) - NoteUserDeclaredDestructor(dtor); + reporter_.NoteUserDeclaredDestructor(dtor); for (auto& base : info->GetBases()) if (base.second.info()->NeedsFinalization()) - NoteBaseRequiresFinalization(&base.second); + reporter_.NoteBaseRequiresFinalization(&base.second); for (auto& field : info->GetFields()) if (field.second.edge()->NeedsFinalization()) - NoteField(&field.second, diag_field_requires_finalization_note_); + reporter_.NoteFieldRequiresFinalization(&field.second); } void BlinkGCPluginConsumer::CheckUnneededFinalization(RecordInfo* info) { if (!HasNonEmptyFinalizer(info)) - ReportClassDoesNotRequireFinalization(info); + reporter_.ClassDoesNotRequireFinalization(info); } bool BlinkGCPluginConsumer::HasNonEmptyFinalizer(RecordInfo* info) { CXXDestructorDecl* dtor = info->record()->getDestructor(); + + // If the destructor is virtual (or one of the bases are by way of the + // recursive call below), consider this class as having a non-empty + // finalizer. Not doing so runs counter to standard C++ reflexes like + // + // class A : public GarbageCollectedMixin { + // public: + // virtual ~A() { }; + // virtual void f() = 0; + // }; + // class B : public GarbageCollectedFinalized<B>, public A { + // USING_GARBAGE_COLLECTED_MIXIN(B); + // public: + // ~B() override { } + // void f() override { } + // }; + // + // and it is considered a step too far to report a warning for such + // explicit usage of empty destructors. + if (dtor && dtor->isVirtual()) + return true; + if (dtor && dtor->isUserProvided()) { if (!dtor->hasBody() || !EmptyStmtVisitor::isEmpty(dtor->getBody())) return true; } + + if (info->GetFinalizeDispatchMethod()) + return true; + for (auto& base : info->GetBases()) if (HasNonEmptyFinalizer(base.second.info())) return true; @@ -724,7 +535,7 @@ void BlinkGCPluginConsumer::CheckTraceMethod( if (trace_type == Config::TRACE_METHOD) { for (auto& base : parent->GetBases()) if (CXXMethodDecl* other = base.second.info()->InheritsNonVirtualTrace()) - ReportOverriddenNonVirtualTrace(parent, trace, other); + reporter_.OverriddenNonVirtualTrace(parent, trace, other); } CheckTraceVisitor visitor(trace, parent, &cache_); @@ -738,12 +549,12 @@ void BlinkGCPluginConsumer::CheckTraceMethod( for (auto& base : parent->GetBases()) if (!base.second.IsProperlyTraced()) - ReportBaseRequiresTracing(parent, trace, base.first); + reporter_.BaseRequiresTracing(parent, trace, base.first); for (auto& field : parent->GetFields()) { if (!field.second.IsProperlyTraced()) { // Discontinue once an untraced-field error is found. - ReportFieldsRequireTracing(parent, trace); + reporter_.FieldsRequireTracing(parent, trace); break; } } @@ -834,11 +645,6 @@ void BlinkGCPluginConsumer::DumpClass(RecordInfo* info) { GetLocString(field.second.field()->getLocStart())); } -DiagnosticsEngine::Level BlinkGCPluginConsumer::getErrorLevel() { - return diagnostic_.getWarningsAsErrors() ? DiagnosticsEngine::Error - : DiagnosticsEngine::Warning; -} - std::string BlinkGCPluginConsumer::GetLocString(SourceLocation loc) { const SourceManager& source_manager = instance_.getSourceManager(); PresumedLoc ploc = source_manager.getPresumedLoc(loc); @@ -913,289 +719,3 @@ bool BlinkGCPluginConsumer::GetFilename(SourceLocation loc, *filename = ploc.getFilename(); return true; } - -DiagnosticBuilder BlinkGCPluginConsumer::ReportDiagnostic( - SourceLocation location, - unsigned diag_id) { - SourceManager& manager = instance_.getSourceManager(); - FullSourceLoc full_loc(location, manager); - return diagnostic_.Report(full_loc, diag_id); -} - -void BlinkGCPluginConsumer::ReportClassMustLeftMostlyDeriveGC( - RecordInfo* info) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_class_must_left_mostly_derive_gc_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportClassRequiresTraceMethod(RecordInfo* info) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_class_requires_trace_method_) - << info->record(); - - for (auto& base : info->GetBases()) - if (base.second.NeedsTracing().IsNeeded()) - NoteBaseRequiresTracing(&base.second); - - for (auto& field : info->GetFields()) - if (!field.second.IsProperlyTraced()) - NoteFieldRequiresTracing(info, field.first); -} - -void BlinkGCPluginConsumer::ReportBaseRequiresTracing( - RecordInfo* derived, - CXXMethodDecl* trace, - CXXRecordDecl* base) { - ReportDiagnostic(trace->getLocStart(), diag_base_requires_tracing_) - << base << derived->record(); -} - -void BlinkGCPluginConsumer::ReportFieldsRequireTracing( - RecordInfo* info, - CXXMethodDecl* trace) { - ReportDiagnostic(trace->getLocStart(), diag_fields_require_tracing_) - << info->record(); - for (auto& field : info->GetFields()) - if (!field.second.IsProperlyTraced()) - NoteFieldRequiresTracing(info, field.first); -} - -void BlinkGCPluginConsumer::ReportClassContainsInvalidFields( - RecordInfo* info, - const CheckFieldsVisitor::Errors& errors) { - bool only_warnings = options_.warn_raw_ptr; - for (auto& error : errors) - if (!CheckFieldsVisitor::IsWarning(error.second)) - only_warnings = false; - - ReportDiagnostic(info->record()->getLocStart(), - only_warnings ? - diag_class_contains_invalid_fields_warning_ : - diag_class_contains_invalid_fields_) - << info->record(); - - for (auto& error : errors) { - unsigned note; - if (CheckFieldsVisitor::IsRawPtrError(error.second)) { - note = diag_raw_ptr_to_gc_managed_class_note_; - } else if (CheckFieldsVisitor::IsReferencePtrError(error.second)) { - note = diag_reference_ptr_to_gc_managed_class_note_; - } else if (error.second == CheckFieldsVisitor::kRefPtrToGCManaged) { - note = diag_ref_ptr_to_gc_managed_class_note_; - } else if (error.second == CheckFieldsVisitor::kOwnPtrToGCManaged) { - note = diag_own_ptr_to_gc_managed_class_note_; - } else if (error.second == CheckFieldsVisitor::kMemberToGCUnmanaged) { - note = diag_member_to_gc_unmanaged_class_note_; - } else if (error.second == CheckFieldsVisitor::kMemberInUnmanaged) { - note = diag_member_in_unmanaged_class_note_; - } else if (error.second == CheckFieldsVisitor::kPtrFromHeapToStack) { - note = diag_stack_allocated_field_note_; - } else if (error.second == CheckFieldsVisitor::kGCDerivedPartObject) { - note = diag_part_object_to_gc_derived_class_note_; - } else { - assert(false && "Unknown field error"); - } - NoteField(error.first, note); - } -} - -void BlinkGCPluginConsumer::ReportClassContainsGCRoots( - RecordInfo* info, - const CheckGCRootsVisitor::Errors& errors) { - for (auto& error : errors) { - FieldPoint* point = nullptr; - for (FieldPoint* path : error) { - if (!point) { - point = path; - ReportDiagnostic(info->record()->getLocStart(), - diag_class_contains_gc_root_) - << info->record() << point->field(); - continue; - } - NotePartObjectContainsGCRoot(point); - point = path; - } - NoteFieldContainsGCRoot(point); - } -} - -void BlinkGCPluginConsumer::ReportFinalizerAccessesFinalizedFields( - CXXMethodDecl* dtor, - const CheckFinalizerVisitor::Errors& errors) { - for (auto& error : errors) { - bool as_eagerly_finalized = error.as_eagerly_finalized; - unsigned diag_error = as_eagerly_finalized ? - diag_finalizer_eagerly_finalized_field_ : - diag_finalizer_accesses_finalized_field_; - unsigned diag_note = as_eagerly_finalized ? - diag_eagerly_finalized_field_note_ : - diag_finalized_field_note_; - ReportDiagnostic(error.member->getLocStart(), diag_error) - << dtor << error.field->field(); - NoteField(error.field, diag_note); - } -} - -void BlinkGCPluginConsumer::ReportClassRequiresFinalization(RecordInfo* info) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_class_requires_finalization_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportClassDoesNotRequireFinalization( - RecordInfo* info) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_class_does_not_require_finalization_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportOverriddenNonVirtualTrace( - RecordInfo* info, - CXXMethodDecl* trace, - CXXMethodDecl* overridden) { - ReportDiagnostic(trace->getLocStart(), diag_overridden_non_virtual_trace_) - << info->record() << overridden->getParent(); - NoteOverriddenNonVirtualTrace(overridden); -} - -void BlinkGCPluginConsumer::ReportMissingTraceDispatchMethod(RecordInfo* info) { - ReportMissingDispatchMethod(info, diag_missing_trace_dispatch_method_); -} - -void BlinkGCPluginConsumer::ReportMissingFinalizeDispatchMethod( - RecordInfo* info) { - ReportMissingDispatchMethod(info, diag_missing_finalize_dispatch_method_); -} - -void BlinkGCPluginConsumer::ReportMissingDispatchMethod( - RecordInfo* info, - unsigned error) { - ReportDiagnostic(info->record()->getInnerLocStart(), error) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportVirtualAndManualDispatch( - RecordInfo* info, - CXXMethodDecl* dispatch) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_virtual_and_manual_dispatch_) - << info->record(); - NoteManualDispatchMethod(dispatch); -} - -void BlinkGCPluginConsumer::ReportMissingTraceDispatch( - const FunctionDecl* dispatch, - RecordInfo* receiver) { - ReportMissingDispatch(dispatch, receiver, diag_missing_trace_dispatch_); -} - -void BlinkGCPluginConsumer::ReportMissingFinalizeDispatch( - const FunctionDecl* dispatch, - RecordInfo* receiver) { - ReportMissingDispatch(dispatch, receiver, diag_missing_finalize_dispatch_); -} - -void BlinkGCPluginConsumer::ReportMissingDispatch( - const FunctionDecl* dispatch, - RecordInfo* receiver, - unsigned error) { - ReportDiagnostic(dispatch->getLocStart(), error) << receiver->record(); -} - -void BlinkGCPluginConsumer::ReportDerivesNonStackAllocated( - RecordInfo* info, - BasePoint* base) { - ReportDiagnostic(base->spec().getLocStart(), - diag_derives_non_stack_allocated_) - << info->record() << base->info()->record(); -} - -void BlinkGCPluginConsumer::ReportClassOverridesNew( - RecordInfo* info, - CXXMethodDecl* newop) { - ReportDiagnostic(newop->getLocStart(), diag_class_overrides_new_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportClassDeclaresPureVirtualTrace( - RecordInfo* info, - CXXMethodDecl* trace) { - ReportDiagnostic(trace->getLocStart(), - diag_class_declares_pure_virtual_trace_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportLeftMostBaseMustBePolymorphic( - RecordInfo* derived, - CXXRecordDecl* base) { - ReportDiagnostic(base->getLocStart(), - diag_left_most_base_must_be_polymorphic_) - << base << derived->record(); -} - -void BlinkGCPluginConsumer::ReportBaseClassMustDeclareVirtualTrace( - RecordInfo* derived, - CXXRecordDecl* base) { - ReportDiagnostic(base->getLocStart(), - diag_base_class_must_declare_virtual_trace_) - << base << derived->record(); -} - -void BlinkGCPluginConsumer::NoteManualDispatchMethod(CXXMethodDecl* dispatch) { - ReportDiagnostic(dispatch->getLocStart(), - diag_manual_dispatch_method_note_) - << dispatch; -} - -void BlinkGCPluginConsumer::NoteBaseRequiresTracing(BasePoint* base) { - ReportDiagnostic(base->spec().getLocStart(), - diag_base_requires_tracing_note_) - << base->info()->record(); -} - -void BlinkGCPluginConsumer::NoteFieldRequiresTracing( - RecordInfo* holder, - FieldDecl* field) { - NoteField(field, diag_field_requires_tracing_note_); -} - -void BlinkGCPluginConsumer::NotePartObjectContainsGCRoot(FieldPoint* point) { - FieldDecl* field = point->field(); - ReportDiagnostic(field->getLocStart(), - diag_part_object_contains_gc_root_note_) - << field << field->getParent(); -} - -void BlinkGCPluginConsumer::NoteFieldContainsGCRoot(FieldPoint* point) { - NoteField(point, diag_field_contains_gc_root_note_); -} - -void BlinkGCPluginConsumer::NoteUserDeclaredDestructor(CXXMethodDecl* dtor) { - ReportDiagnostic(dtor->getLocStart(), diag_user_declared_destructor_note_); -} - -void BlinkGCPluginConsumer::NoteUserDeclaredFinalizer(CXXMethodDecl* dtor) { - ReportDiagnostic(dtor->getLocStart(), diag_user_declared_finalizer_note_); -} - -void BlinkGCPluginConsumer::NoteBaseRequiresFinalization(BasePoint* base) { - ReportDiagnostic(base->spec().getLocStart(), - diag_base_requires_finalization_note_) - << base->info()->record(); -} - -void BlinkGCPluginConsumer::NoteField(FieldPoint* point, unsigned note) { - NoteField(point->field(), note); -} - -void BlinkGCPluginConsumer::NoteField(FieldDecl* field, unsigned note) { - ReportDiagnostic(field->getLocStart(), note) << field; -} - -void BlinkGCPluginConsumer::NoteOverriddenNonVirtualTrace( - CXXMethodDecl* overridden) { - ReportDiagnostic(overridden->getLocStart(), - diag_overridden_non_virtual_trace_note_) - << overridden; -} diff --git a/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.h b/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.h index d0b49d89bf2..bcfb3afbd59 100644 --- a/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.h +++ b/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.h @@ -8,10 +8,8 @@ #include <string> #include "BlinkGCPluginOptions.h" -#include "CheckFieldsVisitor.h" -#include "CheckFinalizerVisitor.h" -#include "CheckGCRootsVisitor.h" #include "Config.h" +#include "DiagnosticsReporter.h" #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/Basic/Diagnostic.h" @@ -75,7 +73,7 @@ class BlinkGCPluginConsumer : public clang::ASTConsumer { std::string GetLocString(clang::SourceLocation loc); - bool IsIgnored(RecordInfo* record); + bool IsIgnored(RecordInfo* info); bool IsIgnoredClass(RecordInfo* info); @@ -85,113 +83,11 @@ class BlinkGCPluginConsumer : public clang::ASTConsumer { bool GetFilename(clang::SourceLocation loc, std::string* filename); - clang::DiagnosticBuilder ReportDiagnostic( - clang::SourceLocation location, - unsigned diag_id); - - void ReportClassMustLeftMostlyDeriveGC(RecordInfo* info); - void ReportClassRequiresTraceMethod(RecordInfo* info); - void ReportBaseRequiresTracing(RecordInfo* derived, - clang::CXXMethodDecl* trace, - clang::CXXRecordDecl* base); - void ReportFieldsRequireTracing(RecordInfo* info, - clang::CXXMethodDecl* trace); - void ReportClassContainsInvalidFields( - RecordInfo* info, - const CheckFieldsVisitor::Errors& errors); - void ReportClassContainsGCRoots(RecordInfo* info, - const CheckGCRootsVisitor::Errors& errors); - void ReportFinalizerAccessesFinalizedFields( - clang::CXXMethodDecl* dtor, - const CheckFinalizerVisitor::Errors& errors); - void ReportClassRequiresFinalization(RecordInfo* info); - void ReportClassDoesNotRequireFinalization(RecordInfo* info); - void ReportClassMustDeclareGCMixinTraceMethod(RecordInfo* info); - void ReportOverriddenNonVirtualTrace(RecordInfo* info, - clang::CXXMethodDecl* trace, - clang::CXXMethodDecl* overridden); - void ReportMissingTraceDispatchMethod(RecordInfo* info); - void ReportMissingFinalizeDispatchMethod(RecordInfo* info); - void ReportMissingDispatchMethod(RecordInfo* info, unsigned error); - void ReportVirtualAndManualDispatch(RecordInfo* info, - clang::CXXMethodDecl* dispatch); - void ReportMissingTraceDispatch(const clang::FunctionDecl* dispatch, - RecordInfo* receiver); - void ReportMissingFinalizeDispatch(const clang::FunctionDecl* dispatch, - RecordInfo* receiver); - void ReportMissingDispatch(const clang::FunctionDecl* dispatch, - RecordInfo* receiver, - unsigned error); - void ReportDerivesNonStackAllocated(RecordInfo* info, BasePoint* base); - void ReportClassOverridesNew(RecordInfo* info, clang::CXXMethodDecl* newop); - void ReportClassDeclaresPureVirtualTrace(RecordInfo* info, - clang::CXXMethodDecl* trace); - void ReportLeftMostBaseMustBePolymorphic(RecordInfo* derived, - clang::CXXRecordDecl* base); - void ReportBaseClassMustDeclareVirtualTrace(RecordInfo* derived, - clang::CXXRecordDecl* base); - void NoteManualDispatchMethod(clang::CXXMethodDecl* dispatch); - void NoteBaseRequiresTracing(BasePoint* base); - void NoteFieldRequiresTracing(RecordInfo* holder, clang::FieldDecl* field); - void NotePartObjectContainsGCRoot(FieldPoint* point); - void NoteFieldContainsGCRoot(FieldPoint* point); - void NoteUserDeclaredDestructor(clang::CXXMethodDecl* dtor); - void NoteUserDeclaredFinalizer(clang::CXXMethodDecl* dtor); - void NoteBaseRequiresFinalization(BasePoint* base); - void NoteField(FieldPoint* point, unsigned note); - void NoteField(clang::FieldDecl* field, unsigned note); - void NoteOverriddenNonVirtualTrace(clang::CXXMethodDecl* overridden); - - unsigned diag_class_must_left_mostly_derive_gc_; - unsigned diag_class_requires_trace_method_; - unsigned diag_base_requires_tracing_; - unsigned diag_fields_require_tracing_; - unsigned diag_class_contains_invalid_fields_; - unsigned diag_class_contains_invalid_fields_warning_; - unsigned diag_class_contains_gc_root_; - unsigned diag_class_requires_finalization_; - unsigned diag_class_does_not_require_finalization_; - unsigned diag_finalizer_accesses_finalized_field_; - unsigned diag_finalizer_eagerly_finalized_field_; - unsigned diag_overridden_non_virtual_trace_; - unsigned diag_missing_trace_dispatch_method_; - unsigned diag_missing_finalize_dispatch_method_; - unsigned diag_virtual_and_manual_dispatch_; - unsigned diag_missing_trace_dispatch_; - unsigned diag_missing_finalize_dispatch_; - unsigned diag_derives_non_stack_allocated_; - unsigned diag_class_overrides_new_; - unsigned diag_class_declares_pure_virtual_trace_; - unsigned diag_left_most_base_must_be_polymorphic_; - unsigned diag_base_class_must_declare_virtual_trace_; - - unsigned diag_base_requires_tracing_note_; - unsigned diag_field_requires_tracing_note_; - unsigned diag_raw_ptr_to_gc_managed_class_note_; - unsigned diag_ref_ptr_to_gc_managed_class_note_; - unsigned diag_reference_ptr_to_gc_managed_class_note_; - unsigned diag_own_ptr_to_gc_managed_class_note_; - unsigned diag_member_to_gc_unmanaged_class_note_; - unsigned diag_stack_allocated_field_note_; - unsigned diag_member_in_unmanaged_class_note_; - unsigned diag_part_object_to_gc_derived_class_note_; - unsigned diag_part_object_contains_gc_root_note_; - unsigned diag_field_contains_gc_root_note_; - unsigned diag_finalized_field_note_; - unsigned diag_eagerly_finalized_field_note_; - unsigned diag_user_declared_destructor_note_; - unsigned diag_user_declared_finalizer_note_; - unsigned diag_base_requires_finalization_note_; - unsigned diag_field_requires_finalization_note_; - unsigned diag_overridden_non_virtual_trace_note_; - unsigned diag_manual_dispatch_method_note_; - clang::CompilerInstance& instance_; - clang::DiagnosticsEngine& diagnostic_; + DiagnosticsReporter reporter_; BlinkGCPluginOptions options_; RecordCache cache_; JsonWriter* json_; }; - #endif // TOOLS_BLINK_GC_PLUGIN_BLINK_GC_PLUGIN_CONSUMER_H_ diff --git a/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h b/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h index 812d3a64eee..b941f086456 100644 --- a/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h +++ b/chromium/tools/clang/blink_gc_plugin/BlinkGCPluginOptions.h @@ -11,13 +11,9 @@ struct BlinkGCPluginOptions { BlinkGCPluginOptions() - : enable_oilpan(false), - dump_graph(false), - warn_raw_ptr(false), + : dump_graph(false), warn_unneeded_finalizer(false) {} - bool enable_oilpan; bool dump_graph; - bool warn_raw_ptr; bool warn_unneeded_finalizer; std::set<std::string> ignored_classes; std::set<std::string> checked_namespaces; diff --git a/chromium/tools/clang/blink_gc_plugin/CMakeLists.txt b/chromium/tools/clang/blink_gc_plugin/CMakeLists.txt index 60ad1e52a74..009807b4164 100644 --- a/chromium/tools/clang/blink_gc_plugin/CMakeLists.txt +++ b/chromium/tools/clang/blink_gc_plugin/CMakeLists.txt @@ -10,6 +10,7 @@ set(plugin_sources CheckTraceVisitor.cpp CollectVisitor.cpp Config.cpp + DiagnosticsReporter.cpp Edge.cpp RecordInfo.cpp) diff --git a/chromium/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp b/chromium/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp index 558637c9c19..e5d69f0b897 100644 --- a/chromium/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp +++ b/chromium/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp @@ -9,9 +9,8 @@ #include "BlinkGCPluginOptions.h" #include "RecordInfo.h" -CheckFieldsVisitor::CheckFieldsVisitor(const BlinkGCPluginOptions& options) - : options_(options), - current_(0), +CheckFieldsVisitor::CheckFieldsVisitor() + : current_(0), stack_allocated_host_(false) { } @@ -85,38 +84,19 @@ void CheckFieldsVisitor::AtValue(Value* edge) { if (!Parent() || !edge->value()->IsGCAllocated()) return; - // In transition mode, disallow OwnPtr<T>, RawPtr<T> to GC allocated T's, - // also disallow T* in stack-allocated types. - if (options_.enable_oilpan) { - if (Parent()->IsOwnPtr() || - Parent()->IsRawPtrClass() || - (stack_allocated_host_ && Parent()->IsRawPtr())) { - invalid_fields_.push_back(std::make_pair( - current_, InvalidSmartPtr(Parent()))); - return; - } - if (options_.warn_raw_ptr && Parent()->IsRawPtr()) { - if (static_cast<RawPtr*>(Parent())->HasReferenceType()) { - invalid_fields_.push_back(std::make_pair( - current_, kReferencePtrToGCManagedWarning)); - } else { - invalid_fields_.push_back(std::make_pair( - current_, kRawPtrToGCManagedWarning)); - } - } - return; - } - - if (Parent()->IsRawPtr() || Parent()->IsOwnPtr()) { + // Disallow OwnPtr<T>, RefPtr<T> and T* to stack-allocated types. + if (Parent()->IsOwnPtr() || + Parent()->IsRefPtr() || + (stack_allocated_host_ && Parent()->IsRawPtr())) { invalid_fields_.push_back(std::make_pair( current_, InvalidSmartPtr(Parent()))); return; } - - if (Parent()->IsRefPtr() && !edge->value()->IsGCRefCounted()) { - invalid_fields_.push_back(std::make_pair( - current_, InvalidSmartPtr(Parent()))); - return; + if (Parent()->IsRawPtr()) { + RawPtr* rawPtr = static_cast<RawPtr*>(Parent()); + Error error = rawPtr->HasReferenceType() ? + kReferencePtrToGCManaged : kRawPtrToGCManaged; + invalid_fields_.push_back(std::make_pair(current_, error)); } } @@ -125,24 +105,6 @@ void CheckFieldsVisitor::AtCollection(Collection* edge) { invalid_fields_.push_back(std::make_pair(current_, kOwnPtrToGCManaged)); } -bool CheckFieldsVisitor::IsWarning(Error error) { - if (error == kRawPtrToGCManagedWarning) - return true; - if (error == kReferencePtrToGCManagedWarning) - return true; - return false; -} - -bool CheckFieldsVisitor::IsRawPtrError(Error error) { - return (error == kRawPtrToGCManaged || - error == kRawPtrToGCManagedWarning); -} - -bool CheckFieldsVisitor::IsReferencePtrError(Error error) { - return (error == kReferencePtrToGCManaged || - error == kReferencePtrToGCManagedWarning); -} - CheckFieldsVisitor::Error CheckFieldsVisitor::InvalidSmartPtr(Edge* ptr) { if (ptr->IsRawPtr()) { if (static_cast<RawPtr*>(ptr)->HasReferenceType()) diff --git a/chromium/tools/clang/blink_gc_plugin/CheckFieldsVisitor.h b/chromium/tools/clang/blink_gc_plugin/CheckFieldsVisitor.h index e0c36a2d89d..4fddede3808 100644 --- a/chromium/tools/clang/blink_gc_plugin/CheckFieldsVisitor.h +++ b/chromium/tools/clang/blink_gc_plugin/CheckFieldsVisitor.h @@ -13,8 +13,8 @@ struct BlinkGCPluginOptions; class FieldPoint; // This visitor checks that the fields of a class are "well formed". -// - OwnPtr, RefPtr and RawPtr must not point to a GC derived types. -// - Part objects must not be GC derived types. +// - OwnPtr and RefPtr must not point to a GC derived type. +// - Part objects must not be a GC derived type. // - An on-heap class must never contain GC roots. // - Only stack-allocated types may point to stack-allocated types. @@ -22,10 +22,8 @@ class CheckFieldsVisitor : public RecursiveEdgeVisitor { public: enum Error { kRawPtrToGCManaged, - kRawPtrToGCManagedWarning, kRefPtrToGCManaged, kReferencePtrToGCManaged, - kReferencePtrToGCManagedWarning, kOwnPtrToGCManaged, kMemberToGCUnmanaged, kMemberInUnmanaged, @@ -33,9 +31,9 @@ class CheckFieldsVisitor : public RecursiveEdgeVisitor { kGCDerivedPartObject }; - typedef std::vector<std::pair<FieldPoint*, Error> > Errors; + using Errors = std::vector<std::pair<FieldPoint*, Error>>; - explicit CheckFieldsVisitor(const BlinkGCPluginOptions& options); + CheckFieldsVisitor(); Errors& invalid_fields(); @@ -45,14 +43,9 @@ class CheckFieldsVisitor : public RecursiveEdgeVisitor { void AtValue(Value* edge) override; void AtCollection(Collection* edge) override; - static bool IsWarning(Error error); - static bool IsRawPtrError(Error error); - static bool IsReferencePtrError(Error error); - private: Error InvalidSmartPtr(Edge* ptr); - const BlinkGCPluginOptions& options_; FieldPoint* current_; bool stack_allocated_host_; bool managed_host_; diff --git a/chromium/tools/clang/blink_gc_plugin/Config.h b/chromium/tools/clang/blink_gc_plugin/Config.h index 7ca8ea4c0f1..8d331e5581e 100644 --- a/chromium/tools/clang/blink_gc_plugin/Config.h +++ b/chromium/tools/clang/blink_gc_plugin/Config.h @@ -133,14 +133,7 @@ class Config { } static bool IsGCFinalizedBase(const std::string& name) { - return name == "GarbageCollectedFinalized" || - name == "RefCountedGarbageCollected" || - name == "ThreadSafeRefCountedGarbageCollected"; - } - - static bool IsGCRefCountedBase(const std::string& name) { - return name == "RefCountedGarbageCollected" || - name == "ThreadSafeRefCountedGarbageCollected"; + return name == "GarbageCollectedFinalized"; } static bool IsGCBase(const std::string& name) { diff --git a/chromium/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp b/chromium/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp new file mode 100644 index 00000000000..0057d80da58 --- /dev/null +++ b/chromium/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp @@ -0,0 +1,527 @@ +// Copyright 2016 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. + +#include "DiagnosticsReporter.h" + +using namespace clang; + +namespace { + +const char kClassMustLeftMostlyDeriveGC[] = + "[blink-gc] Class %0 must derive its GC base in the left-most position."; + +const char kClassRequiresTraceMethod[] = + "[blink-gc] Class %0 requires a trace method."; + +const char kBaseRequiresTracing[] = + "[blink-gc] Base class %0 of derived class %1 requires tracing."; + +const char kBaseRequiresTracingNote[] = + "[blink-gc] Untraced base class %0 declared here:"; + +const char kFieldsRequireTracing[] = + "[blink-gc] Class %0 has untraced fields that require tracing."; + +const char kFieldRequiresTracingNote[] = + "[blink-gc] Untraced field %0 declared here:"; + +const char kClassContainsInvalidFields[] = + "[blink-gc] Class %0 contains invalid fields."; + +const char kClassContainsGCRoot[] = + "[blink-gc] Class %0 contains GC root in field %1."; + +const char kClassRequiresFinalization[] = + "[blink-gc] Class %0 requires finalization."; + +const char kClassDoesNotRequireFinalization[] = + "[blink-gc] Class %0 may not require finalization."; + +const char kFinalizerAccessesFinalizedField[] = + "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; + +const char kFinalizerAccessesEagerlyFinalizedField[] = + "[blink-gc] Finalizer %0 accesses eagerly finalized field %1."; + +const char kRawPtrToGCManagedClassNote[] = + "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; + +const char kRefPtrToGCManagedClassNote[] = + "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; + +const char kReferencePtrToGCManagedClassNote[] = + "[blink-gc] Reference pointer field %0 to a GC managed class" + " declared here:"; + +const char kOwnPtrToGCManagedClassNote[] = + "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; + +const char kMemberToGCUnmanagedClassNote[] = + "[blink-gc] Member field %0 to non-GC managed class declared here:"; + +const char kStackAllocatedFieldNote[] = + "[blink-gc] Stack-allocated field %0 declared here:"; + +const char kMemberInUnmanagedClassNote[] = + "[blink-gc] Member field %0 in unmanaged class declared here:"; + +const char kPartObjectToGCDerivedClassNote[] = + "[blink-gc] Part-object field %0 to a GC derived class declared here:"; + +const char kPartObjectContainsGCRootNote[] = + "[blink-gc] Field %0 with embedded GC root in %1 declared here:"; + +const char kFieldContainsGCRootNote[] = + "[blink-gc] Field %0 defining a GC root declared here:"; + +const char kOverriddenNonVirtualTrace[] = + "[blink-gc] Class %0 overrides non-virtual trace of base class %1."; + +const char kOverriddenNonVirtualTraceNote[] = + "[blink-gc] Non-virtual trace method declared here:"; + +const char kMissingTraceDispatchMethod[] = + "[blink-gc] Class %0 is missing manual trace dispatch."; + +const char kMissingFinalizeDispatchMethod[] = + "[blink-gc] Class %0 is missing manual finalize dispatch."; + +const char kVirtualAndManualDispatch[] = + "[blink-gc] Class %0 contains or inherits virtual methods" + " but implements manual dispatching."; + +const char kMissingTraceDispatch[] = + "[blink-gc] Missing dispatch to class %0 in manual trace dispatch."; + +const char kMissingFinalizeDispatch[] = + "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch."; + +const char kFinalizedFieldNote[] = + "[blink-gc] Potentially finalized field %0 declared here:"; + +const char kEagerlyFinalizedFieldNote[] = + "[blink-gc] Field %0 having eagerly finalized value, declared here:"; + +const char kUserDeclaredDestructorNote[] = + "[blink-gc] User-declared destructor declared here:"; + +const char kUserDeclaredFinalizerNote[] = + "[blink-gc] User-declared finalizer declared here:"; + +const char kBaseRequiresFinalizationNote[] = + "[blink-gc] Base class %0 requiring finalization declared here:"; + +const char kFieldRequiresFinalizationNote[] = + "[blink-gc] Field %0 requiring finalization declared here:"; + +const char kManualDispatchMethodNote[] = + "[blink-gc] Manual dispatch %0 declared here:"; + +const char kDerivesNonStackAllocated[] = + "[blink-gc] Stack-allocated class %0 derives class %1" + " which is not stack allocated."; + +const char kClassOverridesNew[] = + "[blink-gc] Garbage collected class %0" + " is not permitted to override its new operator."; + +const char kClassDeclaresPureVirtualTrace[] = + "[blink-gc] Garbage collected class %0" + " is not permitted to declare a pure-virtual trace method."; + +const char kLeftMostBaseMustBePolymorphic[] = + "[blink-gc] Left-most base class %0 of derived class %1" + " must be polymorphic."; + +const char kBaseClassMustDeclareVirtualTrace[] = + "[blink-gc] Left-most base class %0 of derived class %1" + " must define a virtual trace method."; + +} // namespace + +DiagnosticBuilder DiagnosticsReporter::ReportDiagnostic( + SourceLocation location, + unsigned diag_id) { + SourceManager& manager = instance_.getSourceManager(); + FullSourceLoc full_loc(location, manager); + return diagnostic_.Report(full_loc, diag_id); +} + +DiagnosticsReporter::DiagnosticsReporter( + clang::CompilerInstance& instance) + : instance_(instance), + diagnostic_(instance.getDiagnostics()) +{ + // Register warning/error messages. + diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kClassMustLeftMostlyDeriveGC); + diag_class_requires_trace_method_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod); + diag_base_requires_tracing_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing); + diag_fields_require_tracing_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing); + diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kClassContainsInvalidFields); + diag_class_contains_gc_root_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); + diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kClassRequiresFinalization); + diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization); + diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kFinalizerAccessesFinalizedField); + diag_finalizer_eagerly_finalized_field_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kFinalizerAccessesEagerlyFinalizedField); + diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kOverriddenNonVirtualTrace); + diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kMissingTraceDispatchMethod); + diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kMissingFinalizeDispatchMethod); + diag_virtual_and_manual_dispatch_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); + diag_missing_trace_dispatch_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch); + diag_missing_finalize_dispatch_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kMissingFinalizeDispatch); + diag_derives_non_stack_allocated_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated); + diag_class_overrides_new_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew); + diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kClassDeclaresPureVirtualTrace); + diag_left_most_base_must_be_polymorphic_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kLeftMostBaseMustBePolymorphic); + diag_base_class_must_declare_virtual_trace_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kBaseClassMustDeclareVirtualTrace); + + // Register note messages. + diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kBaseRequiresTracingNote); + diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kFieldRequiresTracingNote); + diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); + diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); + diag_reference_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kReferencePtrToGCManagedClassNote); + diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); + diag_member_to_gc_unmanaged_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kMemberToGCUnmanagedClassNote); + diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kStackAllocatedFieldNote); + diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); + diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); + diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); + diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kFieldContainsGCRootNote); + diag_finalized_field_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kFinalizedFieldNote); + diag_eagerly_finalized_field_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kEagerlyFinalizedFieldNote); + diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kUserDeclaredDestructorNote); + diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); + diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); + diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kFieldRequiresFinalizationNote); + diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote); + diag_manual_dispatch_method_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kManualDispatchMethodNote); +} + +bool DiagnosticsReporter::hasErrorOccurred() const +{ + return diagnostic_.hasErrorOccurred(); +} + +DiagnosticsEngine::Level DiagnosticsReporter::getErrorLevel() const { + return diagnostic_.getWarningsAsErrors() ? DiagnosticsEngine::Error + : DiagnosticsEngine::Warning; +} + +void DiagnosticsReporter::ClassMustLeftMostlyDeriveGC( + RecordInfo* info) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_class_must_left_mostly_derive_gc_) + << info->record(); +} + +void DiagnosticsReporter::ClassRequiresTraceMethod(RecordInfo* info) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_class_requires_trace_method_) + << info->record(); + + for (auto& base : info->GetBases()) + if (base.second.NeedsTracing().IsNeeded()) + NoteBaseRequiresTracing(&base.second); + + for (auto& field : info->GetFields()) + if (!field.second.IsProperlyTraced()) + NoteFieldRequiresTracing(info, field.first); +} + +void DiagnosticsReporter::BaseRequiresTracing( + RecordInfo* derived, + CXXMethodDecl* trace, + CXXRecordDecl* base) { + ReportDiagnostic(trace->getLocStart(), diag_base_requires_tracing_) + << base << derived->record(); +} + +void DiagnosticsReporter::FieldsRequireTracing( + RecordInfo* info, + CXXMethodDecl* trace) { + ReportDiagnostic(trace->getLocStart(), diag_fields_require_tracing_) + << info->record(); + for (auto& field : info->GetFields()) + if (!field.second.IsProperlyTraced()) + NoteFieldRequiresTracing(info, field.first); +} + +void DiagnosticsReporter::ClassContainsInvalidFields( + RecordInfo* info, + const CheckFieldsVisitor::Errors& errors) { + + ReportDiagnostic(info->record()->getLocStart(), + diag_class_contains_invalid_fields_) + << info->record(); + + for (auto& error : errors) { + unsigned note; + if (error.second == CheckFieldsVisitor::kRawPtrToGCManaged) { + note = diag_raw_ptr_to_gc_managed_class_note_; + } else if (error.second == CheckFieldsVisitor::kRefPtrToGCManaged) { + note = diag_ref_ptr_to_gc_managed_class_note_; + } else if (error.second == CheckFieldsVisitor::kReferencePtrToGCManaged) { + note = diag_reference_ptr_to_gc_managed_class_note_; + } else if (error.second == CheckFieldsVisitor::kOwnPtrToGCManaged) { + note = diag_own_ptr_to_gc_managed_class_note_; + } else if (error.second == CheckFieldsVisitor::kMemberToGCUnmanaged) { + note = diag_member_to_gc_unmanaged_class_note_; + } else if (error.second == CheckFieldsVisitor::kMemberInUnmanaged) { + note = diag_member_in_unmanaged_class_note_; + } else if (error.second == CheckFieldsVisitor::kPtrFromHeapToStack) { + note = diag_stack_allocated_field_note_; + } else if (error.second == CheckFieldsVisitor::kGCDerivedPartObject) { + note = diag_part_object_to_gc_derived_class_note_; + } else { + assert(false && "Unknown field error"); + } + NoteField(error.first, note); + } +} + +void DiagnosticsReporter::ClassContainsGCRoots( + RecordInfo* info, + const CheckGCRootsVisitor::Errors& errors) { + for (auto& error : errors) { + FieldPoint* point = nullptr; + for (FieldPoint* path : error) { + if (!point) { + point = path; + ReportDiagnostic(info->record()->getLocStart(), + diag_class_contains_gc_root_) + << info->record() << point->field(); + continue; + } + NotePartObjectContainsGCRoot(point); + point = path; + } + NoteFieldContainsGCRoot(point); + } +} + +void DiagnosticsReporter::FinalizerAccessesFinalizedFields( + CXXMethodDecl* dtor, + const CheckFinalizerVisitor::Errors& errors) { + for (auto& error : errors) { + bool as_eagerly_finalized = error.as_eagerly_finalized; + unsigned diag_error = as_eagerly_finalized ? + diag_finalizer_eagerly_finalized_field_ : + diag_finalizer_accesses_finalized_field_; + unsigned diag_note = as_eagerly_finalized ? + diag_eagerly_finalized_field_note_ : + diag_finalized_field_note_; + ReportDiagnostic(error.member->getLocStart(), diag_error) + << dtor << error.field->field(); + NoteField(error.field, diag_note); + } +} + +void DiagnosticsReporter::ClassRequiresFinalization(RecordInfo* info) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_class_requires_finalization_) + << info->record(); +} + +void DiagnosticsReporter::ClassDoesNotRequireFinalization( + RecordInfo* info) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_class_does_not_require_finalization_) + << info->record(); +} + +void DiagnosticsReporter::OverriddenNonVirtualTrace( + RecordInfo* info, + CXXMethodDecl* trace, + CXXMethodDecl* overridden) { + ReportDiagnostic(trace->getLocStart(), diag_overridden_non_virtual_trace_) + << info->record() << overridden->getParent(); + NoteOverriddenNonVirtualTrace(overridden); +} + +void DiagnosticsReporter::MissingTraceDispatchMethod(RecordInfo* info) { + ReportMissingDispatchMethod(info, diag_missing_trace_dispatch_method_); +} + +void DiagnosticsReporter::MissingFinalizeDispatchMethod( + RecordInfo* info) { + ReportMissingDispatchMethod(info, diag_missing_finalize_dispatch_method_); +} + +void DiagnosticsReporter::ReportMissingDispatchMethod( + RecordInfo* info, + unsigned error) { + ReportDiagnostic(info->record()->getInnerLocStart(), error) + << info->record(); +} + +void DiagnosticsReporter::VirtualAndManualDispatch( + RecordInfo* info, + CXXMethodDecl* dispatch) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_virtual_and_manual_dispatch_) + << info->record(); + NoteManualDispatchMethod(dispatch); +} + +void DiagnosticsReporter::MissingTraceDispatch( + const FunctionDecl* dispatch, + RecordInfo* receiver) { + ReportMissingDispatch(dispatch, receiver, diag_missing_trace_dispatch_); +} + +void DiagnosticsReporter::MissingFinalizeDispatch( + const FunctionDecl* dispatch, + RecordInfo* receiver) { + ReportMissingDispatch(dispatch, receiver, diag_missing_finalize_dispatch_); +} + +void DiagnosticsReporter::ReportMissingDispatch( + const FunctionDecl* dispatch, + RecordInfo* receiver, + unsigned error) { + ReportDiagnostic(dispatch->getLocStart(), error) << receiver->record(); +} + +void DiagnosticsReporter::DerivesNonStackAllocated( + RecordInfo* info, + BasePoint* base) { + ReportDiagnostic(base->spec().getLocStart(), + diag_derives_non_stack_allocated_) + << info->record() << base->info()->record(); +} + +void DiagnosticsReporter::ClassOverridesNew( + RecordInfo* info, + CXXMethodDecl* newop) { + ReportDiagnostic(newop->getLocStart(), diag_class_overrides_new_) + << info->record(); +} + +void DiagnosticsReporter::ClassDeclaresPureVirtualTrace( + RecordInfo* info, + CXXMethodDecl* trace) { + ReportDiagnostic(trace->getLocStart(), + diag_class_declares_pure_virtual_trace_) + << info->record(); +} + +void DiagnosticsReporter::LeftMostBaseMustBePolymorphic( + RecordInfo* derived, + CXXRecordDecl* base) { + ReportDiagnostic(base->getLocStart(), + diag_left_most_base_must_be_polymorphic_) + << base << derived->record(); +} + +void DiagnosticsReporter::BaseClassMustDeclareVirtualTrace( + RecordInfo* derived, + CXXRecordDecl* base) { + ReportDiagnostic(base->getLocStart(), + diag_base_class_must_declare_virtual_trace_) + << base << derived->record(); +} + +void DiagnosticsReporter::NoteManualDispatchMethod(CXXMethodDecl* dispatch) { + ReportDiagnostic(dispatch->getLocStart(), + diag_manual_dispatch_method_note_) + << dispatch; +} + +void DiagnosticsReporter::NoteBaseRequiresTracing(BasePoint* base) { + ReportDiagnostic(base->spec().getLocStart(), + diag_base_requires_tracing_note_) + << base->info()->record(); +} + +void DiagnosticsReporter::NoteFieldRequiresTracing( + RecordInfo* holder, + FieldDecl* field) { + NoteField(field, diag_field_requires_tracing_note_); +} + +void DiagnosticsReporter::NotePartObjectContainsGCRoot(FieldPoint* point) { + FieldDecl* field = point->field(); + ReportDiagnostic(field->getLocStart(), + diag_part_object_contains_gc_root_note_) + << field << field->getParent(); +} + +void DiagnosticsReporter::NoteFieldContainsGCRoot(FieldPoint* point) { + NoteField(point, diag_field_contains_gc_root_note_); +} + +void DiagnosticsReporter::NoteUserDeclaredDestructor(CXXMethodDecl* dtor) { + ReportDiagnostic(dtor->getLocStart(), diag_user_declared_destructor_note_); +} + +void DiagnosticsReporter::NoteUserDeclaredFinalizer(CXXMethodDecl* dtor) { + ReportDiagnostic(dtor->getLocStart(), diag_user_declared_finalizer_note_); +} + +void DiagnosticsReporter::NoteBaseRequiresFinalization(BasePoint* base) { + ReportDiagnostic(base->spec().getLocStart(), + diag_base_requires_finalization_note_) + << base->info()->record(); +} + +void DiagnosticsReporter::NoteFieldRequiresFinalization(FieldPoint* point) { + NoteField(point, diag_field_requires_finalization_note_); +} + +void DiagnosticsReporter::NoteField(FieldPoint* point, unsigned note) { + NoteField(point->field(), note); +} + +void DiagnosticsReporter::NoteField(FieldDecl* field, unsigned note) { + ReportDiagnostic(field->getLocStart(), note) << field; +} + +void DiagnosticsReporter::NoteOverriddenNonVirtualTrace( + CXXMethodDecl* overridden) { + ReportDiagnostic(overridden->getLocStart(), + diag_overridden_non_virtual_trace_note_) + << overridden; +} diff --git a/chromium/tools/clang/blink_gc_plugin/DiagnosticsReporter.h b/chromium/tools/clang/blink_gc_plugin/DiagnosticsReporter.h new file mode 100644 index 00000000000..2f9076ec7b9 --- /dev/null +++ b/chromium/tools/clang/blink_gc_plugin/DiagnosticsReporter.h @@ -0,0 +1,137 @@ +// Copyright 2016 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. + +#ifndef TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_ +#define TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_ + +#include "CheckFieldsVisitor.h" +#include "CheckFinalizerVisitor.h" +#include "CheckGCRootsVisitor.h" +#include "Config.h" +#include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Frontend/CompilerInstance.h" + +class RecordInfo; + +// All error/warning reporting methods under one roof. +// +class DiagnosticsReporter { + public: + explicit DiagnosticsReporter(clang::CompilerInstance&); + + bool hasErrorOccurred() const; + clang::DiagnosticsEngine::Level getErrorLevel() const; + + void ClassMustLeftMostlyDeriveGC(RecordInfo* info); + void ClassRequiresTraceMethod(RecordInfo* info); + void BaseRequiresTracing(RecordInfo* derived, + clang::CXXMethodDecl* trace, + clang::CXXRecordDecl* base); + void FieldsRequireTracing(RecordInfo* info, + clang::CXXMethodDecl* trace); + void ClassContainsInvalidFields( + RecordInfo* info, + const CheckFieldsVisitor::Errors& errors); + void ClassContainsGCRoots(RecordInfo* info, + const CheckGCRootsVisitor::Errors& errors); + void FinalizerAccessesFinalizedFields( + clang::CXXMethodDecl* dtor, + const CheckFinalizerVisitor::Errors& errors); + void ClassRequiresFinalization(RecordInfo* info); + void ClassDoesNotRequireFinalization(RecordInfo* info); + void ClassMustDeclareGCMixinTraceMethod(RecordInfo* info); + void OverriddenNonVirtualTrace(RecordInfo* info, + clang::CXXMethodDecl* trace, + clang::CXXMethodDecl* overridden); + void MissingTraceDispatchMethod(RecordInfo* info); + void MissingFinalizeDispatchMethod(RecordInfo* info); + void VirtualAndManualDispatch(RecordInfo* info, + clang::CXXMethodDecl* dispatch); + void MissingTraceDispatch(const clang::FunctionDecl* dispatch, + RecordInfo* receiver); + void MissingFinalizeDispatch(const clang::FunctionDecl* dispatch, + RecordInfo* receiver); + void DerivesNonStackAllocated(RecordInfo* info, BasePoint* base); + void ClassOverridesNew(RecordInfo* info, clang::CXXMethodDecl* newop); + void ClassDeclaresPureVirtualTrace(RecordInfo* info, + clang::CXXMethodDecl* trace); + void LeftMostBaseMustBePolymorphic(RecordInfo* derived, + clang::CXXRecordDecl* base); + void BaseClassMustDeclareVirtualTrace(RecordInfo* derived, + clang::CXXRecordDecl* base); + + void NoteManualDispatchMethod(clang::CXXMethodDecl* dispatch); + void NoteBaseRequiresTracing(BasePoint* base); + void NoteFieldRequiresTracing(RecordInfo* holder, clang::FieldDecl* field); + void NotePartObjectContainsGCRoot(FieldPoint* point); + void NoteFieldContainsGCRoot(FieldPoint* point); + void NoteUserDeclaredDestructor(clang::CXXMethodDecl* dtor); + void NoteUserDeclaredFinalizer(clang::CXXMethodDecl* dtor); + void NoteBaseRequiresFinalization(BasePoint* base); + void NoteFieldRequiresFinalization(FieldPoint* field); + void NoteField(FieldPoint* point, unsigned note); + void NoteField(clang::FieldDecl* field, unsigned note); + void NoteOverriddenNonVirtualTrace(clang::CXXMethodDecl* overridden); + + private: + clang::DiagnosticBuilder ReportDiagnostic( + clang::SourceLocation location, + unsigned diag_id); + + void ReportMissingDispatchMethod(RecordInfo* info, unsigned error); + void ReportMissingDispatch(const clang::FunctionDecl* dispatch, + RecordInfo* receiver, + unsigned error); + + clang::CompilerInstance& instance_; + clang::DiagnosticsEngine& diagnostic_; + + unsigned diag_class_must_left_mostly_derive_gc_; + unsigned diag_class_requires_trace_method_; + unsigned diag_base_requires_tracing_; + unsigned diag_fields_require_tracing_; + unsigned diag_class_contains_invalid_fields_; + unsigned diag_class_contains_gc_root_; + unsigned diag_class_requires_finalization_; + unsigned diag_class_does_not_require_finalization_; + unsigned diag_finalizer_accesses_finalized_field_; + unsigned diag_finalizer_eagerly_finalized_field_; + unsigned diag_overridden_non_virtual_trace_; + unsigned diag_missing_trace_dispatch_method_; + unsigned diag_missing_finalize_dispatch_method_; + unsigned diag_virtual_and_manual_dispatch_; + unsigned diag_missing_trace_dispatch_; + unsigned diag_missing_finalize_dispatch_; + unsigned diag_derives_non_stack_allocated_; + unsigned diag_class_overrides_new_; + unsigned diag_class_declares_pure_virtual_trace_; + unsigned diag_left_most_base_must_be_polymorphic_; + unsigned diag_base_class_must_declare_virtual_trace_; + + unsigned diag_base_requires_tracing_note_; + unsigned diag_field_requires_tracing_note_; + unsigned diag_raw_ptr_to_gc_managed_class_note_; + unsigned diag_ref_ptr_to_gc_managed_class_note_; + unsigned diag_reference_ptr_to_gc_managed_class_note_; + unsigned diag_own_ptr_to_gc_managed_class_note_; + unsigned diag_member_to_gc_unmanaged_class_note_; + unsigned diag_stack_allocated_field_note_; + unsigned diag_member_in_unmanaged_class_note_; + unsigned diag_part_object_to_gc_derived_class_note_; + unsigned diag_part_object_contains_gc_root_note_; + unsigned diag_field_contains_gc_root_note_; + unsigned diag_finalized_field_note_; + unsigned diag_eagerly_finalized_field_note_; + unsigned diag_user_declared_destructor_note_; + unsigned diag_user_declared_finalizer_note_; + unsigned diag_base_requires_finalization_note_; + unsigned diag_field_requires_finalization_note_; + unsigned diag_overridden_non_virtual_trace_note_; + unsigned diag_manual_dispatch_method_note_; + +}; + +#endif // TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_ diff --git a/chromium/tools/clang/blink_gc_plugin/Edge.h b/chromium/tools/clang/blink_gc_plugin/Edge.h index eca3158d75f..91e569867d8 100644 --- a/chromium/tools/clang/blink_gc_plugin/Edge.h +++ b/chromium/tools/clang/blink_gc_plugin/Edge.h @@ -87,7 +87,6 @@ class Edge { virtual bool IsValue() { return false; } virtual bool IsRawPtr() { return false; } - virtual bool IsRawPtrClass() { return false; } virtual bool IsRefPtr() { return false; } virtual bool IsOwnPtr() { return false; } virtual bool IsMember() { return false; } @@ -126,16 +125,13 @@ class PtrEdge : public Edge { class RawPtr : public PtrEdge { public: - RawPtr(Edge* ptr, bool is_ptr_class, bool is_ref_type) + RawPtr(Edge* ptr, bool is_ref_type) : PtrEdge(ptr) - , is_ptr_class_(is_ptr_class) , is_ref_type_(is_ref_type) { - assert(!(is_ptr_class_ && is_ref_type_)); } bool IsRawPtr() { return true; } - bool IsRawPtrClass() { return is_ptr_class_; } LivenessKind Kind() { return kWeak; } bool NeedsFinalization() { return false; } TracingStatus NeedsTracing(NeedsTracingOption) { @@ -145,7 +141,6 @@ class RawPtr : public PtrEdge { bool HasReferenceType() { return is_ref_type_; } private: - bool is_ptr_class_; bool is_ref_type_; }; diff --git a/chromium/tools/clang/blink_gc_plugin/OWNERS b/chromium/tools/clang/blink_gc_plugin/OWNERS index 9c24a9651d6..789d7efaaaa 100644 --- a/chromium/tools/clang/blink_gc_plugin/OWNERS +++ b/chromium/tools/clang/blink_gc_plugin/OWNERS @@ -1,5 +1,4 @@ -ager@chromium.org haraken@chromium.org kouhei@chromium.org tkent@chromium.org -zerny@chromium.org +sigbjornf@opera.com diff --git a/chromium/tools/clang/blink_gc_plugin/RecordInfo.cpp b/chromium/tools/clang/blink_gc_plugin/RecordInfo.cpp index b4937abd20f..f0e2ade715b 100644 --- a/chromium/tools/clang/blink_gc_plugin/RecordInfo.cpp +++ b/chromium/tools/clang/blink_gc_plugin/RecordInfo.cpp @@ -186,16 +186,6 @@ bool RecordInfo::IsEagerlyFinalized() { return is_eagerly_finalized_; } -bool RecordInfo::IsGCRefCounted() { - if (!IsGCDerived()) - return false; - for (const auto& gc_base : gc_base_names_) { - if (Config::IsGCRefCountedBase(gc_base)) - return true; - } - return false; -} - bool RecordInfo::HasDefinition() { return record_->hasDefinition(); } @@ -584,7 +574,7 @@ Edge* RecordInfo::CreateEdge(const Type* type) { if (type->isPointerType() || type->isReferenceType()) { if (Edge* ptr = CreateEdge(type->getPointeeType().getTypePtrOrNull())) - return new RawPtr(ptr, false, type->isReferenceType()); + return new RawPtr(ptr, type->isReferenceType()); return 0; } @@ -597,12 +587,6 @@ Edge* RecordInfo::CreateEdge(const Type* type) { TemplateArgs args; - if (Config::IsRawPtr(info->name()) && info->GetTemplateArgs(1, &args)) { - if (Edge* ptr = CreateEdge(args[0])) - return new RawPtr(ptr, true, false); - return 0; - } - if (Config::IsRefPtr(info->name()) && info->GetTemplateArgs(1, &args)) { if (Edge* ptr = CreateEdge(args[0])) return new RefPtr(ptr); diff --git a/chromium/tools/clang/blink_gc_plugin/RecordInfo.h b/chromium/tools/clang/blink_gc_plugin/RecordInfo.h index b294ffe03b6..39c13f01c6d 100644 --- a/chromium/tools/clang/blink_gc_plugin/RecordInfo.h +++ b/chromium/tools/clang/blink_gc_plugin/RecordInfo.h @@ -101,7 +101,6 @@ class RecordInfo { bool IsNonNewable(); bool IsOnlyPlacementNewable(); bool IsEagerlyFinalized(); - bool IsGCRefCounted(); bool HasDefinition(); diff --git a/chromium/tools/clang/scripts/blink_gc_plugin_flags.py b/chromium/tools/clang/scripts/blink_gc_plugin_flags.py index 0b3e82ba86a..c2b8762bcb7 100755 --- a/chromium/tools/clang/scripts/blink_gc_plugin_flags.py +++ b/chromium/tools/clang/scripts/blink_gc_plugin_flags.py @@ -16,26 +16,14 @@ CLANG_LIB_PATH = os.path.normpath(os.path.join( FLAGS = '-Xclang -add-plugin -Xclang blink-gc-plugin' PREFIX= ' -Xclang -plugin-arg-blink-gc-plugin -Xclang ' -warn_raw_pointers = None for arg in sys.argv[1:]: - if arg == 'enable-oilpan=1': - FLAGS += PREFIX + 'enable-oilpan' - if warn_raw_pointers is None: - warn_raw_pointers = True - elif arg == 'dump-graph=1': + if arg == 'dump-graph=1': FLAGS += PREFIX + 'dump-graph' - elif arg == 'warn-raw-ptr=1': - warn_raw_pointers = True - elif arg == 'warn-raw-ptr=0': - warn_raw_pointers = False elif arg == 'warn-unneeded-finalizer=1': FLAGS += PREFIX + 'warn-unneeded-finalizer' elif arg.startswith('custom_clang_lib_path='): CLANG_LIB_PATH = arg[len('custom_clang_lib_path='):] -if warn_raw_pointers is True: - FLAGS += PREFIX + 'warn-raw-ptr' - if not sys.platform in ['win32', 'cygwin']: LIBSUFFIX = 'dylib' if sys.platform == 'darwin' else 'so' FLAGS = ('-Xclang -load -Xclang "%s/libBlinkGCPlugin.%s" ' + FLAGS) % \ diff --git a/chromium/tools/clang/scripts/update.py b/chromium/tools/clang/scripts/update.py index 0abb42af058..baac014965a 100755 --- a/chromium/tools/clang/scripts/update.py +++ b/chromium/tools/clang/scripts/update.py @@ -23,10 +23,11 @@ import time import urllib2 import zipfile + # Do NOT CHANGE this if you don't know what you're doing -- see # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md # Reverting problematic clang rolls is safe, though. -CLANG_REVISION = '264915' +CLANG_REVISION = '269902' use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ if use_head_revision: @@ -82,6 +83,12 @@ LLVM_REPO_URL='https://llvm.org/svn/llvm-project' if 'LLVM_REPO_URL' in os.environ: LLVM_REPO_URL = os.environ['LLVM_REPO_URL'] +# Bump after VC updates. +DIA_DLL = { + '2013': 'msdia120.dll', + '2015': 'msdia140.dll', +} + def DownloadUrl(url, output_file): """Download url into output_file.""" @@ -160,6 +167,14 @@ def WriteStampFile(s, path=STAMP_FILE): def GetSvnRevision(svn_repo): """Returns current revision of the svn repo at svn_repo.""" + if sys.platform == 'darwin': + # mac_files toolchain must be set for hermetic builds. + root = os.path.dirname(os.path.dirname(os.path.dirname( + os.path.dirname(__file__)))) + sys.path.append(os.path.join(root, 'build')) + import mac_toolchain + + mac_toolchain.SetToolchainEnvironment() svn_info = subprocess.check_output('svn info ' + svn_repo, shell=True) m = re.search(r'Revision: (\d+)', svn_info) return m.group(1) @@ -220,8 +235,8 @@ def RunCommand(command, msvc_arch=None, env=None, fail_hard=True): def CopyFile(src, dst): """Copy a file from src to dst.""" - shutil.copy(src, dst) print "Copying %s to %s" % (src, dst) + shutil.copy(src, dst) def CopyDirectoryContents(src, dst, filename_filter=None): @@ -300,13 +315,13 @@ def DownloadHostGcc(args): def AddCMakeToPath(): """Download CMake and add it to PATH.""" if sys.platform == 'win32': - zip_name = 'cmake-3.2.2-win32-x86.zip' + zip_name = 'cmake-3.4.3-win32-x86.zip' cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, - 'cmake-3.2.2-win32-x86', 'bin') + 'cmake-3.4.3-win32-x86', 'bin') else: suffix = 'Darwin' if sys.platform == 'darwin' else 'Linux' - zip_name = 'cmake322_%s.tgz' % suffix - cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake322', 'bin') + zip_name = 'cmake343_%s.tgz' % suffix + cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake343', 'bin') if not os.path.exists(cmake_dir): DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR) os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '') @@ -318,7 +333,7 @@ def AddGnuWinToPath(): return gnuwin_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gnuwin') - GNUWIN_VERSION = '1' + GNUWIN_VERSION = '4' GNUWIN_STAMP = os.path.join(gnuwin_dir, 'stamp') if ReadStampFile(GNUWIN_STAMP) == GNUWIN_VERSION: print 'GNU Win tools already up to date.' @@ -351,6 +366,13 @@ def GetVSVersion(): return vs_version +def CopyDiaDllTo(target_dir): + # This script always wants to use the 64-bit msdia*.dll. + dia_path = os.path.join(GetVSVersion().Path(), 'DIA SDK', 'bin', 'amd64') + dia_dll = os.path.join(dia_path, DIA_DLL[GetVSVersion().ShortName()]) + CopyFile(dia_dll, target_dir) + + def UpdateClang(args): print 'Updating Clang to %s...' % PACKAGE_VERSION @@ -384,6 +406,8 @@ def UpdateClang(args): try: DownloadAndUnpack(cds_full_url, LLVM_BUILD_DIR) print 'clang %s unpacked' % PACKAGE_VERSION + if sys.platform == 'win32': + CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin')) # Download the gold plugin if requested to by an environment variable. # This is used by the CFI ClusterFuzz bot, and it's required for official # builds on linux. @@ -413,7 +437,7 @@ def UpdateClang(args): Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) - if sys.platform == 'win32': + if sys.platform == 'win32' or use_head_revision: Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR) if sys.platform == 'darwin': @@ -476,6 +500,8 @@ def UpdateClang(args): RunCommand(['cmake'] + bootstrap_args + [LLVM_DIR], msvc_arch='x64') RunCommand(['ninja'], msvc_arch='x64') if args.run_tests: + if sys.platform == 'win32': + CopyDiaDllTo(os.path.join(LLVM_BOOTSTRAP_DIR, 'bin')) RunCommand(['ninja', 'check-all'], msvc_arch='x64') RunCommand(['ninja', 'install'], msvc_arch='x64') if args.gcc_toolchain: @@ -584,7 +610,6 @@ def UpdateClang(args): if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx) cmake_args += base_cmake_args + [ '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir, - '-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly', '-DCMAKE_C_FLAGS=' + ' '.join(cflags), '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags), '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags), @@ -608,8 +633,7 @@ def UpdateClang(args): [cxx] + cxxflags + ['-print-file-name=libstdc++.so.6']).rstrip() CopyFile(libstdcpp, os.path.join(LLVM_BUILD_DIR, 'lib')) - # TODO(thakis): Remove "-d explain" once http://crbug.com/569337 is fixed. - RunCommand(['ninja', '-d', 'explain'], msvc_arch='x64') + RunCommand(['ninja'], msvc_arch='x64') if args.tools: # If any Chromium tools were built, install those now. @@ -760,6 +784,8 @@ def UpdateClang(args): os.chdir(LLVM_BUILD_DIR) RunCommand(['ninja', 'cr-check-all'], msvc_arch='x64') if args.run_tests: + if sys.platform == 'win32': + CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin')) os.chdir(LLVM_BUILD_DIR) RunCommand(['ninja', 'check-all'], msvc_arch='x64') @@ -781,6 +807,9 @@ def main(): 'picks /opt/foo/bin/gcc') parser.add_argument('--lto-gold-plugin', action='store_true', help='build LLVM Gold plugin with LTO') + parser.add_argument('--llvm-force-head-revision', action='store_true', + help=('use the revision in the repo when printing ' + 'the revision')) parser.add_argument('--print-revision', action='store_true', help='print current clang revision and exit.') parser.add_argument('--print-clang-version', action='store_true', @@ -824,7 +853,7 @@ def main(): global CLANG_REVISION, PACKAGE_VERSION if args.print_revision: - if use_head_revision: + if use_head_revision or args.llvm_force_head_revision: print GetSvnRevision(LLVM_DIR) else: print PACKAGE_VERSION diff --git a/chromium/tools/copyright_scanner/third_party_files_whitelist.txt b/chromium/tools/copyright_scanner/third_party_files_whitelist.txt index 43fc3311682..91def8082e7 100644 --- a/chromium/tools/copyright_scanner/third_party_files_whitelist.txt +++ b/chromium/tools/copyright_scanner/third_party_files_whitelist.txt @@ -174,9 +174,6 @@ net/http/md4.h # third-party code is taken from Mozilla, the license for which we already pick # up from third_party/npapi/. net/proxy/proxy_resolver_script.h -# Copyright The Chromium Authors and Netscape Communications Corporation; BSD -# and (MPL, GPL v2 or LGPL v2) licenses. Not used on Android. -net/socket/ssl_client_socket_nss.cc # Contains the word 'Copyright' in comments ppapi/generators/idl_c_proto.py ppapi/generators/idl_outfile.py diff --git a/chromium/tools/cygprofile/cygprofile.cc b/chromium/tools/cygprofile/cygprofile.cc index d699c3e355b..c7f12e8b49f 100644 --- a/chromium/tools/cygprofile/cygprofile.cc +++ b/chromium/tools/cygprofile/cygprofile.cc @@ -51,7 +51,27 @@ const char kLogFilenameFormat[] = "%scyglog.%d.%d-%d"; ThreadLog* const kMagicBeingConstructed = reinterpret_cast<ThreadLog*>(1); // Per-thread pointer to the current log object. -static __thread ThreadLog* g_tls_log = NULL; +pthread_key_t g_tls_slot; + +// Used to initialize the tls slot, once per the entire process. +pthread_once_t g_tls_slot_initializer_once = PTHREAD_ONCE_INIT; + +// This variable is to prevent re-entrancy in the __cyg_profile_func_enter() +// while the TLS slot itself is being initialized. Volatile here is required +// to avoid compiler optimizations as this need to be read in a re-entrant way. +// This variable is written by one thread only, which is the first thread that +// happens to run the TLSSlotInitializer(). In practice this will happen very +// early in the startup process, as soon as the first instrumented function is +// called. +volatile bool g_tls_slot_being_initialized = false; + +// Initializes the global TLS slot. This is invoked only once per process. +static void TLSSlotInitializer() +{ + g_tls_slot_being_initialized = true; + PCHECK(0 == pthread_key_create(&g_tls_slot, NULL)); + g_tls_slot_being_initialized = false; +} // Returns light-weight process ID. On Linux, this is a system-wide unique // thread id. @@ -151,11 +171,11 @@ class Thread { public: Thread(const base::Closure& thread_callback) : thread_callback_(thread_callback) { - CHECK_EQ(0, pthread_create(&handle_, NULL, &Thread::EntryPoint, this)); + PCHECK(0 == pthread_create(&handle_, NULL, &Thread::EntryPoint, this)); } ~Thread() { - CHECK_EQ(0, pthread_join(handle_, NULL)); + PCHECK(0 == pthread_join(handle_, NULL)); } private: @@ -163,8 +183,11 @@ class Thread { // Disable logging on this thread. Although this routine is not instrumented // (cygprofile.gyp provides that), the called routines are and thus will // call instrumentation. - CHECK(g_tls_log == NULL); // Must be 0 as this is a new thread. - g_tls_log = kMagicBeingConstructed; + pthread_once(&g_tls_slot_initializer_once, TLSSlotInitializer); + ThreadLog* thread_log = reinterpret_cast<ThreadLog*>( + pthread_getspecific(g_tls_slot)); + CHECK(thread_log == NULL); // Must be 0 as this is a new thread. + PCHECK(0 == pthread_setspecific(g_tls_slot, kMagicBeingConstructed)); Thread* const instance = reinterpret_cast<Thread*>(data); instance->thread_callback_.Run(); @@ -199,7 +222,7 @@ ThreadLog::ThreadLog(const FlushCallback& flush_callback) } ThreadLog::~ThreadLog() { - g_tls_log = NULL; + PCHECK(0 == pthread_setspecific(g_tls_slot, NULL)); } void ThreadLog::AddEntry(void* address) { @@ -358,16 +381,24 @@ void __cyg_profile_func_exit(void* this_fn, void* call_site) __attribute__((no_instrument_function)); void __cyg_profile_func_enter(void* this_fn, void* callee_unused) { - if (g_tls_log == NULL) { - g_tls_log = kMagicBeingConstructed; - ThreadLog* new_log = new ThreadLog(); - CHECK(new_log); - g_logs_manager.Pointer()->AddLog(base::WrapUnique(new_log)); - g_tls_log = new_log; + // Avoid re-entrancy while initializing the TLS slot (once per process). + if (g_tls_slot_being_initialized) + return; + + pthread_once(&g_tls_slot_initializer_once, TLSSlotInitializer); + ThreadLog* thread_log = reinterpret_cast<ThreadLog*>( + pthread_getspecific(g_tls_slot)); + + if (thread_log == NULL) { + PCHECK(0 == pthread_setspecific(g_tls_slot, kMagicBeingConstructed)); + thread_log = new ThreadLog(); + CHECK(thread_log); + g_logs_manager.Pointer()->AddLog(base::WrapUnique(thread_log)); + PCHECK(0 == pthread_setspecific(g_tls_slot, thread_log)); } - if (g_tls_log != kMagicBeingConstructed) - g_tls_log->AddEntry(this_fn); + if (thread_log != kMagicBeingConstructed) + thread_log->AddEntry(this_fn); } void __cyg_profile_func_exit(void* this_fn, void* call_site) {} diff --git a/chromium/tools/export_tarball/export_tarball.py b/chromium/tools/export_tarball/export_tarball.py deleted file mode 100755 index 876b3d89d35..00000000000 --- a/chromium/tools/export_tarball/export_tarball.py +++ /dev/null @@ -1,197 +0,0 @@ -#!/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. - -""" -This tool creates a tarball with all the sources, but without .svn directories. - -It can also remove files which are not strictly required for build, so that -the resulting tarball can be reasonably small (last time it was ~110 MB). - -Example usage: - -export_tarball.py /foo/bar - -The above will create file /foo/bar.tar.bz2. -""" - -import optparse -import os -import subprocess -import sys -import tarfile - - -NONESSENTIAL_DIRS = ( - 'breakpad/src/processor/testdata', - 'chrome/browser/resources/tracing/tests', - 'chrome/common/extensions/docs', - 'courgette/testdata', - 'data', - 'native_client/src/trusted/service_runtime/testdata', - 'src/chrome/test/data', - 'o3d/documentation', - 'o3d/samples', - 'o3d/tests', - 'ppapi/examples', - 'ppapi/native_client/tests', - 'third_party/angle/samples/gles2_book', - 'third_party/findbugs', - 'third_party/hunspell_dictionaries', - 'third_party/hunspell/tests', - 'third_party/lighttpd', - 'third_party/sqlite/src/test', - 'third_party/sqlite/test', - 'third_party/vc_80', - 'third_party/xdg-utils/tests', - 'third_party/yasm/source/patched-yasm/modules/arch/x86/tests', - 'third_party/yasm/source/patched-yasm/modules/dbgfmts/dwarf2/tests', - 'third_party/yasm/source/patched-yasm/modules/objfmts/bin/tests', - 'third_party/yasm/source/patched-yasm/modules/objfmts/coff/tests', - 'third_party/yasm/source/patched-yasm/modules/objfmts/elf/tests', - 'third_party/yasm/source/patched-yasm/modules/objfmts/macho/tests', - 'third_party/yasm/source/patched-yasm/modules/objfmts/rdf/tests', - 'third_party/yasm/source/patched-yasm/modules/objfmts/win32/tests', - 'third_party/yasm/source/patched-yasm/modules/objfmts/win64/tests', - 'third_party/yasm/source/patched-yasm/modules/objfmts/xdf/tests', - 'third_party/WebKit/LayoutTests', - 'third_party/WebKit/Source/JavaScriptCore/tests', - 'third_party/WebKit/Source/WebCore/ChangeLog', - 'third_party/WebKit/Source/WebKit2', - 'third_party/WebKit/Tools/Scripts', - 'tools/gyp/test', - 'v8/test', - 'webkit/data/layout_tests', - 'webkit/tools/test/reference_build', -) - -TESTDIRS = ( - 'chrome/test/data', - 'content/test/data', - 'media/test/data', - 'net/data', -) - - -def GetSourceDirectory(): - return os.path.realpath( - os.path.join(os.path.dirname(__file__), '..', '..', '..', 'src')) - - -# Workaround lack of the exclude parameter in add method in python-2.4. -# TODO(phajdan.jr): remove the workaround when it's not needed on the bot. -class MyTarFile(tarfile.TarFile): - def set_remove_nonessential_files(self, remove): - self.__remove_nonessential_files = remove - - def set_verbose(self, verbose): - self.__verbose = verbose - - def __report_skipped(self, name): - if self.__verbose: - print 'D\t%s' % name - - def __report_added(self, name): - if self.__verbose: - print 'A\t%s' % name - - def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): - head, tail = os.path.split(name) - if tail in ('.svn', '.git'): - self.__report_skipped(name) - return - - if self.__remove_nonessential_files: - # WebKit change logs take quite a lot of space. This saves ~10 MB - # in a bzip2-compressed tarball. - if 'ChangeLog' in name: - self.__report_skipped(name) - return - - # Remove contents of non-essential directories, but preserve gyp files, - # so that build/gyp_chromium can work. - for nonessential_dir in (NONESSENTIAL_DIRS + TESTDIRS): - dir_path = os.path.join(GetSourceDirectory(), nonessential_dir) - if (name.startswith(dir_path) and - os.path.isfile(name) and - 'gyp' not in name): - self.__report_skipped(name) - return - - self.__report_added(name) - tarfile.TarFile.add(self, name, arcname=arcname, recursive=recursive) - - -def main(argv): - parser = optparse.OptionParser() - parser.add_option("--basename") - parser.add_option("--remove-nonessential-files", - dest="remove_nonessential_files", - action="store_true", default=False) - parser.add_option("--test-data", action="store_true") - # TODO(phajdan.jr): Remove --xz option when it's not needed for compatibility. - parser.add_option("--xz", action="store_true") - parser.add_option("--verbose", action="store_true", default=False) - parser.add_option("--progress", action="store_true", default=False) - - options, args = parser.parse_args(argv) - - if len(args) != 1: - print 'You must provide only one argument: output file name' - print '(without .tar.xz extension).' - return 1 - - if not os.path.exists(GetSourceDirectory()): - print 'Cannot find the src directory ' + GetSourceDirectory() - return 1 - - # These two commands are from src/DEPS; please keep them in sync. - if subprocess.call(['python', 'build/util/lastchange.py', '-o', - 'build/util/LASTCHANGE'], cwd=GetSourceDirectory()) != 0: - print 'Could not run build/util/lastchange.py to update LASTCHANGE.' - return 1 - if subprocess.call(['python', 'build/util/lastchange.py', '-s', - 'third_party/WebKit', '-o', - 'build/util/LASTCHANGE.blink'], - cwd=GetSourceDirectory()) != 0: - print 'Could not run build/util/lastchange.py to update LASTCHANGE.blink.' - return 1 - - output_fullname = args[0] + '.tar' - output_basename = options.basename or os.path.basename(args[0]) - - archive = MyTarFile.open(output_fullname, 'w') - archive.set_remove_nonessential_files(options.remove_nonessential_files) - archive.set_verbose(options.verbose) - try: - if options.test_data: - for directory in TESTDIRS: - archive.add(os.path.join(GetSourceDirectory(), directory), - arcname=os.path.join(output_basename, directory)) - else: - archive.add(GetSourceDirectory(), arcname=output_basename) - finally: - archive.close() - - if options.progress: - sys.stdout.flush() - pv = subprocess.Popen( - ['pv', '--force', output_fullname], - stdout=subprocess.PIPE, - stderr=sys.stdout) - with open(output_fullname + '.xz', 'w') as f: - rc = subprocess.call(['xz', '-9', '-'], stdin=pv.stdout, stdout=f) - pv.wait() - else: - rc = subprocess.call(['xz', '-9', output_fullname]) - - if rc != 0: - print 'xz -9 failed!' - return 1 - - return 0 - - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/chromium/tools/export_tarball/export_v8_tarball.py b/chromium/tools/export_tarball/export_v8_tarball.py deleted file mode 100755 index b232c0aee73..00000000000 --- a/chromium/tools/export_tarball/export_v8_tarball.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2011 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. - -"""Creates a tarball with V8 sources, but without .svn directories. - -This allows easy packaging of V8, synchronized with browser releases. - -Example usage: - -export_v8_tarball.py /foo/bar - -The above will create file /foo/bar/v8-VERSION.tar.bz2 if it doesn't exist. -""" - -import optparse -import os -import re -import subprocess -import sys -import tarfile - -_V8_MAJOR_VERSION_PATTERN = re.compile(r'#define\s+MAJOR_VERSION\s+(.*)') -_V8_MINOR_VERSION_PATTERN = re.compile(r'#define\s+MINOR_VERSION\s+(.*)') -_V8_BUILD_NUMBER_PATTERN = re.compile(r'#define\s+BUILD_NUMBER\s+(.*)') -_V8_PATCH_LEVEL_PATTERN = re.compile(r'#define\s+PATCH_LEVEL\s+(.*)') - -_V8_PATTERNS = [ - _V8_MAJOR_VERSION_PATTERN, - _V8_MINOR_VERSION_PATTERN, - _V8_BUILD_NUMBER_PATTERN, - _V8_PATCH_LEVEL_PATTERN] - -_NONESSENTIAL_DIRS = ( - 'third_party/icu', -) - - -def GetV8Version(v8_directory): - """ - Returns version number as string based on the string - contents of version.cc file. - """ - with open(os.path.join(v8_directory, 'src', 'version.cc')) as version_file: - version_contents = version_file.read() - - version_components = [] - for pattern in _V8_PATTERNS: - version_components.append(pattern.search(version_contents).group(1).strip()) - - if version_components[len(version_components) - 1] == '0': - version_components.pop() - - return '.'.join(version_components) - - -def GetSourceDirectory(): - return os.path.realpath( - os.path.join(os.path.dirname(__file__), '..', '..', '..', 'src')) - - -def GetV8Directory(): - return os.path.join(GetSourceDirectory(), 'v8') - - -# Workaround lack of the exclude parameter in add method in python-2.4. -# TODO(phajdan.jr): remove the workaround when it's not needed on the bot. -class MyTarFile(tarfile.TarFile): - def set_remove_nonessential_files(self, remove): - self.__remove_nonessential_files = remove - - def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): - head, tail = os.path.split(name) - if tail in ('.svn', '.git'): - return - - if self.__remove_nonessential_files: - # Remove contents of non-essential directories, but preserve gyp files, - # so that build/gyp_chromium can work. - for nonessential_dir in _NONESSENTIAL_DIRS: - dir_path = os.path.join(GetV8Directory(), nonessential_dir) - if (name.startswith(dir_path) and - os.path.isfile(name) and - 'gyp' not in name): - return - - tarfile.TarFile.add(self, name, arcname=arcname, recursive=recursive) - - -def main(argv): - parser = optparse.OptionParser() - options, args = parser.parse_args(argv) - - if len(args) != 1: - print 'You must provide only one argument: output file directory' - return 1 - - v8_directory = GetV8Directory() - if not os.path.exists(v8_directory): - print 'Cannot find the v8 directory.' - return 1 - - v8_version = GetV8Version(v8_directory) - print 'Packaging V8 version %s...' % v8_version - - subprocess.check_call(["make", "dependencies"], cwd=v8_directory) - - output_basename = 'v8-%s' % v8_version - - # Package full tarball. - output_fullname = os.path.join(args[0], output_basename + '.tar.bz2') - if not os.path.exists(output_fullname): - archive = MyTarFile.open(output_fullname, 'w:bz2') - archive.set_remove_nonessential_files(False) - try: - archive.add(v8_directory, arcname=output_basename) - finally: - archive.close() - - # Package lite tarball. - output_fullname = os.path.join(args[0], output_basename + '-lite.tar.bz2') - if not os.path.exists(output_fullname): - archive = MyTarFile.open(output_fullname, 'w:bz2') - archive.set_remove_nonessential_files(True) - try: - archive.add(v8_directory, arcname=output_basename) - finally: - archive.close() - - return 0 - - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:])) diff --git a/chromium/tools/findit/OWNERS b/chromium/tools/findit/OWNERS deleted file mode 100644 index 947f12e8524..00000000000 --- a/chromium/tools/findit/OWNERS +++ /dev/null @@ -1 +0,0 @@ -stgao@chromium.org diff --git a/chromium/tools/findit/blame.py b/chromium/tools/findit/blame.py deleted file mode 100644 index 5e5494e6cd5..00000000000 --- a/chromium/tools/findit/blame.py +++ /dev/null @@ -1,165 +0,0 @@ -# Copyright (c) 2014 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. - -from threading import Lock - -from common import utils -import crash_utils - - -class Blame(object): - """Represents a blame object. - - The object contains blame information for one line of stack, and this - information is shown when there are no CLs that change the crashing files. - Attributes: - line_content: The content of the line to find the blame for. - component_name: The name of the component for this line. - stack_frame_index: The stack frame index of this file. - file_name: The name of the file. - line_number: The line that caused a crash. - author: The author of this line on the latest revision. - revision: The latest revision of this line before the crash revision. - message: The commit message for the revision. - time: When the revision was committed. - url: The url of the change for the revision. - range_start: The starting range of the regression for this component. - range_end: The ending range of the regression. - - """ - - def __init__(self, line_content, component_name, stack_frame_index, - file_name, line_number, author, revision, message, time, - url, range_start, range_end): - # Set all the variables from the arguments. - self.line_content = line_content - self.component_name = component_name - self.stack_frame_index = stack_frame_index - self.file = file_name - self.line_number = line_number - self.author = author - self.revision = revision - self.message = message - self.time = time - self.url = url - self.range_start = range_start - self.range_end = range_end - - -class BlameList(object): - """Represents a list of blame objects. - - Thread-safe. - """ - - def __init__(self): - self.blame_list = [] - self.blame_list_lock = Lock() - - def __getitem__(self, index): - return self.blame_list[index] - - def FindBlame(self, callstack, component_to_crash_revision_dict, - component_to_regression_dict, parsers, - top_n_frames=10): - """Given a stack within a stacktrace, retrieves blame information. - - Only either first 'top_n_frames' or the length of stack, whichever is - shorter, results are returned. The default value of 'top_n_frames' is 10. - - Args: - callstack: The list of stack frames. - component_to_crash_revision_dict: A dictionary that maps component to its - crash revision. - component_to_regression_dict: A dictionary that maps component to its - revision range. - parsers: A list of two parsers, svn_parser and git_parser - top_n_frames: A number of stack frames to show the blame result for. - """ - # Only return blame information for first 'top_n_frames' frames. - stack_frames = callstack.GetTopNFrames(top_n_frames) - tasks = [] - # Iterate through frames in stack. - for stack_frame in stack_frames: - # If the component this line is from does not have a crash revision, - # it is not possible to get blame information, so ignore this line. - component_path = stack_frame.component_path - if component_path not in component_to_crash_revision_dict: - continue - - crash_revision = component_to_crash_revision_dict[ - component_path]['revision'] - range_start = None - range_end = None - repository_type = crash_utils.GetRepositoryType(crash_revision) - repository_parser = parsers[repository_type] - - # If the revision is in SVN, and if regression information is available, - # get it. For Git, we cannot know the ordering between hash numbers. - if repository_type == 'svn': - if component_to_regression_dict and \ - component_path in component_to_regression_dict: - component_object = component_to_regression_dict[component_path] - range_start = int(component_object['old_revision']) - range_end = int(component_object['new_revision']) - - # Create a task to generate blame entry. - tasks.append({ - 'function': self.__GenerateBlameEntry, - 'args': [repository_parser, stack_frame, crash_revision, - range_start, range_end]}) - - # Run all the tasks. - crash_utils.RunTasks(tasks) - - def __GenerateBlameEntry(self, repository_parser, stack_frame, - crash_revision, range_start, range_end): - """Generates blame list from the arguments.""" - stack_frame_index = stack_frame.index - component_path = stack_frame.component_path - component_name = stack_frame.component_name - file_name = stack_frame.file_name - file_path = stack_frame.file_path - crashed_line_number = stack_frame.crashed_line_range[0] - - if file_path.startswith(component_path): - file_path = file_path[len(component_path):] - - # Parse blame information. - parsed_blame_info = repository_parser.ParseBlameInfo( - component_path, file_path, crashed_line_number, crash_revision) - - # If it fails to retrieve information, do not do anything. - if not parsed_blame_info: - return - - # Create blame object from the parsed info and add it to the list. - (line_content, revision, author, url, message, time) = parsed_blame_info - blame = Blame(line_content, component_name, stack_frame_index, file_name, - crashed_line_number, author, revision, message, time, url, - range_start, range_end) - - with self.blame_list_lock: - self.blame_list.append(blame) - - def FilterAndSortBlameList(self): - """Filters and sorts the blame list.""" - # Sort the blame list by its position in stack. - self.blame_list.sort(key=lambda blame: blame.stack_frame_index) - - filtered_blame_list = [] - - for blame in self.blame_list: - # If regression information is available, check if it needs to be - # filtered. - if blame.range_start and blame.range_end: - - # Discards results that are after the end of regression. - if not utils.IsGitHash(blame.revision) and ( - int(blame.range_end) <= int(blame.revision)): - continue - - filtered_blame_list.append(blame) - - self.blame_list = filtered_blame_list diff --git a/chromium/tools/findit/chromium_deps.py b/chromium/tools/findit/chromium_deps.py deleted file mode 100644 index 46436cbc7e0..00000000000 --- a/chromium/tools/findit/chromium_deps.py +++ /dev/null @@ -1,240 +0,0 @@ -# Copyright (c) 2014 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. - -import base64 -import json -import os -import re -import time -import urllib2 - -from common import utils - - -_THIS_DIR = os.path.abspath(os.path.dirname(__file__)) -CONFIG = json.loads(open(os.path.join(_THIS_DIR, - 'deps_config.json'), 'r').read()) -OLD_GIT_URL_PATTERN = re.compile(r'https?://git.chromium.org/(.*)') - - -class _VarImpl(object): - - def __init__(self, local_scope): - self._local_scope = local_scope - - def Lookup(self, var_name): - if var_name in self._local_scope.get('vars', {}): - return self._local_scope['vars'][var_name] - raise Exception('Var is not defined: %s' % var_name) - - -def _ParseDEPS(content): - """Parse the DEPS file of chromium.""" - local_scope = {} - var = _VarImpl(local_scope) - global_scope = { - 'Var': var.Lookup, - 'deps': {}, - 'deps_os': {}, - 'include_rules': [], - 'skip_child_includes': [], - 'hooks': [], - } - exec(content, global_scope, local_scope) - - local_scope.setdefault('deps', {}) - local_scope.setdefault('deps_os', {}) - - return (local_scope['deps'], local_scope['deps_os']) - - -def _GetComponentName(path, host_dirs): - """Return the component name of a path.""" - components_renamed = { - 'webkit': 'blink', - } - - for host_dir in host_dirs: - if path.startswith(host_dir): - path = path[len(host_dir):] - name = path.split('/')[0].lower() - if name in components_renamed: - return components_renamed[name].lower() - else: - return name.lower() - - # Unknown path, return the whole path as component name. - return '_'.join(path.split('/')) - - -def _GetContentOfDEPS(revision): - chromium_git_file_url_template = CONFIG['chromium_git_file_url'] - - # Try .DEPS.git first, because before migration from SVN to GIT, the .DEPS.git - # has the dependency in GIT repo while DEPS has dependency in SVN repo. - url = chromium_git_file_url_template % (revision, '.DEPS.git') - http_status_code, content = utils.GetHttpClient().Get( - url, retries=5, retry_if_not=404) - - # If .DEPS.git is not found, use DEPS, assuming it is a commit after migration - # from SVN to GIT. - if http_status_code == 404: - url = chromium_git_file_url_template % (revision, 'DEPS') - http_status_code, content = utils.GetHttpClient().Get(url, retries=5) - - if http_status_code == 200: - return base64.b64decode(content) - else: - return '' - - -def GetChromiumComponents(chromium_revision, - os_platform='unix', - deps_file_downloader=_GetContentOfDEPS): - """Return a list of components used by Chrome of the given revision. - - Args: - chromium_revision: Revision of the Chrome build: svn revision, or git hash. - os_platform: The target platform of the Chrome build, eg. win, mac, etc. - deps_file_downloader: A function that takes the chromium_revision as input, - and returns the content of the DEPS file. The returned - content is assumed to be trusted input and will be - evaluated as python code. - - Returns: - A map from component path to parsed component name, repository URL, - repository type and revision. - Return None if an error occurs. - """ - if os_platform.lower() == 'linux': - os_platform = 'unix' - - chromium_git_base_url = CONFIG['chromium_git_base_url'] - - if not utils.IsGitHash(chromium_revision): - # Convert svn revision or commit position to Git hash. - cr_rev_url_template = CONFIG['cr_rev_url'] - url = cr_rev_url_template % chromium_revision - status_code, content = utils.GetHttpClient().Get( - url, timeout=120, retries=5, retry_if_not=404) - if status_code != 200 or not content: - if status_code == 404: - print 'Chromium commit position %s is not found.' % chromium_revision - return None - - cr_rev_data = json.loads(content) - if 'git_sha' not in cr_rev_data: - return None - - if 'repo' not in cr_rev_data or cr_rev_data['repo'] != 'chromium/src': - print ('%s seems like a commit position of "%s", but not "chromium/src".' - % (chromium_revision, cr_rev_data['repo'])) - return None - - chromium_revision = cr_rev_data.get('git_sha') - if not chromium_revision: - return None - - # Download the content of DEPS file in chromium. - deps_content = deps_file_downloader(chromium_revision) - if not deps_content: - return None - - all_deps = {} - - # Parse the content of DEPS file. - deps, deps_os = _ParseDEPS(deps_content) - all_deps.update(deps) - if os_platform is not None: - all_deps.update(deps_os.get(os_platform, {})) - - # Figure out components based on the dependencies. - components = {} - host_dirs = CONFIG['host_directories'] - for component_path, component_repo_url in all_deps.iteritems(): - if component_repo_url is None: - # For some platform like iso, some component is ignored. - continue - - name = _GetComponentName(component_path, host_dirs) - repository, revision = component_repo_url.split('@') - match = OLD_GIT_URL_PATTERN.match(repository) - if match: - repository = 'https://chromium.googlesource.com/%s' % match.group(1) - is_git_hash = utils.IsGitHash(revision) - if is_git_hash: - repository_type = 'git' - else: - repository_type = 'svn' - if not component_path.endswith('/'): - component_path += '/' - components[component_path] = { - 'path': component_path, - 'name': name, - 'repository': repository, - 'repository_type': repository_type, - 'revision': revision - } - - # Add chromium as a component. - components['src/'] = { - 'path': 'src/', - 'name': 'chromium', - 'repository': chromium_git_base_url, - 'repository_type': 'git', - 'revision': chromium_revision - } - - return components - - -def GetChromiumComponentRange(old_revision, - new_revision, - os_platform='unix', - deps_file_downloader=_GetContentOfDEPS): - """Return a list of components with their revision ranges. - - Args: - old_revision: The old revision of a Chrome build. - new_revision: The new revision of a Chrome build. - os_platform: The target platform of the Chrome build, eg. win, mac, etc. - deps_file_downloader: A function that takes the chromium_revision as input, - and returns the content of the DEPS file. The returned - content is assumed to be trusted input and will be - evaluated as python code. - - Returns: - A map from component path to its parsed regression and other information. - Return None if an error occurs. - """ - old_components = GetChromiumComponents(old_revision, os_platform, - deps_file_downloader) - if not old_components: - return None - - new_components = GetChromiumComponents(new_revision, os_platform, - deps_file_downloader) - if not new_components: - return None - - components = {} - for path in new_components: - new_component = new_components[path] - old_revision = None - - if path in old_components: - old_component = old_components[path] - old_revision = old_component['revision'] - - components[path] = { - 'path': path, - 'rolled': new_component['revision'] != old_revision, - 'name': new_component['name'], - 'old_revision': old_revision, - 'new_revision': new_component['revision'], - 'repository': new_component['repository'], - 'repository_type': new_component['repository_type'] - } - - return components diff --git a/chromium/tools/findit/chromium_deps_unittest.py b/chromium/tools/findit/chromium_deps_unittest.py deleted file mode 100644 index 7f64a12b8fd..00000000000 --- a/chromium/tools/findit/chromium_deps_unittest.py +++ /dev/null @@ -1,189 +0,0 @@ -# Copyright (c) 2014 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. - -import unittest - -import chromium_deps -from common import utils - - -class ChromiumDEPSTest(unittest.TestCase): - DEPS_TEMPLATE = """ -vars = { - "googlecode_url": "http://%%s.googlecode.com/svn", - "webkit_trunk": "http://src.chromium.org/blink/trunk", - "webkit_revision": "%s", - "chromium_git": "https://chromium.googlesource.com", -} - -deps = { - "src/breakpad/src": - (Var("googlecode_url") %% "google-breakpad") + "/trunk/src@%s", - - "src/third_party/WebKit": - Var("webkit_trunk") + "@" + Var("webkit_revision"), -} - -deps_os = { - "unix": { - "src/third_party/liblouis/src": - Var("chromium_git") + - "/external/liblouis.git@%s", - } -} -""" - - def __init__(self, *args, **kwargs): - super(ChromiumDEPSTest, self).__init__(*args, **kwargs) - - def testGetChromiumComponents(self): - chromium_revision = '283296' - chromium_revision_git_hash = 'b041fda2e8493dcb26aac08deb493943df240cbb' - webkit_revision = '178200' - breakpad_revision = '1345' - liblouis_commit_hashcode = '3c2daee56250162e5a75830871601d74328d39f5' - - def _GetContentOfDEPS(chromium_revision_tmp): - self.assertEqual(chromium_revision_tmp, chromium_revision_git_hash) - return self.DEPS_TEMPLATE % (webkit_revision, breakpad_revision, - liblouis_commit_hashcode) - - expected_results = { - 'src/breakpad/src/': { - 'path': 'src/breakpad/src/', - 'repository_type': 'svn', - 'name': 'breakpad', - 'repository': 'http://google-breakpad.googlecode.com/svn/trunk/src', - 'revision': breakpad_revision - }, - 'src/third_party/liblouis/src/': { - 'path': 'src/third_party/liblouis/src/', - 'repository_type': 'git', - 'name': 'liblouis', - 'repository': - 'https://chromium.googlesource.com/external/liblouis.git', - 'revision': liblouis_commit_hashcode - }, - 'src/': { - 'path': 'src/', - 'repository_type': 'git', - 'name': 'chromium', - 'repository': 'https://chromium.googlesource.com/chromium/src/', - 'revision': chromium_revision_git_hash - }, - 'src/third_party/WebKit/': { - 'path': 'src/third_party/WebKit/', - 'repository_type': 'svn', - 'name': 'blink', - 'repository': 'http://src.chromium.org/blink/trunk', - 'revision': webkit_revision - } - } - - components = chromium_deps.GetChromiumComponents( - chromium_revision, deps_file_downloader=_GetContentOfDEPS) - self.assertEqual(expected_results, components) - - def testGetChromiumComponentRange(self): - chromium_revision1 = '283200' - chromium_revision_git_hash1 = 'c53c387f46a2ff0cf7c072222b826cff0817a80f' - webkit_revision1 = '178084' - breakpad_revision1 = '1345' - liblouis_commit_hashcode1 = '3c2daee56250162e5a75830871601d74328d39f5' - - chromium_revision2 = '283296' - chromium_revision_git_hash2 = 'b041fda2e8493dcb26aac08deb493943df240cbb' - webkit_revision2 = '178200' - breakpad_revision2 = '1345' - liblouis_commit_hashcode2 = '3c2daee56250162e5a75830871601d74328d39f5' - - def _GetContentOfDEPS(chromium_revision): - chromium_revision = str(chromium_revision) - if chromium_revision == chromium_revision_git_hash1: - return self.DEPS_TEMPLATE % (webkit_revision1, breakpad_revision1, - liblouis_commit_hashcode1) - else: - self.assertEqual(chromium_revision, chromium_revision_git_hash2) - return self.DEPS_TEMPLATE % (webkit_revision2, breakpad_revision2, - liblouis_commit_hashcode2) - - expected_results = { - 'src/breakpad/src/': { - 'old_revision': breakpad_revision1, - 'name': 'breakpad', - 'repository': 'http://google-breakpad.googlecode.com/svn/trunk/src', - 'rolled': False, - 'new_revision': breakpad_revision2, - 'path': 'src/breakpad/src/', - 'repository_type': 'svn' - }, - 'src/third_party/liblouis/src/': { - 'old_revision': liblouis_commit_hashcode1, - 'name': 'liblouis', - 'repository': - 'https://chromium.googlesource.com/external/liblouis.git', - 'rolled': False, - 'new_revision': liblouis_commit_hashcode2, - 'path': 'src/third_party/liblouis/src/', - 'repository_type': 'git' - }, - 'src/': { - 'old_revision': chromium_revision_git_hash1, - 'name': 'chromium', - 'repository': 'https://chromium.googlesource.com/chromium/src/', - 'rolled': True, - 'new_revision': chromium_revision_git_hash2, - 'path': 'src/', - 'repository_type': 'git' - }, - 'src/third_party/WebKit/': { - 'old_revision': webkit_revision1, - 'name': 'blink', - 'repository': 'http://src.chromium.org/blink/trunk', - 'rolled': True, - 'new_revision': webkit_revision2, - 'path': 'src/third_party/WebKit/', - 'repository_type': 'svn' - } - } - - components = chromium_deps.GetChromiumComponentRange( - chromium_revision1, chromium_revision2, - deps_file_downloader=_GetContentOfDEPS) - self.assertEqual(expected_results, components) - - def _VerifyGitHashForAllComponents(self, deps): - self.assertTrue(deps) - self.assertTrue(isinstance(deps, dict)) - for component in deps.values(): - for key in ['revision', 'old_revision', 'new_revision']: - if key in component: - self.assertTrue(utils.IsGitHash(component[key])) - - def testComponentRangeCrossGitMigrationPoint(self): - # The old revision is from svn. - # The new revision is from git. - deps = chromium_deps.GetChromiumComponentRange( - '291440', - '744746cc51ef81c8f8d727fafa46b14d1c03fe44') - self._VerifyGitHashForAllComponents(deps) - - def testGetSvnRevision(self): - # For this case, svn revision needs converting to git hash and there will be - # .DEPS.git and DEPS. - deps = chromium_deps.GetChromiumComponents(284750) - self._VerifyGitHashForAllComponents(deps) - - def testGetGitRevisionWithoutDEPS_dot_GIT(self): - # For this case, there is only DEPS, not .DEPS.git. - deps = chromium_deps.GetChromiumComponents( - 'f8b3fe9660d8dda318800f55d5e29799bbfd43f7') - self._VerifyGitHashForAllComponents(deps) - - - def testGetGitRevisionWithDEPS_dot_GIT(self): - # For this case, there will be .DEPS.git. - deps = chromium_deps.GetChromiumComponents( - '8ae88241aa9f224e8ce97250f32469d616e437aa') - self._VerifyGitHashForAllComponents(deps) diff --git a/chromium/tools/findit/common/__init__.py b/chromium/tools/findit/common/__init__.py deleted file mode 100644 index 31f0497a8a5..00000000000 --- a/chromium/tools/findit/common/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright (c) 2014 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. - diff --git a/chromium/tools/findit/common/cacert.pem b/chromium/tools/findit/common/cacert.pem deleted file mode 100644 index c9ea29d7ee0..00000000000 --- a/chromium/tools/findit/common/cacert.pem +++ /dev/null @@ -1,2186 +0,0 @@ -# Source: http://pki.google.com/roots.pem -# Updated at: Wed Dec 17 18:17:42 PST 2014 - -# Issuer: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc. -# Subject: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc. -# Label: "GTE CyberTrust Global Root" -# Serial: 421 -# MD5 Fingerprint: ca:3d:d3:68:f1:03:5c:d0:32:fa:b8:2b:59:e8:5a:db -# SHA1 Fingerprint: 97:81:79:50:d8:1c:96:70:cc:34:d8:09:cf:79:44:31:36:7e:f4:74 -# SHA256 Fingerprint: a5:31:25:18:8d:21:10:aa:96:4b:02:c7:b7:c6:da:32:03:17:08:94:e5:fb:71:ff:fb:66:67:d5:e6:81:0a:36 ------BEGIN CERTIFICATE----- -MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD -VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv -bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv -b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV -UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU -cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds -b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH -iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS -r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 -04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r -GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 -3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P -lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ ------END CERTIFICATE----- - -# Issuer: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division -# Subject: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division -# Label: "Thawte Server CA" -# Serial: 1 -# MD5 Fingerprint: c5:70:c4:a2:ed:53:78:0c:c8:10:53:81:64:cb:d0:1d -# SHA1 Fingerprint: 23:e5:94:94:51:95:f2:41:48:03:b4:d5:64:d2:a3:a3:f5:d8:8b:8c -# SHA256 Fingerprint: b4:41:0b:73:e2:e6:ea:ca:47:fb:c4:2f:8f:a4:01:8a:f4:38:1d:c5:4c:fa:a8:44:50:46:1e:ed:09:45:4d:e9 ------BEGIN CERTIFICATE----- -MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx -FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD -VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv -biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm -MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx -MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT -DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3 -dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl -cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3 -DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD -gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91 -yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX -L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj -EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG -7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e -QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ -qdq5snUb9kLy78fyGPmJvKP/iiMucEc= ------END CERTIFICATE----- - -# Issuer: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division -# Subject: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division -# Label: "Thawte Premium Server CA" -# Serial: 1 -# MD5 Fingerprint: 06:9f:69:79:16:66:90:02:1b:8c:8c:a2:c3:07:6f:3a -# SHA1 Fingerprint: 62:7f:8d:78:27:65:63:99:d2:7d:7f:90:44:c9:fe:b3:f3:3e:fa:9a -# SHA256 Fingerprint: ab:70:36:36:5c:71:54:aa:29:c2:c2:9f:5d:41:91:16:3b:16:2a:22:25:01:13:57:d5:6d:07:ff:a7:bc:1f:72 ------BEGIN CERTIFICATE----- -MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx -FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD -VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv -biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy -dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t -MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB -MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG -A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp -b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl -cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv -bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE -VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ -ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR -uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG -9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI -hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM -pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== ------END CERTIFICATE----- - -# Issuer: O=Equifax OU=Equifax Secure Certificate Authority -# Subject: O=Equifax OU=Equifax Secure Certificate Authority -# Label: "Equifax Secure CA" -# Serial: 903804111 -# MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4 -# SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a -# SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78 ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV -UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy -dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 -MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx -dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f -BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A -cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC -AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ -MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm -aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw -ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj -IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF -MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA -A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y -7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh -1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 ------END CERTIFICATE----- - -# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority -# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority -# Label: "Verisign Class 3 Public Primary Certification Authority" -# Serial: 149843929435818692848040365716851702463 -# MD5 Fingerprint: 10:fc:63:5d:f6:26:3e:0d:f3:25:be:5f:79:cd:67:67 -# SHA1 Fingerprint: 74:2c:31:92:e6:07:e4:24:eb:45:49:54:2b:e1:bb:c5:3e:61:74:e2 -# SHA256 Fingerprint: e7:68:56:34:ef:ac:f6:9a:ce:93:9a:6b:25:5b:7b:4f:ab:ef:42:93:5b:50:a2:65:ac:b5:cb:60:27:e4:4e:70 ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz -cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 -MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV -BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt -YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN -ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE -BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is -I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G -CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do -lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc -AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k ------END CERTIFICATE----- - -# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network -# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network -# Label: "Verisign Class 3 Public Primary Certification Authority - G2" -# Serial: 167285380242319648451154478808036881606 -# MD5 Fingerprint: a2:33:9b:4c:74:78:73:d4:6c:e7:c1:f3:8d:cb:5c:e9 -# SHA1 Fingerprint: 85:37:1c:a6:e5:50:14:3d:ce:28:03:47:1b:de:3a:09:e8:f8:77:0f -# SHA256 Fingerprint: 83:ce:3c:12:29:68:8a:59:3d:48:5f:81:97:3c:0f:91:95:43:1e:da:37:cc:5e:36:43:0e:79:c7:a8:88:63:8b ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ -BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh -c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy -MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp -emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X -DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw -FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg -UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo -YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 -MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB -AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 -pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 -13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID -AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk -U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i -F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY -oJ2daZH9 ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA -# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA -# Label: "GlobalSign Root CA" -# Serial: 4835703278459707669005204 -# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a -# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c -# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw -MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT -aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ -jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp -xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp -1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG -snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ -U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 -9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B -AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz -yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE -38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP -AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad -DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME -HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 -# Label: "GlobalSign Root CA - R2" -# Serial: 4835703278459682885658125 -# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 -# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe -# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 -MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL -v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 -eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq -tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd -C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa -zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB -mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH -V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n -bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG -3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs -J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO -291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS -ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd -AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- - -# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority -# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority -# Label: "ValiCert Class 1 VA" -# Serial: 1 -# MD5 Fingerprint: 65:58:ab:15:ad:57:6c:1e:a8:a7:b5:69:ac:bf:ff:eb -# SHA1 Fingerprint: e5:df:74:3c:b6:01:c4:9b:98:43:dc:ab:8c:e8:6a:81:10:9f:e4:8e -# SHA256 Fingerprint: f4:c1:49:55:1a:30:13:a3:5b:c7:bf:fe:17:a7:f3:44:9b:c1:ab:5b:5a:0a:e7:4b:06:c2:3b:90:00:4c:01:04 ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 -IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz -BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y -aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG -9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy -NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y -azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw -Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl -cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y -LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+ -TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y -TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0 -LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW -I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw -nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI ------END CERTIFICATE----- - -# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority -# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority -# Label: "ValiCert Class 2 VA" -# Serial: 1 -# MD5 Fingerprint: a9:23:75:9b:ba:49:36:6e:31:c2:db:f2:e7:66:ba:87 -# SHA1 Fingerprint: 31:7a:2a:d0:7f:2b:33:5e:f5:a1:c3:4e:4b:57:e8:b7:d8:f1:fc:a6 -# SHA256 Fingerprint: 58:d0:17:27:9c:d4:dc:63:ab:dd:b1:96:a6:c9:90:6c:30:c4:e0:87:83:ea:e8:c1:60:99:54:d6:93:55:59:6b ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 -IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz -BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y -aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG -9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy -NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y -azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw -Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl -cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY -dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9 -WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS -v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v -UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu -IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC -W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd ------END CERTIFICATE----- - -# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority -# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority -# Label: "RSA Root Certificate 1" -# Serial: 1 -# MD5 Fingerprint: a2:6f:53:b7:ee:40:db:4a:68:e7:fa:18:d9:10:4b:72 -# SHA1 Fingerprint: 69:bd:8c:f4:9c:d3:00:fb:59:2e:17:93:ca:55:6a:f3:ec:aa:35:fb -# SHA256 Fingerprint: bc:23:f9:8a:31:3c:b9:2d:e3:bb:fc:3a:5a:9f:44:61:ac:39:49:4c:4a:e1:5a:9e:9d:f1:31:e9:9b:73:01:9a ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 -IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz -BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y -aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG -9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy -NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y -azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw -Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl -cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD -cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs -2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY -JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE -Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ -n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A -PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Label: "Verisign Class 3 Public Primary Certification Authority - G3" -# Serial: 206684696279472310254277870180966723415 -# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 -# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 -# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b -N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t -KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu -kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm -CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ -Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu -imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te -2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe -DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p -F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt -TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Label: "Verisign Class 4 Public Primary Certification Authority - G3" -# Serial: 314531972711909413743075096039378935511 -# MD5 Fingerprint: db:c8:f2:27:2e:b1:ea:6a:29:23:5d:fe:56:3e:33:df -# SHA1 Fingerprint: c8:ec:8c:87:92:69:cb:4b:ab:39:e9:8d:7e:57:67:f3:14:95:73:9d -# SHA256 Fingerprint: e3:89:36:0d:0f:db:ae:b3:d2:50:58:4b:47:30:31:4e:22:2f:39:c1:56:a0:20:14:4e:8d:96:05:61:79:15:06 ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 -GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ -+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd -U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm -NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY -ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ -ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 -CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq -g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm -fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c -2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ -bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== ------END CERTIFICATE----- - -# Issuer: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited -# Subject: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited -# Label: "Entrust.net Secure Server CA" -# Serial: 927650371 -# MD5 Fingerprint: df:f2:80:73:cc:f1:e6:61:73:fc:f5:42:e9:c5:7c:ee -# SHA1 Fingerprint: 99:a6:9b:e6:1a:fe:88:6b:4d:2b:82:00:7c:b8:54:fc:31:7e:15:39 -# SHA256 Fingerprint: 62:f2:40:27:8c:56:4c:4d:d8:bf:7d:9d:4f:6f:36:6e:a8:94:d2:2f:5f:34:d9:89:a9:83:ac:ec:2f:ff:ed:50 ------BEGIN CERTIFICATE----- -MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC -VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u -ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc -KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u -ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 -MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE -ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j -b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF -bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg -U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA -A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ -I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 -wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC -AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb -oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 -BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p -dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk -MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp -b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu -dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 -MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi -E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa -MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI -hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN -95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd -2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= ------END CERTIFICATE----- - -# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited -# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited -# Label: "Entrust.net Premium 2048 Secure Server CA" -# Serial: 946059622 -# MD5 Fingerprint: ba:21:ea:20:d6:dd:db:8f:c1:57:8b:40:ad:a1:fc:fc -# SHA1 Fingerprint: 80:1d:62:d0:7b:44:9d:5c:5c:03:5c:98:ea:61:fa:44:3c:2a:58:fe -# SHA256 Fingerprint: d1:c3:39:ea:27:84:eb:87:0f:93:4f:c5:63:4e:4a:a9:ad:55:05:01:64:01:f2:64:65:d3:7a:57:46:63:35:9f ------BEGIN CERTIFICATE----- -MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy -MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA -vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G -CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA -WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo -oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ -h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18 -f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN -B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy -vUxFnmG6v4SBkgPR0ml8xQ== ------END CERTIFICATE----- - -# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust -# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust -# Label: "Baltimore CyberTrust Root" -# Serial: 33554617 -# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 -# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 -# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX -DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y -ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy -VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr -mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr -IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK -mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu -XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy -dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye -jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 -BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 -DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 -9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx -jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 -Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz -ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS -R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- - -# Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. -# Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. -# Label: "Equifax Secure Global eBusiness CA" -# Serial: 1 -# MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc -# SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45 -# SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07 ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT -ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw -MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj -dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l -c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC -UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc -58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ -o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr -aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA -A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA -Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv -8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- - -# Issuer: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc. -# Subject: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc. -# Label: "Equifax Secure eBusiness CA 1" -# Serial: 4 -# MD5 Fingerprint: 64:9c:ef:2e:44:fc:c6:8f:52:07:d0:51:73:8f:cb:3d -# SHA1 Fingerprint: da:40:18:8b:91:89:a3:ed:ee:ae:da:97:fe:2f:9d:f5:b7:d1:8a:41 -# SHA256 Fingerprint: cf:56:ff:46:a4:a1:86:10:9d:d9:65:84:b5:ee:b5:8a:51:0c:42:75:b0:e5:f9:4f:40:bb:ae:86:5e:19:f6:73 ------BEGIN CERTIFICATE----- -MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT -ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw -MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j -LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ -KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo -RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu -WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw -Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK -eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM -zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ -WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN -/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== ------END CERTIFICATE----- - -# Issuer: O=Equifax Secure OU=Equifax Secure eBusiness CA-2 -# Subject: O=Equifax Secure OU=Equifax Secure eBusiness CA-2 -# Label: "Equifax Secure eBusiness CA 2" -# Serial: 930140085 -# MD5 Fingerprint: aa:bf:bf:64:97:da:98:1d:6f:c6:08:3a:95:70:33:ca -# SHA1 Fingerprint: 39:4f:f6:85:0b:06:be:52:e5:18:56:cc:10:e1:80:e8:82:b3:85:cc -# SHA256 Fingerprint: 2f:27:4e:48:ab:a4:ac:7b:76:59:33:10:17:75:50:6d:c3:0e:e3:8e:f6:ac:d5:c0:49:32:cf:e0:41:23:42:20 ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj -dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0 -NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD -VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G -vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/ -BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C -AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX -MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl -IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw -NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq -y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF -MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA -A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy -0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1 -E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN ------END CERTIFICATE----- - -# Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network -# Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network -# Label: "AddTrust Low-Value Services Root" -# Serial: 1 -# MD5 Fingerprint: 1e:42:95:02:33:92:6b:b9:5f:c0:7f:da:d6:b2:4b:fc -# SHA1 Fingerprint: cc:ab:0e:a0:4c:23:01:d6:69:7b:dd:37:9f:cd:12:eb:24:e3:94:9d -# SHA256 Fingerprint: 8c:72:09:27:9a:c0:4e:27:5e:16:d0:7f:d3:b7:75:e8:01:54:b5:96:80:46:e3:1f:52:dd:25:76:63:24:e9:a7 ------BEGIN CERTIFICATE----- -MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 -b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw -MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD -VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA -A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul -CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n -tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl -dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch -PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC -+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O -BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk -ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB -IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X -7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz -43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY -eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl -pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA -WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= ------END CERTIFICATE----- - -# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network -# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network -# Label: "AddTrust External Root" -# Serial: 1 -# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f -# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 -# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs -IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 -MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h -bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt -H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 -uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX -mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX -a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN -E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 -WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD -VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 -Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU -cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx -IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN -AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH -YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC -Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX -c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a -mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- - -# Issuer: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network -# Subject: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network -# Label: "AddTrust Public Services Root" -# Serial: 1 -# MD5 Fingerprint: c1:62:3e:23:c5:82:73:9c:03:59:4b:2b:e9:77:49:7f -# SHA1 Fingerprint: 2a:b6:28:48:5e:78:fb:f3:ad:9e:79:10:dd:6b:df:99:72:2c:96:e5 -# SHA256 Fingerprint: 07:91:ca:07:49:b2:07:82:aa:d3:c7:d7:bd:0c:df:c9:48:58:35:84:3e:b2:d7:99:60:09:ce:43:ab:6c:69:27 ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 -b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx -MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB -ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV -BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV -6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX -GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP -dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH -1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF -62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW -BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw -AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL -MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU -cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv -b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6 -IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/ -iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao -GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh -4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm -XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY= ------END CERTIFICATE----- - -# Issuer: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network -# Subject: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network -# Label: "AddTrust Qualified Certificates Root" -# Serial: 1 -# MD5 Fingerprint: 27:ec:39:47:cd:da:5a:af:e2:9a:01:65:21:a9:4c:bb -# SHA1 Fingerprint: 4d:23:78:ec:91:95:39:b5:00:7f:75:8f:03:3b:21:1e:c5:4d:8b:cf -# SHA256 Fingerprint: 80:95:21:08:05:db:4b:bc:35:5e:44:28:d8:fd:6e:c2:cd:e3:ab:5f:b9:7a:99:42:98:8e:b8:f4:dc:d0:60:16 ------BEGIN CERTIFICATE----- -MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 -b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1 -MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK -EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh -BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq -xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G -87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i -2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U -WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1 -0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G -A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr -pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL -ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm -aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv -hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm -hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X -dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3 -P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y -iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no -xqE= ------END CERTIFICATE----- - -# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. -# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. -# Label: "Entrust Root Certification Authority" -# Serial: 1164660820 -# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 -# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 -# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 -Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW -KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw -NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw -NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy -ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV -BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo -Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 -4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 -KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI -rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi -94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB -sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi -gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo -kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE -vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t -O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua -AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP -9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ -eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m -0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. -# Subject: CN=GeoTrust Global CA O=GeoTrust Inc. -# Label: "GeoTrust Global CA" -# Serial: 144470 -# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 -# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 -# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg -R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 -9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq -fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv -iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU -1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ -bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW -MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA -ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l -uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn -Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS -tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF -PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un -hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV -5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Global CA 2 O=GeoTrust Inc. -# Subject: CN=GeoTrust Global CA 2 O=GeoTrust Inc. -# Label: "GeoTrust Global CA 2" -# Serial: 1 -# MD5 Fingerprint: 0e:40:a7:6c:de:03:5d:8f:d1:0f:e4:d1:8d:f9:6c:a9 -# SHA1 Fingerprint: a9:e9:78:08:14:37:58:88:f2:05:19:b0:6d:2b:0d:2b:60:16:90:7d -# SHA256 Fingerprint: ca:2d:82:a0:86:77:07:2f:8a:b6:76:4f:f0:35:67:6c:fe:3e:5e:32:5e:01:21:72:df:3f:92:09:6d:b7:9b:85 ------BEGIN CERTIFICATE----- -MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs -IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg -R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A -PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8 -Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL -TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL -5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7 -S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe -2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE -FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap -EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td -EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv -/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN -A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0 -abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF -I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz -4iIprn2DQKi6bA== ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. -# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. -# Label: "GeoTrust Universal CA" -# Serial: 1 -# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 -# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 -# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 ------BEGIN CERTIFICATE----- -MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy -c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE -BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 -IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV -VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 -cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT -QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh -F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v -c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w -mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd -VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX -teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ -f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe -Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ -nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB -/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY -MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG -9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc -aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX -IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn -ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z -uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN -Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja -QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW -koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 -ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt -DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm -bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. -# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. -# Label: "GeoTrust Universal CA 2" -# Serial: 1 -# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 -# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 -# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy -c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD -VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 -c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 -WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG -FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq -XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL -se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb -KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd -IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 -y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt -hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc -QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 -Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV -HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ -KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z -dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ -L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr -Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo -ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY -T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz -GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m -1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV -OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH -6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX -QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS ------END CERTIFICATE----- - -# Issuer: CN=America Online Root Certification Authority 1 O=America Online Inc. -# Subject: CN=America Online Root Certification Authority 1 O=America Online Inc. -# Label: "America Online Root Certification Authority 1" -# Serial: 1 -# MD5 Fingerprint: 14:f1:08:ad:9d:fa:64:e2:89:e7:1c:cf:a8:ad:7d:5e -# SHA1 Fingerprint: 39:21:c1:15:c1:5d:0e:ca:5c:cb:5b:c4:f0:7d:21:d8:05:0b:56:6a -# SHA256 Fingerprint: 77:40:73:12:c6:3a:15:3d:5b:c0:0b:4e:51:75:9c:df:da:c2:37:dc:2a:33:b6:79:46:e9:8e:9b:fa:68:0a:e3 ------BEGIN CERTIFICATE----- -MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP -bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2 -MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft -ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk -hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym -1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW -OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb -2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko -O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU -AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB -BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF -Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb -LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir -oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C -MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds -sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 ------END CERTIFICATE----- - -# Issuer: CN=America Online Root Certification Authority 2 O=America Online Inc. -# Subject: CN=America Online Root Certification Authority 2 O=America Online Inc. -# Label: "America Online Root Certification Authority 2" -# Serial: 1 -# MD5 Fingerprint: d6:ed:3c:ca:e2:66:0f:af:10:43:0d:77:9b:04:09:bf -# SHA1 Fingerprint: 85:b5:ff:67:9b:0c:79:96:1f:c8:6e:44:22:00:46:13:db:17:92:84 -# SHA256 Fingerprint: 7d:3b:46:5a:60:14:e5:26:c0:af:fc:ee:21:27:d2:31:17:27:ad:81:1c:26:84:2d:00:6a:f3:73:06:cc:80:bd ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP -bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2 -MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft -ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC -206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci -KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2 -JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9 -BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e -Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B -PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67 -Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq -Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ -o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3 -+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj -YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj -FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn -xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2 -LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc -obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8 -CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe -IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA -DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F -AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX -Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb -AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl -Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw -RY8mkaKO/qk= ------END CERTIFICATE----- - -# Issuer: CN=AAA Certificate Services O=Comodo CA Limited -# Subject: CN=AAA Certificate Services O=Comodo CA Limited -# Label: "Comodo AAA Services root" -# Serial: 1 -# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 -# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 -# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj -YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM -GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua -BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe -3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 -YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR -rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm -ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU -oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v -QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t -b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF -AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q -GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 -G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi -l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 -smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- - -# Issuer: CN=Secure Certificate Services O=Comodo CA Limited -# Subject: CN=Secure Certificate Services O=Comodo CA Limited -# Label: "Comodo Secure Services root" -# Serial: 1 -# MD5 Fingerprint: d3:d9:bd:ae:9f:ac:67:24:b3:c8:1b:52:e1:b9:a9:bd -# SHA1 Fingerprint: 4a:65:d5:f4:1d:ef:39:b8:b8:90:4a:4a:d3:64:81:33:cf:c7:a1:d1 -# SHA256 Fingerprint: bd:81:ce:3b:4f:65:91:d1:1a:67:b5:fc:7a:47:fd:ef:25:52:1b:f9:aa:4e:18:b9:e3:df:2e:34:a7:80:3b:e8 ------BEGIN CERTIFICATE----- -MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp -ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow -fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV -BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM -cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S -HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996 -CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk -3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz -6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV -HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud -EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv -Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw -Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww -DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0 -5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj -Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI -gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ -aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl -izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk= ------END CERTIFICATE----- - -# Issuer: CN=Trusted Certificate Services O=Comodo CA Limited -# Subject: CN=Trusted Certificate Services O=Comodo CA Limited -# Label: "Comodo Trusted Services root" -# Serial: 1 -# MD5 Fingerprint: 91:1b:3f:6e:cd:9e:ab:ee:07:fe:1f:71:d2:b3:61:27 -# SHA1 Fingerprint: e1:9f:e3:0e:8b:84:60:9e:80:9b:17:0d:72:a8:c5:ba:6e:14:09:bd -# SHA256 Fingerprint: 3f:06:e5:56:81:d4:96:f5:be:16:9e:b5:38:9f:9f:2b:8f:f6:1e:17:08:df:68:81:72:48:49:cd:5d:27:cb:69 ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0 -aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla -MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO -BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD -VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW -fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt -TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL -fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW -1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7 -kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G -A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v -ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo -dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu -Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/ -HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 -pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS -jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+ -xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn -dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi ------END CERTIFICATE----- - -# Issuer: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com -# Subject: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com -# Label: "UTN DATACorp SGC Root CA" -# Serial: 91374294542884689855167577680241077609 -# MD5 Fingerprint: b3:a5:3e:77:21:6d:ac:4a:c0:c9:fb:d5:41:3d:ca:06 -# SHA1 Fingerprint: 58:11:9f:0e:12:82:87:ea:50:fd:d9:87:45:6f:4f:78:dc:fa:d6:d4 -# SHA256 Fingerprint: 85:fb:2f:91:dd:12:27:5a:01:45:b6:36:53:4f:84:02:4a:d6:8b:69:b8:ee:88:68:4f:f7:11:37:58:05:b3:48 ------BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG -EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD -VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu -dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 -E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ -D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK -4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq -lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW -bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB -o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT -MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js -LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr -BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB -AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj -j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH -KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv -2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 -mfnGV/TJVTl4uix5yaaIK/QI ------END CERTIFICATE----- - -# Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com -# Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com -# Label: "UTN USERFirst Hardware Root CA" -# Serial: 91374294542884704022267039221184531197 -# MD5 Fingerprint: 4c:56:41:e5:0d:bb:2b:e8:ca:a3:ed:18:08:ad:43:39 -# SHA1 Fingerprint: 04:83:ed:33:99:ac:36:08:05:87:22:ed:bc:5e:46:00:e3:be:f9:d7 -# SHA256 Fingerprint: 6e:a5:47:41:d0:04:66:7e:ed:1b:48:16:63:4a:a3:a7:9e:6e:4b:96:95:0f:82:79:da:fc:8d:9b:d8:81:21:37 ------BEGIN CERTIFICATE----- -MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB -lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt -SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG -A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe -MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v -d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh -cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn -0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ -M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a -MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd -oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI -DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy -oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 -dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy -bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF -BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM -//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli -CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE -CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t -3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS -KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== ------END CERTIFICATE----- - -# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com -# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com -# Label: "XRamp Global CA Root" -# Serial: 107108908803651509692980124233745014957 -# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 -# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 -# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB -gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk -MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY -UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx -NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 -dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy -dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 -38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP -KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q -DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 -qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa -JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi -PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P -BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs -jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 -eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR -vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa -IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy -i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ -O+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- - -# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority -# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority -# Label: "Go Daddy Class 2 CA" -# Serial: 0 -# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 -# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 -# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh -MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE -YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 -MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo -ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg -MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN -ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA -PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w -wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi -EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY -avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ -YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE -sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h -/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 -IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD -ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy -OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P -TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER -dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf -ReYNnyicsbkqWletNw+vHX/bvZ8= ------END CERTIFICATE----- - -# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority -# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority -# Label: "Starfield Class 2 CA" -# Serial: 0 -# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 -# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a -# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl -MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp -U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw -NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE -ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp -ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 -DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf -8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN -+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 -X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa -K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA -1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G -A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR -zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 -YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD -bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 -L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D -eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp -VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY -WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- - -# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing -# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing -# Label: "StartCom Certification Authority" -# Serial: 1 -# MD5 Fingerprint: 22:4d:8f:8a:fc:f7:35:c2:bb:57:34:90:7b:8b:22:16 -# SHA1 Fingerprint: 3e:2b:f7:f2:03:1b:96:f3:8c:e6:c4:d8:a8:5d:3e:2d:58:47:6a:0f -# SHA256 Fingerprint: c7:66:a9:be:f2:d4:07:1c:86:3a:31:aa:49:20:e8:13:b2:d1:98:60:8c:b7:b7:cf:e2:11:43:b8:36:df:09:ea ------BEGIN CERTIFICATE----- -MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE -FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j -ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js -LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM -BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 -Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy -dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh -cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh -YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg -dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp -bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ -YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT -TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ -9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 -jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW -FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz -ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 -ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L -EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu -L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq -yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC -O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V -um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh -NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Assured ID Root CA" -# Serial: 17154717934120587862167794914071425081 -# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 -# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 -# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c -JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP -mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ -wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 -VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ -AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB -AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun -pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC -dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf -fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm -NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx -H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Global Root CA" -# Serial: 10944719598952040374951832963794454346 -# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e -# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 -# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- - -# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert High Assurance EV Root CA" -# Serial: 3553400076410547919724730734378100087 -# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a -# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 -# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. -# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. -# Label: "GeoTrust Primary Certification Authority" -# Serial: 32798226551256963324313806436981982369 -# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf -# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 -# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY -MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo -R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx -MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 -AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA -ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 -7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W -kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI -mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ -KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 -6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl -4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K -oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj -UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU -AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= ------END CERTIFICATE----- - -# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only -# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only -# Label: "thawte Primary Root CA" -# Serial: 69529181992039203566298953787712940909 -# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 -# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 -# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB -qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV -BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw -NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j -LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG -A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs -W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta -3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk -6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 -Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J -NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP -r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU -DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz -YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX -xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 -/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ -LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 -jVaMaA== ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only -# Label: "VeriSign Class 3 Public Primary Certification Authority - G5" -# Serial: 33037644167568058970164719475676101450 -# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c -# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 -# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df ------BEGIN CERTIFICATE----- -MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 -nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex -t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz -SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG -BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ -rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ -NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E -BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH -BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy -aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv -MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE -p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y -5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK -WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ -4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N -hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq ------END CERTIFICATE----- - -# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO Certification Authority O=COMODO CA Limited -# Label: "COMODO Certification Authority" -# Serial: 104350513648249232941998508985834464573 -# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 -# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b -# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB -gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV -BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw -MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl -YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P -RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 -UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI -2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 -Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp -+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ -DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O -nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW -/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g -PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u -QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY -SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv -IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 -zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd -BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB -ZQ== ------END CERTIFICATE----- - -# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. -# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. -# Label: "Network Solutions Certificate Authority" -# Serial: 116697915152937497490437556386812487904 -# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e -# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce -# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi -MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV -UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO -ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz -c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP -OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl -mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF -BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 -qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw -gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu -bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp -dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 -6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ -h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH -/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN -pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- - -# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited -# Label: "COMODO ECC Certification Authority" -# Serial: 41578283867086692638256921589707938090 -# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 -# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 -# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT -IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw -MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy -ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N -T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR -FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J -cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW -BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm -fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv -GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - -# Issuer: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA -# Subject: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA -# Label: "TC TrustCenter Class 2 CA II" -# Serial: 941389028203453866782103406992443 -# MD5 Fingerprint: ce:78:33:5c:59:78:01:6e:18:ea:b9:36:a0:b9:2e:23 -# SHA1 Fingerprint: ae:50:83:ed:7c:f4:5c:bc:8f:61:c6:21:fe:68:5d:79:42:21:15:6e -# SHA256 Fingerprint: e6:b8:f8:76:64:85:f8:07:ae:7f:8d:ac:16:70:46:1f:07:c0:a1:3e:ef:3a:1f:f7:17:53:8d:7a:ba:d3:91:b4 ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV -BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 -Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1 -OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i -SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc -VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf -tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg -uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J -XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK -8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99 -5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3 -kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy -dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6 -Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz -JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 -Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS -GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt -ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8 -au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV -hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI -dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ== ------END CERTIFICATE----- - -# Issuer: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA -# Subject: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA -# Label: "TC TrustCenter Class 3 CA II" -# Serial: 1506523511417715638772220530020799 -# MD5 Fingerprint: 56:5f:aa:80:61:12:17:f6:67:21:e6:2b:6d:61:56:8e -# SHA1 Fingerprint: 80:25:ef:f4:6e:70:c8:d4:72:24:65:84:fe:40:3b:8a:8d:6a:db:f5 -# SHA256 Fingerprint: 8d:a0:84:fc:f9:9c:e0:77:22:f8:9b:32:05:93:98:06:fa:5c:b8:11:e1:c8:13:f6:a1:08:c7:d3:36:b3:40:8e ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV -BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 -Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1 -OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i -SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc -VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW -Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q -Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2 -1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq -ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1 -Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX -XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy -dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6 -Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz -JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 -Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN -irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8 -TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6 -g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB -95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj -S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A== ------END CERTIFICATE----- - -# Issuer: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA -# Subject: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA -# Label: "TC TrustCenter Universal CA I" -# Serial: 601024842042189035295619584734726 -# MD5 Fingerprint: 45:e1:a5:72:c5:a9:36:64:40:9e:f5:e4:58:84:67:8c -# SHA1 Fingerprint: 6b:2f:34:ad:89:58:be:62:fd:b0:6b:5c:ce:bb:9d:d9:4f:4e:39:f3 -# SHA256 Fingerprint: eb:f3:c0:2a:87:89:b1:fb:7d:51:19:95:d6:63:b7:29:06:d9:13:ce:0d:5e:10:56:8a:8a:77:e2:58:61:67:e7 ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV -BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1 -c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx -MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg -R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD -VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR -JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T -fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu -jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z -wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ -fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD -VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G -CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1 -7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn -8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs -ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT -ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/ -2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY ------END CERTIFICATE----- - -# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc -# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc -# Label: "Cybertrust Global Root" -# Serial: 4835703278459682877484360 -# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 -# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 -# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG -A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh -bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE -ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS -b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 -7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS -J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y -HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP -t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz -FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY -XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ -MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw -hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js -MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA -A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj -Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx -XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o -omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc -A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only -# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only -# Label: "GeoTrust Primary Certification Authority - G3" -# Serial: 28809105769928564313984085209975885599 -# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 -# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd -# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 ------BEGIN CERTIFICATE----- -MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB -mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT -MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s -eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ -BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg -MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 -BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz -+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm -hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn -5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W -JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL -DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC -huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw -HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB -AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB -zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN -kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD -AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH -SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G -spki4cErx5z481+oghLrGREt ------END CERTIFICATE----- - -# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only -# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only -# Label: "thawte Primary Root CA - G2" -# Serial: 71758320672825410020661621085256472406 -# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f -# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 -# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 ------BEGIN CERTIFICATE----- -MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp -IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi -BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw -MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh -d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig -YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v -dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ -BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 -papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K -DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 -KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox -XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== ------END CERTIFICATE----- - -# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only -# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only -# Label: "thawte Primary Root CA - G3" -# Serial: 127614157056681299805556476275995414779 -# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 -# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 -# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB -rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV -BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa -Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl -LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u -MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl -ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm -gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 -YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf -b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 -9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S -zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk -OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV -HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA -2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW -oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu -t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c -KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM -m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu -MdRAGmI0Nj81Aa6sY6A= ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only -# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only -# Label: "GeoTrust Primary Certification Authority - G2" -# Serial: 80682863203381065782177908751794619243 -# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a -# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 -# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 ------BEGIN CERTIFICATE----- -MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL -MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj -KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 -MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw -NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV -BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH -MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL -So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal -tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG -CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT -qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz -rD6ogRLQy7rQkgu2npaqBA+K ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only -# Label: "VeriSign Universal Root Certification Authority" -# Serial: 85209574734084581917763752644031726877 -# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 -# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 -# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c ------BEGIN CERTIFICATE----- -MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB -vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W -ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX -MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 -IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y -IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh -bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF -9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH -H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H -LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN -/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT -rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw -WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs -exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud -DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 -sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ -seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz -4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ -BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR -lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 -7M2CYfE45k+XmCpajQ== ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only -# Label: "VeriSign Class 3 Public Primary Certification Authority - G4" -# Serial: 63143484348153506665311985501458640051 -# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 -# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a -# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 ------BEGIN CERTIFICATE----- -MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp -U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg -SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln -biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm -GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve -fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ -aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj -aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW -kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC -4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga -FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== ------END CERTIFICATE----- - -# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority -# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority -# Label: "Verisign Class 3 Public Primary Certification Authority" -# Serial: 80507572722862485515306429940691309246 -# MD5 Fingerprint: ef:5a:f1:33:ef:f1:cd:bb:51:02:ee:12:14:4b:96:c4 -# SHA1 Fingerprint: a1:db:63:93:91:6f:17:e4:18:55:09:40:04:15:c7:02:40:b0:ae:6b -# SHA256 Fingerprint: a4:b6:b3:99:6f:c2:f3:06:b3:fd:86:81:bd:63:41:3d:8c:50:09:cc:4f:a3:29:c2:cc:f0:e2:fa:1b:14:03:05 ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz -cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 -MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV -BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt -YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN -ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE -BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is -I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G -CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i -2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ -2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 -# Label: "GlobalSign Root CA - R3" -# Serial: 4835703278459759426209954 -# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 -# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad -# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 -MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 -RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT -gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm -KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd -QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ -XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o -LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU -RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp -jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK -6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX -mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs -Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH -WD9f ------END CERTIFICATE----- - -# Issuer: CN=TC TrustCenter Universal CA III O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA -# Subject: CN=TC TrustCenter Universal CA III O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA -# Label: "TC TrustCenter Universal CA III" -# Serial: 2010889993983507346460533407902964 -# MD5 Fingerprint: 9f:dd:db:ab:ff:8e:ff:45:21:5f:f0:6c:9d:8f:fe:2b -# SHA1 Fingerprint: 96:56:cd:7b:57:96:98:95:d0:e1:41:46:68:06:fb:b8:c6:11:06:87 -# SHA256 Fingerprint: 30:9b:4a:87:f6:ca:56:c9:31:69:aa:a9:9c:6d:98:88:54:d7:89:2b:d5:43:7e:2d:07:b2:9c:be:da:55:d3:5d ------BEGIN CERTIFICATE----- -MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV -BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1 -c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAeFw0wOTA5MDkwODE1MjdaFw0yOTEy -MzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRl -ciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAm -BgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF -5+cvAqBNLaT6hdqbJYUtQCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYv -DIRlzg9uwliT6CwLOunBjvvya8o84pxOjuT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8v -zArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+EutCHnNaYlAJ/Uqwa1D7KRT -yGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1M4BDj5yj -dipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBh -MB8GA1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMB -Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI -4jANBgkqhkiG9w0BAQUFAAOCAQEAg8ev6n9NCjw5sWi+e22JLumzCecYV42Fmhfz -dkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+KGwWaODIl0YgoGhnYIg5IFHY -aAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhKBgePxLcHsU0G -DeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV -CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPH -LQNjO9Po5KIqwoIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg== ------END CERTIFICATE----- - -# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. -# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. -# Label: "Go Daddy Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 -# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b -# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz -NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE -AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD -E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH -/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy -DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh -GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR -tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA -AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX -WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu -9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr -gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo -2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI -4uJEvlz36hz1 ------END CERTIFICATE----- - -# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Label: "Starfield Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 -# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e -# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw -MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp -Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg -nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 -HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N -Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN -dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 -HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G -CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU -sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 -4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg -8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 -mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- - -# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Label: "Starfield Services Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 -# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f -# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs -ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy -dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p -OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 -8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K -Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe -hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk -6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q -AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI -bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB -ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z -qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn -0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN -sSi6 ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Commercial O=AffirmTrust -# Subject: CN=AffirmTrust Commercial O=AffirmTrust -# Label: "AffirmTrust Commercial" -# Serial: 8608355977964138876 -# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 -# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 -# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP -Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr -ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL -MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 -yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr -VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ -nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG -XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj -vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt -Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g -N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC -nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Networking O=AffirmTrust -# Subject: CN=AffirmTrust Networking O=AffirmTrust -# Label: "AffirmTrust Networking" -# Serial: 8957382827206547757 -# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f -# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f -# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y -YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua -kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL -QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp -6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG -yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i -QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO -tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu -QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ -Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u -olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 -x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Premium O=AffirmTrust -# Subject: CN=AffirmTrust Premium O=AffirmTrust -# Label: "AffirmTrust Premium" -# Serial: 7893706540734352110 -# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 -# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 -# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz -dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG -A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U -cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf -qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ -JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ -+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS -s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 -HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 -70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG -V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S -qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S -5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia -C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX -OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE -FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 -KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B -8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ -MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc -0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ -u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF -u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH -YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 -GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO -RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e -KeC2uAloGRwYQw== ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust -# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust -# Label: "AffirmTrust Premium ECC" -# Serial: 8401224907861490260 -# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d -# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb -# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC -VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ -cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ -BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt -VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D -0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 -ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G -A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs -aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I -flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== ------END CERTIFICATE----- - -# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing -# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing -# Label: "StartCom Certification Authority" -# Serial: 45 -# MD5 Fingerprint: c9:3b:0d:84:41:fc:a4:76:79:23:08:57:de:10:19:16 -# SHA1 Fingerprint: a3:f1:33:3f:e2:42:bf:cf:c5:d1:4e:8f:39:42:98:40:68:10:d1:a0 -# SHA256 Fingerprint: e1:78:90:ee:09:a3:fb:f4:f4:8b:9c:41:4a:17:d6:37:b7:a5:06:47:e9:bc:75:23:22:72:7f:cc:17:42:a9:11 ------BEGIN CERTIFICATE----- -MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul -F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC -ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w -ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk -aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 -YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg -c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 -d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG -CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF -wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS -Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst -0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc -pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl -CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF -P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK -1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm -KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE -JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ -8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm -fyWl8kgAwKQB2j8= ------END CERTIFICATE----- - -# Issuer: CN=StartCom Certification Authority G2 O=StartCom Ltd. -# Subject: CN=StartCom Certification Authority G2 O=StartCom Ltd. -# Label: "StartCom Certification Authority G2" -# Serial: 59 -# MD5 Fingerprint: 78:4b:fb:9e:64:82:0a:d3:b8:4c:62:f3:64:f2:90:64 -# SHA1 Fingerprint: 31:f1:fd:68:22:63:20:ee:c6:3b:3f:9d:ea:4a:3e:53:7c:7c:39:17 -# SHA256 Fingerprint: c7:ba:65:67:de:93:a7:98:ae:1f:aa:79:1e:71:2d:37:8f:ae:1f:93:c4:39:7f:ea:44:1b:b7:cb:e6:fd:59:95 ------BEGIN CERTIFICATE----- -MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 -OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG -A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ -JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD -vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo -D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ -Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW -RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK -HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN -nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM -0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i -UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 -Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg -TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL -BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K -2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX -UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl -6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK -9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ -HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI -wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY -XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l -IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo -hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr -so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI ------END CERTIFICATE----- diff --git a/chromium/tools/findit/common/http_client.py b/chromium/tools/findit/common/http_client.py deleted file mode 100644 index ae3349dac46..00000000000 --- a/chromium/tools/findit/common/http_client.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2014 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. - -class HttpClient(object): - """Represent a http client for sending request to a http[s] server. - - If cookies need to be sent, they should be in a file pointed to by - COOKIE_FILE in the environment. - """ - - @staticmethod - def Get(url, params={}, timeout=120, retries=5, retry_interval=0.5, - retry_if_not=None): - """Send a GET request to the given url with the given parameters. - - Args: - url: the url to send request to. - params: parameters to send as part of the http request. - timeout: timeout for the http request, default is 120 seconds. - retries: indicate how many retries before failing, default is 5. - retry_interval: interval in second to wait before retry, default is 0.5. - retry_if_not: a http status code. If set, retry only when the failed http - status code is a different value. - - Returns: - (status_code, data) - state_code: the http status code in the response. - data: the body of the response. - """ - raise NotImplemented() diff --git a/chromium/tools/findit/common/http_client_local.py b/chromium/tools/findit/common/http_client_local.py deleted file mode 100644 index b8a168dce24..00000000000 --- a/chromium/tools/findit/common/http_client_local.py +++ /dev/null @@ -1,253 +0,0 @@ -# Copyright (c) 2014 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 http client with support for https connections with certificate verification. - -The verification is based on http://tools.ietf.org/html/rfc6125#section-6.4.3 -and the code is from Lib/ssl.py in python3: - http://hg.python.org/cpython/file/4dac45f88d45/Lib/ssl.py - -One use case is to download Chromium DEPS file in a secure way: - https://src.chromium.org/chrome/trunk/src/DEPS - -Notice: python 2.7 or newer is required. -""" - -import cookielib -import httplib -import os -import re -import socket -import ssl -import time -import urllib -import urllib2 - -import http_client - - -_SCRIPT_DIR = os.path.dirname(__file__) -_TRUSTED_ROOT_CERTS = os.path.join(_SCRIPT_DIR, 'cacert.pem') - - -class CertificateError(ValueError): - pass - - -def _DNSNameMatch(dn, hostname, max_wildcards=1): - """Matching according to RFC 6125, section 6.4.3 - - http://tools.ietf.org/html/rfc6125#section-6.4.3 - """ - pats = [] - if not dn: - return False - - parts = dn.split(r'.') - leftmost = parts[0] - remainder = parts[1:] - - wildcards = leftmost.count('*') - if wildcards > max_wildcards: - # Issue #17980: avoid denials of service by refusing more - # than one wildcard per fragment. A survery of established - # policy among SSL implementations showed it to be a - # reasonable choice. - raise CertificateError( - 'too many wildcards in certificate DNS name: ' + repr(dn)) - - # speed up common case w/o wildcards - if not wildcards: - return dn.lower() == hostname.lower() - - # RFC 6125, section 6.4.3, subitem 1. - # The client SHOULD NOT attempt to match a presented identifier in which - # the wildcard character comprises a label other than the left-most label. - if leftmost == '*': - # When '*' is a fragment by itself, it matches a non-empty dotless - # fragment. - pats.append('[^.]+') - elif leftmost.startswith('xn--') or hostname.startswith('xn--'): - # RFC 6125, section 6.4.3, subitem 3. - # The client SHOULD NOT attempt to match a presented identifier - # where the wildcard character is embedded within an A-label or - # U-label of an internationalized domain name. - pats.append(re.escape(leftmost)) - else: - # Otherwise, '*' matches any dotless string, e.g. www* - pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) - - # add the remaining fragments, ignore any wildcards - for frag in remainder: - pats.append(re.escape(frag)) - - pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) - return pat.match(hostname) - - -def _MatchHostname(cert, hostname): - """Verify that *cert* (in decoded format as returned by - SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 - rules are followed, but IP addresses are not accepted for *hostname*. - - CertificateError is raised on failure. On success, the function - returns nothing. - """ - if not cert: - raise ValueError('empty or no certificate, match_hostname needs a ' - 'SSL socket or SSL context with either ' - 'CERT_OPTIONAL or CERT_REQUIRED') - dnsnames = [] - san = cert.get('subjectAltName', ()) - for key, value in san: - if key == 'DNS': - if _DNSNameMatch(value, hostname): - return - dnsnames.append(value) - if not dnsnames: - # The subject is only checked when there is no dNSName entry - # in subjectAltName - for sub in cert.get('subject', ()): - for key, value in sub: - # XXX according to RFC 2818, the most specific Common Name - # must be used. - if key == 'commonName': - if _DNSNameMatch(value, hostname): - return - dnsnames.append(value) - if len(dnsnames) > 1: - raise CertificateError('hostname %r doesn\'t match either of %s' - % (hostname, ', '.join(map(repr, dnsnames)))) - elif len(dnsnames) == 1: - raise CertificateError('hostname %r doesn\'t match %r' - % (hostname, dnsnames[0])) - else: - raise CertificateError('no appropriate commonName or ' - 'subjectAltName fields were found') - - -class HTTPSConnection(httplib.HTTPSConnection): - - def __init__(self, host, root_certs=_TRUSTED_ROOT_CERTS, **kwargs): - self.root_certs = root_certs - httplib.HTTPSConnection.__init__(self, host, **kwargs) - - def connect(self): - # Overrides for certificate verification. - args = [(self.host, self.port), self.timeout,] - if self.source_address: - args.append(self.source_address) - sock = socket.create_connection(*args) - - if self._tunnel_host: - self.sock = sock - self._tunnel() - - # Wrap the socket for verification with the root certs. - kwargs = {} - if self.root_certs is not None: - kwargs.update(cert_reqs=ssl.CERT_REQUIRED, ca_certs=self.root_certs) - self.sock = ssl.wrap_socket(sock, **kwargs) - - # Check hostname. - try: - _MatchHostname(self.sock.getpeercert(), self.host) - except CertificateError: - self.sock.shutdown(socket.SHUT_RDWR) - self.sock.close() - raise - - -class HTTPSHandler(urllib2.HTTPSHandler): - - def __init__(self, root_certs=_TRUSTED_ROOT_CERTS): - urllib2.HTTPSHandler.__init__(self) - self.root_certs = root_certs - - def https_open(self, req): - # Pass a reference to the function below so that verification against - # trusted root certs could be injected. - return self.do_open(self.GetConnection, req) - - def GetConnection(self, host, **kwargs): - params = dict(root_certs=self.root_certs) - params.update(kwargs) - return HTTPSConnection(host, **params) - - -def _SendRequest(url, timeout=None): - """Send request to the given https url, and return the server response. - - Args: - url: The https url to send request to. - - Returns: - An integer: http code of the response. - A string: content of the response. - - Raises: - CertificateError: Certificate verification fails. - """ - if not url: - return None, None - - handlers = [] - if url.startswith('https://'): - # HTTPSHandler has to go first, because we don't want to send secure cookies - # to a man in the middle. - handlers.append(HTTPSHandler()) - - - cookie_file = os.environ.get('COOKIE_FILE') - if cookie_file and os.path.exists(cookie_file): - handlers.append( - urllib2.HTTPCookieProcessor(cookielib.MozillaCookieJar(cookie_file))) - - url_opener = urllib2.build_opener(*handlers) - - status_code = None - content = None - - try: - response = url_opener.open(url, timeout=timeout) - - status_code = response.code - content = response.read() - except urllib2.HTTPError as e: - status_code = e.code - content = None - except (ssl.SSLError, httplib.BadStatusLine, IOError): - status_code = -1 - content = None - - return status_code, content - - -class HttpClientLocal(http_client.HttpClient): - """This http client is used locally in a workstation, GCE VMs, etc.""" - - @staticmethod - def Get(url, params={}, timeout=120, retries=5, retry_interval=0.5, - retry_if_not=None): - if params: - url = '%s?%s' % (url, urllib.urlencode(params)) - - count = 0 - while True: - count += 1 - - status_code, content = _SendRequest(url, timeout=timeout) - if status_code == 200: - return status_code, content - if retry_if_not and status_code == retry_if_not: - return status_code, content - - if count < retries: - time.sleep(retry_interval) - else: - return status_code, content - - # Should never be reached. - return status_code, content diff --git a/chromium/tools/findit/common/http_client_local_unittest.py b/chromium/tools/findit/common/http_client_local_unittest.py deleted file mode 100644 index 40d41fa5058..00000000000 --- a/chromium/tools/findit/common/http_client_local_unittest.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2014 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. - -import unittest - -from http_client_local import HttpClientLocal - -class HttpClientLocalTest(unittest.TestCase): - - def testGetWithoutParameters(self): - code, deps = HttpClientLocal.Get( - 'https://src.chromium.org/chrome/trunk/src/DEPS') - self.assertEqual(200, code) - self.assertTrue(isinstance(deps, str)) diff --git a/chromium/tools/findit/common/utils.py b/chromium/tools/findit/common/utils.py deleted file mode 100644 index 5011e76e2b1..00000000000 --- a/chromium/tools/findit/common/utils.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2011 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. - -import re -import sys - -from http_client_local import HttpClientLocal - - -GIT_HASH_PATTERN = re.compile(r'^[0-9a-fA-F]{40}$') - - -def GetOSName(platform_name=sys.platform): - if platform_name == 'cygwin' or platform_name.startswith('win'): - return 'win' - elif platform_name.startswith('linux'): - return 'unix' - elif platform_name.startswith('darwin'): - return 'mac' - else: - return platform_name - - -def IsGitHash(revision): - return GIT_HASH_PATTERN.match(str(revision)) - - -def GetHttpClient(): - # TODO(stgao): return implementation for appengine when running on appengine. - return HttpClientLocal - - -def JoinLineNumbers(line_numbers, accepted_gap=1): - """Join line numbers into line blocks. - - Args: - line_numbers: a list of line number. - accepted_gap: if two line numbers are within the give gap, - they would be combined together into a block. - Eg: for (1, 2, 3, 6, 7, 8, 12), if |accepted_gap| = 1, result - would be 1-3, 6-8, 12; if |accepted_gap| = 3, result would be - 1-8, 12; if |accepted_gap| =4, result would be 1-12. - """ - if not line_numbers: - return '' - - line_numbers = map(int, line_numbers) - line_numbers.sort() - - block = [] - start_line_number = line_numbers[0] - last_line_number = start_line_number - for current_line_number in line_numbers[1:]: - if last_line_number + accepted_gap < current_line_number: - if start_line_number == last_line_number: - block.append('%d' % start_line_number) - else: - block.append('%d-%d' % (start_line_number, last_line_number)) - start_line_number = current_line_number - last_line_number = current_line_number - else: - if start_line_number == last_line_number: - block.append('%d' % start_line_number) - else: - block.append('%d-%d' % (start_line_number, last_line_number)) - - return ', '.join(block) diff --git a/chromium/tools/findit/component_dictionary.py b/chromium/tools/findit/component_dictionary.py deleted file mode 100644 index d1a8967338e..00000000000 --- a/chromium/tools/findit/component_dictionary.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright (c) 2014 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. - - -class FileDictionary(object): - """Maps file in a stacktrace to its crash information. - - It maps file to another dictionary, which maps the file's path to crashed - lines, stack frame indices and crashed functions. - """ - - def __init__(self): - """Initializes the file dictionary.""" - self.file_dict = {} - - def AddFile(self, file_path, crashed_line_range, stack_frame_index, - function): - """Adds file and its crash information to the map. - - Args: - file_path: The path of the crashed file. - crashed_line_range: The crashed line of the file. - stack_frame_index: The file's position in the callstack. - function: The name of the crashed function. - """ - # Populate the dictionary if this file path has not been added before. - if file_path not in self.file_dict: - self.file_dict[file_path] = {} - self.file_dict[file_path]['line_numbers'] = [] - self.file_dict[file_path]['stack_frame_indices'] = [] - self.file_dict[file_path]['function'] = [] - - # Add the crashed line, frame index and function name. - self.file_dict[file_path]['line_numbers'].append( - crashed_line_range) - self.file_dict[file_path]['stack_frame_indices'].append( - stack_frame_index) - self.file_dict[file_path]['function'].append(function) - - def GetCrashedLineNumbers(self, file_path): - """Returns crashed line numbers given a file path.""" - return self.file_dict[file_path]['line_numbers'] - - def GetCrashStackFrameIndices(self, file_path): - """Returns stack frame indices given a file path.""" - return self.file_dict[file_path]['stack_frame_indices'] - - def GetCrashFunctions(self, file_path): - """Returns list of crashed functions given a file path.""" - return self.file_dict[file_path]['function'] - - def __iter__(self): - return iter(self.file_dict) - - -class ComponentDictionary(object): - """Represents a file dictionary. - - It maps each component path to a file dictionary. - """ - - def __init__(self, callstack, components): - """Initializes the dictionary with given components.""" - self.component_dict = {} - - # Create file dictionary for all the components. - for component in components: - self.component_dict[component] = FileDictionary() - - # Create file dict from callstack. - self.__CreateFileDictFromCallstack(callstack) - - def GetFileDict(self, component): - """Returns a file dictionary for a given component.""" - return self.component_dict.get(component) - - def __GenerateFileDict(self, stack_frame_list): - """Generates file dictionary, given an instance of StackFrame list.""" - # Iterate through the list of stackframe objects. - for stack_frame in stack_frame_list: - # If the component of this line is not in the list of components to - # look for, ignore this line. - component_path = stack_frame.component_path - if component_path not in self.component_dict: - continue - - # Get values of the variables - file_path = stack_frame.file_path - crashed_line_range = stack_frame.crashed_line_range - stack_frame_index = stack_frame.index - function = stack_frame.function - - # Add the file to this component's dictionary of files. - file_dict = self.component_dict[component_path] - file_dict.AddFile(file_path, crashed_line_range, stack_frame_index, - function) - - def __CreateFileDictFromCallstack(self, callstack, top_n_frames=10): - """Creates a file dict that maps a file to the occurrence in the stack. - - Args: - callstack: A list containing parsed result from a single stack - within a stacktrace. For example, a stacktrace from - previously-allocated thread in release build stacktrace. - top_n_frames: The number of frames to look for. - - Returns: - Component_dict, a dictionary with key as a file name and value as another - dictionary, which maps the file's path (because there can be multiple - files with same name but in different directory) to the list of this - file's place in stack, lines that this file caused a crash, and the name - of the function. - """ - - # Only look at first top_n_frames of the stacktrace, below those are likely - # to be noisy. Parse the stacktrace into the component dictionary. - stack_list = callstack.GetTopNFrames(top_n_frames) - self.__GenerateFileDict(stack_list) - - def __iter__(self): - return iter(self.component_dict) diff --git a/chromium/tools/findit/config.ini b/chromium/tools/findit/config.ini deleted file mode 100644 index f6071ecf274..00000000000 --- a/chromium/tools/findit/config.ini +++ /dev/null @@ -1,26 +0,0 @@ -[svn:src/] -changelog_url: http://build.chromium.org/cgi-bin/svn-log?url=http://src.chromium.org/svn/trunk/src/&range=%s -revision_url: http://src.chromium.org/viewvc/chrome?revision=%d&view=revision -diff_url: http://src.chromium.org/viewvc/chrome/trunk/%s?r1=%d&r2=%d&pathrev=%d -blame_url: http://src.chromium.org/viewvc/chrome/trunk/%s?annotate=%s&pathrev=%s - -[svn:src/third_party/WebKit/] -changelog_url: http://build.chromium.org/cgi-bin/svn-log?url=http://src.chromium.org/blink/trunk/&range=%s -revision_url: http://src.chromium.org/viewvc/blink?revision=%d&view=revision -diff_url: http://src.chromium.org/viewvc/blink/trunk/%s?r1=%d&r2=%d&pathrev=%d -blame_url: http://src.chromium.org/viewvc/blink/trunk/%s?annotate=%s&pathrev=%s - -[svn:src/third_party/WebKit/Source/] -changelog_url: http://build.chromium.org/cgi-bin/svn-log?url=http://src.chromium.org/blink/trunk/&range=%s -revision_url: http://src.chromium.org/viewvc/blink?revision=%d&view=revision -diff_url: http://src.chromium.org/viewvc/blink/trunk/%s?r1=%d&r2=%d&pathrev=%d -blame_url: http://src.chromium.org/viewvc/blink/trunk/%s?annotate=%s&pathrev=%s - -[git] -changelog_url: /+log/%s..%s -revision_url: /+/%s -diff_url: /+/%s^!/%s -blame_url: /+blame/%s/%s?format=json - -[codereview] -review_url: https://codereview.chromium.org/api/%s?message=true diff --git a/chromium/tools/findit/crash_utils.py b/chromium/tools/findit/crash_utils.py deleted file mode 100644 index 7e8011334e2..00000000000 --- a/chromium/tools/findit/crash_utils.py +++ /dev/null @@ -1,570 +0,0 @@ -# Copyright (c) 2014 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. - -import atexit -import cgi -import ConfigParser -import json -import os -import Queue -import threading -import time - -from common import utils -from result import Result - - -INFINITY = float('inf') - -MAX_THREAD_NUMBER = 10 -TASK_QUEUE = None - - -def SignalWorkerThreads(): - global TASK_QUEUE - if not TASK_QUEUE: - return - - for i in range(MAX_THREAD_NUMBER): - TASK_QUEUE.put(None) - - # Give worker threads a chance to exit. - # Workaround the harmless bug in python 2.7 below. - time.sleep(1) - - -atexit.register(SignalWorkerThreads) - - -def Worker(): - global TASK_QUEUE - while True: - try: - task = TASK_QUEUE.get() - if not task: - return - except TypeError: - # According to http://bugs.python.org/issue14623, this is a harmless bug - # in python 2.7 which won't be fixed. - # The exception is raised on daemon threads when python interpreter is - # shutting down. - return - - function, args, kwargs, result_semaphore = task - try: - function(*args, **kwargs) - except: - pass - finally: - # Signal one task is done in case of exception. - result_semaphore.release() - - -def RunTasks(tasks): - """Run given tasks. Not thread-safe: no concurrent calls of this function. - - Return after all tasks were completed. A task is a dict as below: - { - 'function': the function to call, - 'args': the positional argument to pass to the function, - 'kwargs': the key-value arguments to pass to the function, - } - """ - if not tasks: - return - - global TASK_QUEUE - if not TASK_QUEUE: - TASK_QUEUE = Queue.Queue() - for index in range(MAX_THREAD_NUMBER): - thread = threading.Thread(target=Worker, name='worker_%s' % index) - # Set as daemon, so no join is needed. - thread.daemon = True - thread.start() - - result_semaphore = threading.Semaphore(0) - # Push task to task queue for execution. - for task in tasks: - TASK_QUEUE.put( - (task['function'], task.get('args', []), - task.get('kwargs', {}), result_semaphore)) - - # Wait until all tasks to be executed. - for _ in tasks: - result_semaphore.acquire() - - -def GetRepositoryType(revision_number): - """Returns the repository type of this revision number. - - Args: - revision_number: A revision number or git hash. - - Returns: - 'git' or 'svn', depending on the revision_number. - """ - if utils.IsGitHash(revision_number): - return 'git' - else: - return 'svn' - - -def ParseURLsFromConfig(file_name): - """Parses URLS from the config file. - - The file should be in python config format, where svn section is in the - format "svn:component_path". - Each of the section for svn should contain changelog_url, revision_url, - diff_url and blame_url. - - Args: - file_name: The name of the file that contains URL information. - - Returns: - A dictionary that maps repository type to list of URLs. For svn, it maps - key 'svn' to another dictionary, which maps component path to the URLs - as explained above. For git, it maps to the URLs as explained above. - """ - config = ConfigParser.ConfigParser() - - # Get the absolute path of the config file, and read the file. If it fails, - # return none. - config_file_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), - file_name) - config.read(config_file_path) - if not config: - return None - - # Iterate through the config file, check for sections. - config_dict = {} - for section in config.sections(): - # These two do not need another layer of dictionary, so add it and go - # to next section. - if ':' not in section: - for option in config.options(section): - if section not in config_dict: - config_dict[section] = {} - - url = config.get(section, option) - config_dict[section][option] = url - - continue - - # Get repository type and component name from the section name. - repository_type_and_component = section.split(':') - repository_type = repository_type_and_component[0] - component_path = repository_type_and_component[1] - - # Add 'svn' as the key, if it is not already there. - if repository_type not in config_dict: - config_dict[repository_type] = {} - url_map_for_repository = config_dict[repository_type] - - # Add the path to the 'svn', if it is not already there. - if component_path not in url_map_for_repository: - url_map_for_repository[component_path] = {} - type_to_url = url_map_for_repository[component_path] - - # Add all URLs to this map. - for option in config.options(section): - url = config.get(section, option) - type_to_url[option] = url - - return config_dict - - -def NormalizePath(path, parsed_deps): - """Normalizes the path. - - Args: - path: A string representing a path. - parsed_deps: A map from component path to its component name, repository, - etc. - - Returns: - A tuple containing a component this path is in (e.g blink, skia, etc) - and a path in that component's repository. Returns None if the component - repository is not supported, i.e from googlecode. - """ - # First normalize the path by retreiving the normalized path. - normalized_path = os.path.normpath(path).replace('\\', '/') - - # Iterate through all component paths in the parsed DEPS, in the decreasing - # order of the length of the file path. - for component_path in sorted(parsed_deps, - key=(lambda path: -len(path))): - # new_component_path is the component path with 'src/' removed. - new_component_path = component_path - if new_component_path.startswith('src/') and new_component_path != 'src/': - new_component_path = new_component_path[len('src/'):] - - # We need to consider when the lowercased component path is in the path, - # because syzyasan build returns lowercased file path. - lower_component_path = new_component_path.lower() - - # If this path is the part of file path, this file must be from this - # component. - if new_component_path in normalized_path or \ - lower_component_path in normalized_path: - - # Case when the retreived path is in lowercase. - if lower_component_path in normalized_path: - current_component_path = lower_component_path - else: - current_component_path = new_component_path - - # Normalize the path by stripping everything off the component's relative - # path. - normalized_path = normalized_path.split(current_component_path, 1)[1] - lower_normalized_path = normalized_path.lower() - - # Add 'src/' or 'Source/' at the front of the normalized path, depending - # on what prefix the component path uses. For example, blink uses - # 'Source' but chromium uses 'src/', and blink component path is - # 'src/third_party/WebKit/Source', so add 'Source/' in front of the - # normalized path. - if (lower_component_path == 'src/third_party/webkit/source' and - not lower_normalized_path.startswith('source/')): - normalized_path = (current_component_path.split('/')[-2] + '/' + - normalized_path) - - component_name = parsed_deps[component_path]['name'] - - return (component_path, component_name, normalized_path) - - # If the path does not match any component, default to chromium. - return ('src/', 'chromium', normalized_path) - - -def SplitRange(regression): - """Splits a range as retrieved from clusterfuzz. - - Args: - regression: A string in format 'r1234:r5678'. - - Returns: - A list containing two numbers represented in string, for example - ['1234','5678']. - """ - if not regression: - return None - - revisions = regression.split(':') - - # If regression information is not available, return none. - if len(revisions) != 2: - return None - - range_start = revisions[0] - range_end = revisions[1] - - # Strip 'r' off the range start/end. Not using lstrip to avoid the case when - # the range is in git hash and it starts with 'r'. - if range_start.startswith('r'): - range_start = range_start[1:] - - if range_end.startswith('r'): - range_end = range_end[1:] - - return [range_start, range_end] - - -def LoadJSON(json_string): - """Loads json object from string, or None. - - Args: - json_string: A string to get object from. - - Returns: - JSON object if the string represents a JSON object, None otherwise. - """ - try: - data = json.loads(json_string) - except ValueError: - data = None - - return data - - -def GetDataFromURL(url): - """Retrieves raw data from URL, tries 10 times. - - Args: - url: URL to get data from. - retries: Number of times to retry connection. - - Returns: - None if the data retrieval fails, or the raw data. - """ - status_code, data = utils.GetHttpClient().Get(url, retries=10) - if status_code == 200: - return data - else: - # Return None if it fails to read data. - return None - - -def FindMinLineDistance(crashed_line_list, changed_line_numbers, - line_range=3): - """Calculates how far the changed line is from one of the crashes. - - Finds the minimum distance between the lines that the file crashed on - and the lines that the file changed. For example, if the file crashed on - line 200 and the CL changes line 203,204 and 205, the function returns 3. - - Args: - crashed_line_list: A list of lines that the file crashed on. - changed_line_numbers: A list of lines that the file changed. - line_range: Number of lines to look back for. - - Returns: - The minimum distance. If either of the input lists is empty, - it returns inf. - - """ - min_distance = INFINITY - crashed_line = -1 - changed_line = -1 - - crashed_line_numbers = set() - for crashed_line_range in crashed_line_list: - for crashed_line in crashed_line_range: - for line in range(crashed_line - line_range, crashed_line + 1): - crashed_line_numbers.add(line) - - for line in crashed_line_numbers: - for distance in changed_line_numbers: - # Find the current distance and update the min if current distance is - # less than current min. - current_distance = abs(line - distance) - if current_distance < min_distance: - min_distance = current_distance - crashed_line = line - changed_line = distance - - return (min_distance, crashed_line, changed_line) - - -def GuessIfSameSubPath(path1, path2): - """Guesses if two paths represent same path. - - Compares the name of the folders in the path (by split('/')), and checks - if they match either more than 3 or min of path lengths. - - Args: - path1: First path. - path2: Second path to compare. - - Returns: - True if it they are thought to be a same path, False otherwise. - """ - path1 = path1.split('/') - path2 = path2.split('/') - - intersection = set(path1).intersection(set(path2)) - return len(intersection) >= (min(3, min(len(path1), len(path2)))) - - -def FindMinStackFrameNumber(stack_frame_indices, priorities): - """Finds the minimum stack number, from the list of stack numbers. - - Args: - stack_frame_indices: A list of lists containing stack position. - priorities: A list of of priority for each file. - - Returns: - Inf if stack_frame_indices is empty, minimum stack number otherwise. - """ - # Get the indexes of the highest priority (or low priority number). - highest_priority = min(priorities) - highest_priority_indices = [] - for i in range(len(priorities)): - if priorities[i] == highest_priority: - highest_priority_indices.append(i) - - # Gather the list of stack frame numbers for the files that change the - # crash lines. - flattened = [] - for i in highest_priority_indices: - flattened += stack_frame_indices[i] - - # If no stack frame information is available, return inf. Else, return min. - if not flattened: - return INFINITY - else: - return min(flattened) - - -def AddHyperlink(text, link): - """Returns a string with HTML link tag. - - Args: - text: A string to add link. - link: A link to add to the string. - - Returns: - A string with hyperlink added. - """ - sanitized_link = cgi.escape(link, quote=True) - sanitized_text = cgi.escape(str(text)) - return '<a href="%s">%s</a>' % (sanitized_link, sanitized_text) - - -def PrettifyList(items): - """Returns a string representation of a list. - - It adds comma in between the elements and removes the brackets. - Args: - items: A list to prettify. - Returns: - A string representation of the list. - """ - return ', '.join(map(str, items)) - - -def PrettifyFrameInfo(frame_indices, functions): - """Return a string to represent the frames with functions.""" - frames = [] - for frame_index, function in zip(frame_indices, functions): - frames.append('frame #%s, "%s"' % (frame_index, function.split('(')[0])) - return '; '.join(frames) - - -def PrettifyFiles(file_list): - """Returns a string representation of a list of file names. - - Args: - file_list: A list of tuple, (file_name, file_url). - Returns: - A string representation of file names with their urls. - """ - ret = ['\n'] - for file_name, file_url in file_list: - ret.append(' %s\n' % AddHyperlink(file_name, file_url)) - return ''.join(ret) - - -def Intersection(crashed_line_list, stack_frame_index, changed_line_numbers, - function, line_range=3): - """Finds the overlap betwee changed lines and crashed lines. - - Finds the intersection of the lines that caused the crash and - lines that the file changes. The intersection looks within 3 lines - of the line that caused the crash. - - Args: - crashed_line_list: A list of lines that the file crashed on. - stack_frame_index: A list of positions in stack for each of the lines. - changed_line_numbers: A list of lines that the file changed. - function: A list of functions that the file crashed on. - line_range: Number of lines to look backwards from crashed lines. - - Returns: - line_number_intersection: Intersection between crashed_line_list and - changed_line_numbers. - stack_frame_index_intersection: Stack number for each of the intersections. - """ - line_number_intersection = [] - stack_frame_index_intersection = [] - function_intersection = [] - - # Iterate through the crashed lines, and its occurence in stack. - for (lines, stack_frame_index, function_name) in zip( - crashed_line_list, stack_frame_index, function): - # Also check previous 'line_range' lines. Create a set of all changed lines - # and lines within 3 lines range before the crashed line. - line_minus_n = set() - for line in lines: - for line_in_range in range(line - line_range, line + 1): - line_minus_n.add(line_in_range) - - for changed_line in changed_line_numbers: - # If a CL does not change crahsed line, check next line. - if changed_line not in line_minus_n: - continue - - intersected_line = set() - # If the changed line is exactly the crashed line, add that line. - for line in lines: - if line in changed_line_numbers: - intersected_line.add(line) - - # If the changed line is in 3 lines of the crashed line, add the line. - else: - intersected_line.add(changed_line) - - # Avoid adding the same line twice. - if intersected_line not in line_number_intersection: - line_number_intersection.append(list(intersected_line)) - stack_frame_index_intersection.append(stack_frame_index) - function_intersection.append(function_name) - break - - return (line_number_intersection, stack_frame_index_intersection, - function_intersection) - - -def MatchListToResultList(matches): - """Convert list of matches to the list of result objects. - - Args: - matches: A list of match objects along with its stack priority and revision - number/git hash - Returns: - A list of result object. - - """ - result_list = [] - - for _, cl, match in matches: - suspected_cl = cl - revision_url = match.revision_url - component_name = match.component_name - author = match.author - reason = match.reason.strip() - review_url = match.review_url - reviewers = match.reviewers - # For matches, line content do not exist. - line_content = None - message = match.message - time = match.time - - result = Result(suspected_cl, revision_url, component_name, author, reason, - review_url, reviewers, line_content, message, time) - result_list.append(result) - - return result_list - - -def BlameListToResultList(blame_list): - """Convert blame list to the list of result objects. - - Args: - blame_list: A list of blame objects. - - Returns: - A list of result objects. - """ - result_list = [] - - for blame in blame_list: - suspected_cl = blame.revision - revision_url = blame.url - component_name = blame.component_name - author = blame.author - reason = ( - 'The CL last changed line %s of file %s, which is stack frame %d.' % - (blame.line_number, blame.file, blame.stack_frame_index)) - time = blame.time - # Blame object does not have review url and reviewers. - review_url = None - reviewers = None - line_content = blame.line_content - message = blame.message - - result = Result(suspected_cl, revision_url, component_name, author, reason, - review_url, reviewers, line_content, message, time) - result_list.append(result) - - return result_list diff --git a/chromium/tools/findit/deps_config.json b/chromium/tools/findit/deps_config.json deleted file mode 100644 index 57b41f9b2bf..00000000000 --- a/chromium/tools/findit/deps_config.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "cr_rev_url": "https://cr-rev.appspot.com/_ah/api/crrev/v1/redirect/%s", - "chromium_git_base_url": "https://chromium.googlesource.com/chromium/src/", - "chromium_git_file_url": - "https://chromium.googlesource.com/chromium/src/+/%s/%s?format=text", - "host_directories": [ - "src/chrome/browser/resources/", - "src/chrome/test/data/layout_tests/", - "src/media/", - "src/sdch/", - "src/testing/", - "src/third_party/WebKit/", - "src/third_party/", - "src/tools/", - "src/" - ] -} diff --git a/chromium/tools/findit/findit_for_clusterfuzz.py b/chromium/tools/findit/findit_for_clusterfuzz.py deleted file mode 100644 index c101fbcae36..00000000000 --- a/chromium/tools/findit/findit_for_clusterfuzz.py +++ /dev/null @@ -1,224 +0,0 @@ -# Copyright (c) 2014 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. - -import chromium_deps -from common import utils -import crash_utils -import findit_for_crash as findit -import stacktrace - - -def SplitStacktrace(stacktrace_string): - """Preprocesses stacktrace string into two parts, release and debug. - - Args: - stacktrace_string: A string representation of stacktrace, - in clusterfuzz format. - - Returns: - A tuple of list of strings, release build stacktrace and - debug build stacktrace. - """ - # Make sure we only parse release/debug build stacktrace, and ignore - # unsymbolised stacktrace. - in_release_or_debug_stacktrace = False - release_build_stacktrace_lines = None - debug_build_stacktrace_lines = None - current_stacktrace_lines = [] - - # Iterate through all lines in stacktrace. - for line in stacktrace_string.splitlines(): - line = line.strip() - - # If the line starts with +, it signifies the start of new stacktrace. - if line.startswith('+-') and line.endswith('-+'): - if 'Release Build Stacktrace' in line: - in_release_or_debug_stacktrace = True - current_stacktrace_lines = [] - release_build_stacktrace_lines = current_stacktrace_lines - - elif 'Debug Build Stacktrace' in line: - in_release_or_debug_stacktrace = True - current_stacktrace_lines = [] - debug_build_stacktrace_lines = current_stacktrace_lines - - # If the stacktrace is neither release/debug build stacktrace, ignore - # all lines after it until we encounter release/debug build stacktrace. - else: - in_release_or_debug_stacktrace = False - - # This case, it must be that the line is an actual stack frame, so add to - # the current stacktrace. - elif in_release_or_debug_stacktrace: - current_stacktrace_lines.append(line) - - return (release_build_stacktrace_lines, debug_build_stacktrace_lines) - - -def FindCulpritCLs(stacktrace_string, - build_type, - chrome_regression=None, - component_regression=None, - chrome_crash_revision=None, - component_crash_revision=None, - crashing_component_path=None, - crashing_component_name=None, - crashing_component_repo_url=None): - """Returns the result, a list of result.Result objects and message. - - If either or both of component_regression and component_crash_revision is not - None, is is assumed that crashing_component_path and - crashing_component_repo_url are not None. - - Args: - stacktrace_string: A string representing stacktrace. - build_type: The type of the job. - chrome_regression: A string, chrome regression from clusterfuzz, in format - '123456:123457' - component_regression: A string, component regression in the same format. - chrome_crash_revision: A crash revision of chrome, in string. - component_crash_revision: A crash revision of the component, - if component build. - crashing_component_path: A relative path of the crashing component, as in - DEPS file. For example, it would be 'src/v8' for - v8 and 'src/third_party/WebKit' for blink. - crashing_component_name: A name of the crashing component, such as v8. - crashing_component_repo_url: The URL of the crashing component's repo, as - shown in DEPS file. For example, - 'https://chromium.googlesource.com/skia.git' - for skia. - - Returns: - A list of result objects, along with the short description on where the - result is from. - """ - build_type = build_type.lower() - component_to_crash_revision_dict = {} - component_to_regression_dict = {} - - # If chrome regression is available, parse DEPS file. - chrome_regression = crash_utils.SplitRange(chrome_regression) - if chrome_regression: - chrome_regression_start = chrome_regression[0] - chrome_regression_end = chrome_regression[1] - - # Do not parse regression information for crashes introduced before the - # first archived build. - if chrome_regression_start != '0': - component_to_regression_dict = chromium_deps.GetChromiumComponentRange( - chrome_regression_start, chrome_regression_end) - if not component_to_regression_dict: - return (('Failed to get component regression ranges for chromium ' - 'regression range %s:%s' - % (chrome_regression_start, chrome_regression_end)), []) - - # Parse crash revision. - if chrome_crash_revision: - component_to_crash_revision_dict = chromium_deps.GetChromiumComponents( - chrome_crash_revision) - if not component_to_crash_revision_dict: - return (('Failed to get component dependencies for chromium revision "%s"' - % chrome_crash_revision), []) - - # Check if component regression information is available. - component_regression = crash_utils.SplitRange(component_regression) - if component_regression: - component_regression_start = component_regression[0] - component_regression_end = component_regression[1] - - # If this component already has an entry in parsed DEPS file, overwrite - # regression range and url. - if crashing_component_path in component_to_regression_dict: - component_regression_info = \ - component_to_regression_dict[crashing_component_path] - component_regression_info['old_revision'] = component_regression_start - component_regression_info['new_revision'] = component_regression_end - component_regression_info['repository'] = crashing_component_repo_url - - # if this component does not have an entry, add the entry to the parsed - # DEPS file. - else: - repository_type = crash_utils.GetRepositoryType( - component_regression_start) - component_regression_info = { - 'path': crashing_component_path, - 'rolled': True, - 'name': crashing_component_name, - 'old_revision': component_regression_start, - 'new_revision': component_regression_end, - 'repository': crashing_component_repo_url, - 'repository_type': repository_type - } - component_to_regression_dict[crashing_component_path] = \ - component_regression_info - - # If component crash revision is available, add it to the parsed crash - # revisions. - if component_crash_revision: - - # If this component has already a crash revision info, overwrite it. - if crashing_component_path in component_to_crash_revision_dict: - component_crash_revision_info = \ - component_to_crash_revision_dict[crashing_component_path] - component_crash_revision_info['revision'] = component_crash_revision - component_crash_revision_info['repository'] = crashing_component_repo_url - - # If not, add it to the parsed DEPS. - else: - if utils.IsGitHash(component_crash_revision): - repository_type = 'git' - else: - repository_type = 'svn' - component_crash_revision_info = { - 'path': crashing_component_path, - 'name': crashing_component_name, - 'repository': crashing_component_repo_url, - 'repository_type': repository_type, - 'revision': component_crash_revision - } - component_to_crash_revision_dict[crashing_component_path] = \ - component_crash_revision_info - - # Parsed DEPS is used to normalize the stacktrace. Since parsed regression - # and parsed crash state essentially contain same information, use either. - if component_to_regression_dict: - parsed_deps = component_to_regression_dict - elif component_to_crash_revision_dict: - parsed_deps = component_to_crash_revision_dict - else: - return (('Identifying culprit CL requires at lease one of regression ' - 'information or crash revision'), []) - - # Split stacktrace into release build/debug build and parse them. - (release_build_stacktrace, debug_build_stacktrace) = SplitStacktrace( - stacktrace_string) - if not (release_build_stacktrace or debug_build_stacktrace): - parsed_release_build_stacktrace = stacktrace.Stacktrace( - stacktrace_string.splitlines(), build_type, parsed_deps) - else: - parsed_release_build_stacktrace = stacktrace.Stacktrace( - release_build_stacktrace, build_type, parsed_deps) - - parsed_debug_build_stacktrace = stacktrace.Stacktrace( - debug_build_stacktrace, build_type, parsed_deps) - - # Get a highest priority callstack (main_stack) from stacktrace, with release - # build stacktrace in higher priority than debug build stacktace. This stack - # is the callstack to find blame information for. - if parsed_release_build_stacktrace.stack_list: - main_stack = parsed_release_build_stacktrace.GetCrashStack() - elif parsed_debug_build_stacktrace.stack_list: - main_stack = parsed_debug_build_stacktrace.GetCrashStack() - else: - if 'mac_' in build_type: - return ('No line information available in stacktrace.', []) - - return ('Findit failed to find any stack trace. Is it in a new format?', []) - - # Run the algorithm on the parsed stacktrace, and return the result. - stacktrace_list = [parsed_release_build_stacktrace, - parsed_debug_build_stacktrace] - return findit.FindItForCrash( - stacktrace_list, main_stack, component_to_regression_dict, - component_to_crash_revision_dict) diff --git a/chromium/tools/findit/findit_for_crash.py b/chromium/tools/findit/findit_for_crash.py deleted file mode 100644 index 689294987ca..00000000000 --- a/chromium/tools/findit/findit_for_crash.py +++ /dev/null @@ -1,664 +0,0 @@ -# Copyright (c) 2014 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. - -import os -from threading import Lock - -import blame -from common import utils -import component_dictionary -import crash_utils -import git_repository_parser -import match_set -import svn_repository_parser - - -LINE_CHANGE_PRIORITY = 1 -FILE_CHANGE_PRIORITY = 2 -_THIS_DIR = os.path.abspath(os.path.dirname(__file__)) -CONFIG = crash_utils.ParseURLsFromConfig(os.path.join(_THIS_DIR, - 'config.ini')) - - -def GenerateMatchEntry( - matches, revision_info, revision_number, file_path, function, - component_path, component_name, crashed_line_numbers, stack_frame_indices, - file_change_type, repository_parser): - """Generates a match object and adds it to the match set. - - Args: - matches: A matchset object, a map from CL to a match object. - revision_info: The revision information, a map from fields (message, - changed files, etc) to its values. - revision_number: The SVN revision number or git hash. - file_path: The path of the file. - function: The function that caused an crash. - component_path: The path of the component this file is from. - component_name: The name of the component the file is from. - crashed_line_numbers: The list of the lines in the file that caused - the crash. - stack_frame_indices: The list of positions of this file within a stack. - file_change_type: Whether file is modified, added or deleted. - repository_parser: The parser object to parse line diff. - """ - # Check if this CL should be ignored. - with matches.matches_lock: - if revision_number in matches.cls_to_ignore: - return - - # If this CL is not already identified as suspected, create a new entry. - if revision_number not in matches.matches: - match = match_set.Match(revision_info, component_name) - message = revision_info['message'] - # TODO(jeun): Don't hold lock while issuing http request. - match.ParseMessage(message, matches.codereview_api_url) - - # If this match is a revert, add to the set of CLs to be ignored. - if match.is_revert: - matches.cls_to_ignore.add(revision_number) - - # If this match has info on what CL it is reverted from, add that CL. - if match.revert_of: - matches.cls_to_ignore.add(match.revert_of) - - return - - matches.matches[revision_number] = match - - else: - match = matches.matches[revision_number] - - (diff_url, changed_line_numbers, changed_line_contents) = ( - repository_parser.ParseLineDiff( - file_path, component_path, file_change_type, revision_number)) - - # Ignore this match if the component is not supported for svn. - if not diff_url: - return - - # Find the intersection between the lines that this file crashed on and - # the changed lines. - (line_number_intersection, stack_frame_index_intersection, functions) = ( - crash_utils.Intersection( - crashed_line_numbers, stack_frame_indices, changed_line_numbers, - function)) - - # Find the minimum distance between the changed lines and crashed lines. - (min_distance, min_crashed_line, min_changed_line) = \ - crash_utils.FindMinLineDistance(crashed_line_numbers, - changed_line_numbers) - - # Check whether this CL changes the crashed lines or not. - if line_number_intersection: - priority = LINE_CHANGE_PRIORITY - else: - priority = FILE_CHANGE_PRIORITY - - # Add the parsed information to the object. - with matches.matches_lock: - match.crashed_line_numbers.append(line_number_intersection) - - file_name = file_path.split('/')[-1] - match.changed_files.append(file_name) - - # Update the min distance only if it is less than the current one. - if min_distance < match.min_distance: - match.min_distance = min_distance - match.min_distance_info = (file_name, min_crashed_line, min_changed_line) - - # If this CL does not change the crashed line, all occurrence of this - # file in the stack has the same priority. - if not stack_frame_index_intersection: - stack_frame_index_intersection = stack_frame_indices - functions = function - match.stack_frame_indices.append(stack_frame_index_intersection) - match.changed_file_urls.append(diff_url) - match.priorities.append(priority) - match.function_list.append(functions) - - -def FindMatch(revisions_info_map, file_to_revision_info, file_to_crash_info, - component_path, component_name, repository_parser, - codereview_api_url): - """Finds a CL that modifies file in the stacktrace. - - Args: - revisions_info_map: A dictionary mapping revision number to the CL - information. - file_to_revision_info: A dictionary mapping file to the revision that - modifies it. - file_to_crash_info: A dictionary mapping file to its occurrence in - stacktrace. - component_path: The path of the component to search for. - component_name: The name of the component to search for. - repository_parser: The parser object to parse the line diff. - codereview_api_url: A code review url to retrieve data from. - - Returns: - Matches, a set of match objects. - """ - matches = match_set.MatchSet(codereview_api_url) - - tasks = [] - # Iterate through the crashed files in the stacktrace. - for crashed_file_path in file_to_crash_info: - # Ignore header file. - if crashed_file_path.endswith('.h'): - continue - - # If the file in the stacktrace is not changed in any commits, continue. - for changed_file_path in file_to_revision_info: - changed_file_name = changed_file_path.split('/')[-1].lower() - crashed_file_name = crashed_file_path.split('/')[-1].lower() - if changed_file_name != crashed_file_name: - continue - - if not crash_utils.GuessIfSameSubPath( - changed_file_path.lower(), crashed_file_path.lower()): - continue - - crashed_line_numbers = file_to_crash_info.GetCrashedLineNumbers( - crashed_file_path) - stack_frame_nums = file_to_crash_info.GetCrashStackFrameIndices( - crashed_file_path) - functions = file_to_crash_info.GetCrashFunctions(crashed_file_path) - - # Iterate through the CLs that this file path is changed. - for (cl, file_change_type) in file_to_revision_info[changed_file_path]: - # If the file change is delete, ignore this CL. - if file_change_type == 'D': - continue - - revision = revisions_info_map[cl] - - tasks.append({ - 'function': GenerateMatchEntry, - 'args':[matches, revision, cl, changed_file_path, functions, - component_path, component_name, crashed_line_numbers, - stack_frame_nums, file_change_type, - repository_parser]}) - - # Run all the tasks. - crash_utils.RunTasks(tasks) - - matches.RemoveRevertedCLs() - - return matches - - -def FindMatchForComponent(component_path, file_to_crash_info, changelog, - callstack_priority, results, results_lock): - """Parses changelog and finds suspected CLs for a given component. - - Args: - component_path: The path of component to look for the culprit CL. - file_to_crash_info: A dictionary mapping file to its occurrence in - stackframe. - changelog: The parsed changelog for this component. - callstack_priority: The priority of this call stack, 0 if from crash stack, - 1 if from freed, 2 if from previously allocated. - results: A dictionary to store the result. - results_lock: A lock that guards results. - """ - (repository_parser, component_name, revisions, file_to_revision_map) = \ - changelog - - # Find match for this component. - codereview_api_url = CONFIG['codereview']['review_url'] - component_result = FindMatch( - revisions, file_to_revision_map, file_to_crash_info, component_path, - component_name, repository_parser, codereview_api_url) - matches = component_result.matches - - # For all the match results in a dictionary, add to the list so that it - # can be sorted. - with results_lock: - for cl in matches: - match = matches[cl] - results.append((callstack_priority, cl, match)) - - -def FindMatchForCallstack( - callstack, components, component_to_changelog_map, results, - results_lock): - """Finds culprit cl for a stack within a stacktrace. - - For each components to look for, create new thread that computes the matches - and join the results at the end. - - Args: - callstack: A callstack in a stacktrace to find the result for. - components: A set of components to look for. - component_to_changelog_map: A map from component to its parsed changelog. - results: A list to aggregrate results from all stacktraces. - results_lock: A lock that guards results. - """ - # Create component dictionary from the component and call stack. - component_dict = component_dictionary.ComponentDictionary(callstack, - components) - callstack_priority = callstack.priority - - # Iterate through all components. - for component_path in component_dict: - # If the component to consider in this callstack is not in the parsed list - # of components, ignore this one. - if component_path not in component_to_changelog_map: - continue - - changelog = component_to_changelog_map[component_path] - file_to_crash_info = component_dict.GetFileDict(component_path) - FindMatchForComponent(component_path, file_to_crash_info, changelog, - callstack_priority, results, results_lock) - - -def FindMatchForStacktrace(stacktrace, components, - component_to_regression_dict): - """Finds the culprit CL for stacktrace. - - The passed stacktrace is either from release build stacktrace - or debug build stacktrace. - - Args: - stacktrace: A list of parsed stacks within a stacktrace. - components: A set of components to look for. - component_to_regression_dict: A dictionary mapping component path to - its regression. - - Returns: - A list of match results from all stacks. - """ - # A list to aggregate results from all the callstacks in the stacktrace. - results = [] - results_lock = Lock() - - # Setup parsers. - svn_parser = svn_repository_parser.SVNParser(CONFIG['svn']) - git_parser = git_repository_parser.GitParser(component_to_regression_dict, - CONFIG['git']) - - # Create a cache of parsed revisions. - component_to_changelog_map = {} - for component_path in components: - component_object = component_to_regression_dict[component_path] - range_start = component_object['old_revision'] - range_end = component_object['new_revision'] - - # If range start is 0, the range is too large and the crash has been - # introduced the archived build, so ignore this case. - if range_start == '0': - continue - - component_name = component_to_regression_dict[component_path]['name'] - - is_git = utils.IsGitHash(range_start) - if is_git: - repository_parser = git_parser - else: - repository_parser = svn_parser - - (revisions, file_to_revision_map) = repository_parser.ParseChangelog( - component_path, range_start, range_end) - - # If the returned map from ParseChangeLog is empty, we don't need to look - # further because either the parsing failed or the changelog is empty. - if not (revisions and file_to_revision_map): - continue - - component_to_changelog_map[component_path] = (repository_parser, - component_name, - revisions, - file_to_revision_map) - - # Analyze each of the call stacks in the stacktrace. - for callstack in stacktrace.stack_list: - FindMatchForCallstack(callstack, components, component_to_changelog_map, - results, results_lock) - - return results - - -def SortMatchesFunction(match_with_stack_priority): - """A function to sort the match triple. - - Currently, it sorts the list by: - 1) The highest priority file change in the CL (changing crashed line is - higher priority than just changing the file). - 2) The callstack this match is computed (crash stack, freed, allocation). - 3) The minimum stack frame number of the changed file in the match. - 4) The number of files this CL changes (higher the better). - 5) The minimum distance between the lines that the CL changes and crashed - lines. - - Args: - match_with_stack_priority: A match object, with the CL it is from and what - callstack it is from. - - Returns: - A sort key. - """ - (stack_priority, _, match) = match_with_stack_priority - - return (min(match.priorities), - stack_priority, - match.min_distance, - crash_utils.FindMinStackFrameNumber(match.stack_frame_indices, - match.priorities), - -len(match.changed_files)) - - -def SortAndFilterMatches(matches, num_important_frames=5): - """Filters the list of potential culprit CLs to remove noise. - - Args: - matches: A list containing match results. - num_important_frames: A number of frames on the top of the frame to Check - for when filtering the results. A match with a file - that is in top num_important_frames of the stacktrace - is regarded more probable then others. - - Returns: - Filtered match results. - """ - new_matches = [] - line_changed = False - is_important_frame = False - highest_priority_stack = crash_utils.INFINITY - matches.sort(key=SortMatchesFunction) - # Iterate through the matches to find out what results are significant. - for stack_priority, cl, match in matches: - # Check if the current match changes crashed line. - is_line_change = (min(match.priorities) == LINE_CHANGE_PRIORITY) - - # Check which stack this match is from, and finds the highest priority - # callstack up to this point. - current_stack = stack_priority - if current_stack < highest_priority_stack: - highest_priority_stack = current_stack - - # Check if current match changes a file that occurs in crash state. - flattened_stack_frame_indices = [frame for frame_indices in - match.stack_frame_indices - for frame in frame_indices] - current_is_important = ( - min(flattened_stack_frame_indices) < num_important_frames) - - # This match and anything lower than this should be ignored if: - # - Current match does not change crashed lines but there are matches - # that do so. - # - Current match is not in crash state but there are matches in it. - # - There are other matches that came from higher priority stack. - if (line_changed and not is_line_change) or ( - is_important_frame and not current_is_important) or ( - current_stack > highest_priority_stack): - break - - # Update the variables. - if is_line_change: - line_changed = True - if current_is_important: - is_important_frame = True - - # Add current match to the filtered result. - new_matches.append((stack_priority, cl, match)) - - return new_matches - - -def GenerateReasonForMatches(matches): - """Generates a reason that a match (CL) is a culprit cl. - - Args: - matches: A list of match objects. - """ - # Iterate through the matches in the list. - for i, _, match in matches: - reason = [] - - # Zip the files in the match by the reason they are suspected - # (how the file is modified). - match_by_priority = zip( - match.priorities, match.crashed_line_numbers, match.changed_files, - match.stack_frame_indices, match.function_list) - - # Sort the zipped changed files in the match by their priority so that the - # changed lines comes first in the reason. - match_by_priority.sort( - key=lambda (priority, crashed_line_numbers, file_name, - stack_frame_indices, function_list): priority) - - # Iterate through the sorted match. - for i in range(len(match_by_priority)): - (priority, crashed_line_numbers, file_name, stack_frame_indices, - function_list) = match_by_priority[i] - - # If the file in the match is a line change, append a explanation. - if priority == LINE_CHANGE_PRIORITY: - crashed_line_numbers = [crashed_line_number - for lines in crashed_line_numbers - for crashed_line_number in lines] - reason.append( - 'Lines %s of file %s which potentially caused crash ' - 'are changed in this cl (%s).\n' % - (utils.JoinLineNumbers(crashed_line_numbers, accepted_gap=4), - file_name, - crash_utils.PrettifyFrameInfo(stack_frame_indices, function_list))) - - else: - # Get all the files that are not line change. - rest_of_the_files = match_by_priority[i:] - - if len(rest_of_the_files) == 1: - file_string = 'File %s is changed in this cl ' - else: - file_string = 'Files %s are changed in this cl ' - - # Create a list of file names, and prettify the list. - file_names = [ - file_name for (_, _, file_name, _, _) in rest_of_the_files] - pretty_file_names = crash_utils.PrettifyList(file_names) - - # Add the reason, break because we took care of the rest of the files. - file_string += ('(and is part of stack %s)' % - crash_utils.PrettifyFrameInfo(stack_frame_indices, function_list)) - reason.append(file_string % pretty_file_names) - break - - # Set the reason as string. - match.reason = '\n'.join(reason) - - -def CombineMatches(matches): - """Combine possible duplicates in matches. - - Args: - matches: A list of matches object, along with its callstack priority and - CL it is from. - Returns: - A combined list of matches. - """ - combined_matches = [] - - for stack_index, cl, match in matches: - found_match = None - - # Iterate through the list of combined matches. - for _, cl_combined, match_combined in combined_matches: - # Check for if current CL is already higher up in the result. - if cl == cl_combined: - found_match = match_combined - break - - # If current match is not already in, add it to the list of matches. - if not found_match: - combined_matches.append((stack_index, cl, match)) - continue - - # Combine the reason if the current match is already in there. - found_match.reason += '\n' + match.reason - if match.min_distance < found_match.min_distance: - found_match.min_distance = match.min_distance - found_match.min_distance_info = match.min_distance_info - - for stack_index, cl, match in combined_matches: - if match.min_distance_info: - file_name, min_crashed_line, min_changed_line = match.min_distance_info - match.reason = match.reason.strip() - match.reason += ( - '\nMinimum distance from crash line to modified line: %d. ' - '(file: %s, crashed on: %d, modified: %d).' % - (match.min_distance, file_name, min_crashed_line, min_changed_line)) - - return combined_matches - - -def FilterAndGenerateReasonForMatches(result): - """A wrapper function. - - It generates reasons for the matches and returns string representation - of filtered results. - - Args: - result: A list of match objects. - - Returns: - A string representation of filtered results. - """ - new_result = SortAndFilterMatches(result) - GenerateReasonForMatches(new_result) - combined_matches = CombineMatches(new_result) - return crash_utils.MatchListToResultList(combined_matches) - - -def ParseCrashComponents(main_stack): - """Parses the crashing component. - - Crashing components is a component that top_n_frames of the stacktrace is - from. - - Args: - main_stack: Main stack from the stacktrace. - - Returns: - A set of components. - """ - components = set() - - for frame in main_stack.frame_list: - components.add(frame.component_path) - - return components - - -def GenerateAndFilterBlameList(callstack, component_to_crash_revision_dict, - component_to_regression_dict): - """A wrapper function. - - Finds blame information for stack and returns string representation. - - Args: - callstack: A callstack to find the blame information. - component_to_crash_revision_dict: A dictionary mapping component to its - crash revision. - component_to_regression_dict: A dictionary mapping component to its - regression. - - Returns: - A list of blame results. - """ - if component_to_regression_dict: - parsed_deps = component_to_regression_dict - else: - parsed_deps = component_to_crash_revision_dict - - # Setup parser objects to use for parsing blame information. - svn_parser = svn_repository_parser.SVNParser(CONFIG['svn']) - git_parser = git_repository_parser.GitParser(parsed_deps, CONFIG['git']) - parsers = {} - parsers['svn'] = svn_parser - parsers['git'] = git_parser - - # Create and generate the blame objects from the callstack. - blame_list = blame.BlameList() - blame_list.FindBlame(callstack, component_to_crash_revision_dict, - component_to_regression_dict, - parsers) - - blame_list.FilterAndSortBlameList() - return crash_utils.BlameListToResultList(blame_list) - - -def FindItForCrash(stacktrace_list, - callstack, - component_to_regression_dict, - component_to_crash_revision_dict): - """Finds the culprit CL from the list of stacktrace. - - Args: - stacktrace_list: A list of stacktraces to look for, in the order of - decreasing significance. - callstack: A callstack object to show blame information for, if there are - no results for all stacktraces in the stacktrace_list. - component_to_regression_dict: A parsed regression information as a - result of parsing DEPS file. - component_to_crash_revision_dict: A parsed crash revision information. - - Returns: - A list of result objects, with the message how the result is created. - """ - # If regression information is not available, return blame information. - if not component_to_regression_dict: - result = GenerateAndFilterBlameList(callstack, - component_to_crash_revision_dict, - component_to_regression_dict) - if result: - return_message = ( - 'Regression information is not available. The result is ' - 'the blame information.') - else: - return_message = ('Findit could not find any suspected CLs.') - - return (return_message, result) - - for stacktrace in stacktrace_list: - # Check the next stacktrace if current one is empty. - if not stacktrace.stack_list: - continue - - # Get the crash stack for this stacktrace, and extract crashing components - # from it. - main_stack = stacktrace.GetCrashStack() - components = ParseCrashComponents(main_stack) - - result_for_stacktrace = FindMatchForStacktrace( - stacktrace, components, component_to_regression_dict) - filtered_result = FilterAndGenerateReasonForMatches(result_for_stacktrace) - - # If the result is empty, check the next stacktrace. Else, return the - # filtered result. - if not filtered_result: - continue - - return_message = ( - 'The result is a list of CLs that change the crashed files.') - return (return_message, filtered_result) - - # If no match is found, return the blame information for the input - # callstack. - result = GenerateAndFilterBlameList( - callstack, component_to_crash_revision_dict, - component_to_regression_dict) - - if result: - return_message = ( - 'No CL in the regression range changes the crashed files. ' - 'The result is the blame information.') - - # When findit could not find any CL that changes file in stacktrace or if - # if cannot get any blame information, return a message saying that no - # results are available. - else: - return_message = ('Findit could not find any suspected CLs.') - - return (return_message, result) - diff --git a/chromium/tools/findit/git_repository_parser.py b/chromium/tools/findit/git_repository_parser.py deleted file mode 100644 index 765da99b667..00000000000 --- a/chromium/tools/findit/git_repository_parser.py +++ /dev/null @@ -1,293 +0,0 @@ -# Copyright (c) 2014 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. - -import base64 -import xml.dom.minidom as minidom -from xml.parsers.expat import ExpatError - -import crash_utils -from repository_parser_interface import ParserInterface - -FILE_CHANGE_TYPE_MAP = { - 'add': 'A', - 'copy': 'C', - 'delete': 'D', - 'modify': 'M', - 'rename': 'R' -} - - -def _ConvertToFileChangeType(file_action): - # TODO(stgao): verify impact on code that checks the file change type. - return file_action[0].upper() - - -class GitParser(ParserInterface): - """Parser for Git repository in googlesource. - - Attributes: - parsed_deps: A map from component path to its repository name, regression, - etc. - url_parts_map: A map from url type to its url parts. This parts are added - the base url to form different urls. - """ - - def __init__(self, parsed_deps, url_parts_map): - self.component_to_url_map = parsed_deps - self.url_parts_map = url_parts_map - - def ParseChangelog(self, component_path, range_start, range_end): - file_to_revision_map = {} - revision_map = {} - base_url = self.component_to_url_map[component_path]['repository'] - changelog_url = base_url + self.url_parts_map['changelog_url'] - revision_url = base_url + self.url_parts_map['revision_url'] - - # Retrieve data from the url, return empty maps if fails. Html url is a\ - # url where the changelog can be parsed from html. - url = changelog_url % (range_start, range_end) - html_url = url + '?pretty=fuller' - response = crash_utils.GetDataFromURL(html_url) - if not response: - return (revision_map, file_to_revision_map) - - # Parse xml out of the returned string. If it failes, Try parsing - # from JSON objects. - try: - dom = minidom.parseString(response) - except ExpatError: - self.ParseChangelogFromJSON(range_start, range_end, changelog_url, - revision_url, revision_map, - file_to_revision_map) - return (revision_map, file_to_revision_map) - - # The revisions information are in from the third divs to the second - # to last one. - divs = dom.getElementsByTagName('div')[2:-1] - pres = dom.getElementsByTagName('pre') - uls = dom.getElementsByTagName('ul') - - # Divs, pres and uls each contain revision information for one CL, so - # they should have same length. - if not divs or len(divs) != len(pres) or len(pres) != len(uls): - self.ParseChangelogFromJSON(range_start, range_end, changelog_url, - revision_url, revision_map, - file_to_revision_map) - return (revision_map, file_to_revision_map) - - # Iterate through divs and parse revisions - for (div, pre, ul) in zip(divs, pres, uls): - # Create new revision object for each revision. - revision = {} - - # There must be three <tr>s. If not, this page is wrong. - trs = div.getElementsByTagName('tr') - if len(trs) != 3: - continue - - # Retrieve git hash. - githash = trs[0].getElementsByTagName('a')[0].firstChild.nodeValue - - # Retrieve and set author. - author = trs[1].getElementsByTagName( - 'td')[0].firstChild.nodeValue.split('<')[0] - revision['author'] = author - revision['time'] = trs[1].getElementsByTagName( - 'td')[1].firstChild.nodeValue - - # Retrive and set message. - revision['message'] = pre.firstChild.nodeValue - - # Set url of this CL. - revision_url_part = self.url_parts_map['revision_url'] % githash - revision['url'] = base_url + revision_url_part - - # Go through changed files, they are in li. - lis = ul.getElementsByTagName('li') - for li in lis: - # Retrieve path and action of the changed file - file_path = li.getElementsByTagName('a')[0].firstChild.nodeValue - file_change_type = li.getElementsByTagName('span')[ - 0].getAttribute('class') - - # Normalize file action so that it is same as SVN parser. - file_change_type = _ConvertToFileChangeType(file_change_type) - - # Add the changed file to the map. - if file_path not in file_to_revision_map: - file_to_revision_map[file_path] = [] - file_to_revision_map[file_path].append((githash, file_change_type)) - - # Add this revision object to the map. - revision_map[githash] = revision - - # Parse one revision for the start range, because googlesource does not - # include the start of the range. - self.ParseRevision(revision_url, range_start, revision_map, - file_to_revision_map) - - return (revision_map, file_to_revision_map) - - def ParseChangelogFromJSON(self, range_start, range_end, changelog_url, - revision_url, revision_map, file_to_revision_map): - """Parses changelog by going over the JSON file. - - Args: - range_start: Starting range of the regression. - range_end: Ending range of the regression. - changelog_url: The url to retrieve changelog from. - revision_url: The url to retrieve individual revision from. - revision_map: A map from a git hash number to its revision information. - file_to_revision_map: A map from file to a git hash in which it occurs. - """ - # Compute URLs from given range, and retrieves changelog. Stop if it fails. - changelog_url %= (range_start, range_end) - json_url = changelog_url + '?format=json' - response = crash_utils.GetDataFromURL(json_url) - if not response: - return - - # Parse changelog from the returned object. The returned string should - # start with ")}]'\n", so start from the 6th character. - revisions = crash_utils.LoadJSON(response[5:]) - if not revisions: - return - - # Parse individual revision in the log. - for revision in revisions['log']: - githash = revision['commit'] - self.ParseRevision(revision_url, githash, revision_map, - file_to_revision_map) - - # Parse the revision with range_start, because googlesource ignores - # that one. - self.ParseRevision(revision_url, range_start, revision_map, - file_to_revision_map) - - def ParseRevision(self, revision_url, githash, revision_map, - file_to_revision_map): - - # Retrieve data from the URL, return if it fails. - url = revision_url % githash - response = crash_utils.GetDataFromURL(url + '?format=json') - if not response: - return - - # Load JSON object from the string. If it fails, terminate the function. - json_revision = crash_utils.LoadJSON(response[5:]) - if not json_revision: - return - - # Create a map representing object and get githash from the JSON object. - revision = {} - githash = json_revision['commit'] - - # Set author, message and URL of this CL. - revision['author'] = json_revision['author']['name'] - revision['time'] = json_revision['author']['time'] - revision['message'] = json_revision['message'] - revision['url'] = url - - # Iterate through the changed files. - for diff in json_revision['tree_diff']: - file_path = diff['new_path'] - file_change_type = diff['type'] - - # Normalize file action so that it fits with svn_repository_parser. - file_change_type = _ConvertToFileChangeType(file_change_type) - - # Add the file to the map. - if file_path not in file_to_revision_map: - file_to_revision_map[file_path] = [] - file_to_revision_map[file_path].append((githash, file_change_type)) - - # Add this CL to the map. - revision_map[githash] = revision - - return - - def ParseLineDiff(self, path, component, file_change_type, githash): - changed_line_numbers = [] - changed_line_contents = [] - base_url = self.component_to_url_map[component]['repository'] - backup_url = (base_url + self.url_parts_map['revision_url']) % githash - - # If the file is added (not modified), treat it as if it is not changed. - if file_change_type in ('A', 'C', 'R'): - # TODO(stgao): Maybe return whole file change for Add, Rename, and Copy? - return (backup_url, changed_line_numbers, changed_line_contents) - - # Retrieves the diff data from URL, and if it fails, return emptry lines. - url = (base_url + self.url_parts_map['diff_url']) % (githash, path) - data = crash_utils.GetDataFromURL(url + '?format=text') - if not data: - return (backup_url, changed_line_numbers, changed_line_contents) - - # Decode the returned object to line diff info - diff = base64.b64decode(data).splitlines() - - # Iterate through the lines in diff. Set current line to -1 so that we know - # that current line is part of the diff chunk. - current_line = -1 - for line in diff: - line = line.strip() - - # If line starts with @@, a new chunk starts. - if line.startswith('@@'): - current_line = int(line.split('+')[1].split(',')[0]) - - # If we are in a chunk. - elif current_line != -1: - # If line is either added or modified. - if line.startswith('+'): - changed_line_numbers.append(current_line) - changed_line_contents.append(line[2:]) - - # Do not increment current line if the change is 'delete'. - if not line.startswith('-'): - current_line += 1 - - # Return url without '?format=json' - return (url, changed_line_numbers, changed_line_contents) - - def ParseBlameInfo(self, component, file_path, line, revision): - base_url = self.component_to_url_map[component]['repository'] - - # Retrieve blame JSON file from googlesource. If it fails, return None. - url_part = self.url_parts_map['blame_url'] % (revision, file_path) - blame_url = base_url + url_part - json_string = crash_utils.GetDataFromURL(blame_url) - if not json_string: - return - - # Parse JSON object from the string. The returned string should - # start with ")}]'\n", so start from the 6th character. - annotation = crash_utils.LoadJSON(json_string[5:]) - if not annotation: - return - - # Go through the regions, which is a list of consecutive lines with same - # author/revision. - for blame_line in annotation['regions']: - start = blame_line['start'] - count = blame_line['count'] - - # For each region, check if the line we want the blame info of is in this - # region. - if start <= line and line <= start + count - 1: - # If we are in the right region, get the information from the line. - revision = blame_line['commit'] - author = blame_line['author']['name'] - revision_url_parts = self.url_parts_map['revision_url'] % revision - revision_url = base_url + revision_url_parts - # TODO(jeun): Add a way to get content from JSON object. - content = None - - (revision_info, _) = self.ParseChangelog(component, revision, revision) - message = revision_info[revision]['message'] - time = revision_info[revision]['time'] - return (content, revision, author, revision_url, message, time) - - # Return none if the region does not exist. - return None diff --git a/chromium/tools/findit/match_set.py b/chromium/tools/findit/match_set.py deleted file mode 100644 index 52114b8c2bb..00000000000 --- a/chromium/tools/findit/match_set.py +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright (c) 2014 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. - -import re - -from threading import Lock - -import crash_utils - - -REVIEW_URL_PATTERN = re.compile(r'Review URL:( *)(.*?)/(\d+)') - - -class Match(object): - """Represents a match entry. - - A match is a CL that is suspected to have caused the crash. A match object - contains information about files it changes, their authors, etc. - - Attributes: - is_revert: True if this CL is reverted by other CL. - revert_of: If this CL is a revert of some other CL, a revision number/ - git hash of that CL. - crashed_line_numbers: The list of lines that caused crash for this CL. - function_list: The list of functions that caused the crash. - min_distance: The minimum distance between the lines that CL changed and - lines that caused the crash. - changed_files: The list of files that the CL changed. - changed_file_urls: The list of URLs for the file. - author: The author of the CL. - component_name: The name of the component that this CL belongs to. - stack_frame_indices: For files that caused crash, list of where in the - stackframe they occur. - priorities: A list of priorities for each of the changed file. A priority - is 1 if the file changes a crashed line, and 2 if it changes - the file but not the crashed line. - reivision_url: The revision URL of the CL. - review_url: The codereview URL that reviews this CL. - reviewers: The list of people that reviewed this CL. - reason: The reason why this CL is suspected. - time: When this CL was committed. - """ - REVERT_PATTERN = re.compile(r'(revert\w*) r?(\d+)', re.I) - - def __init__(self, revision, component_name): - self.is_revert = False - self.revert_of = None - self.message = None - self.crashed_line_numbers = [] - self.function_list = [] - self.min_distance = crash_utils.INFINITY - self.min_distance_info = None - self.changed_files = [] - self.changed_file_urls = [] - self.author = revision['author'] - self.component_name = component_name - self.stack_frame_indices = [] - self.priorities = [] - self.revision_url = revision['url'] - self.review_url = '' - self.reviewers = [] - self.reason = None - self.time = revision['time'] - - def ParseMessage(self, message, codereview_api_url): - """Parses the message. - - It checks the message to extract the code review website and list of - reviewers, and it also checks if the CL is a revert of another CL. - - Args: - message: The message to parse. - codereview_api_url: URL to retrieve codereview data from. - """ - self.message = message - for line in message.splitlines(): - line = line.strip() - review_url_line_match = REVIEW_URL_PATTERN.match(line) - - # Check if the line has the code review information. - if review_url_line_match: - - # Get review number for the code review site from the line. - issue_number = review_url_line_match.group(3) - - # Get JSON from the code review site, ignore the line if it fails. - url = codereview_api_url % issue_number - json_string = crash_utils.GetDataFromURL(url) - if not json_string: - continue - - # Load the JSON from the string, and get the list of reviewers. - code_review = crash_utils.LoadJSON(json_string) - if code_review: - self.reviewers = code_review['reviewers'] - - # Check if this CL is a revert of other CL. - if line.lower().startswith('revert'): - self.is_revert = True - - # Check if the line says what CL this CL is a revert of. - revert = self.REVERT_PATTERN.match(line) - if revert: - self.revert_of = revert.group(2) - return - - -class MatchSet(object): - """Represents a set of matches. - - Attributes: - matches: A map from CL to a match object. - cls_to_ignore: A set of CLs to ignore. - matches_lock: A lock guarding matches dictionary. - """ - - def __init__(self, codereview_api_url): - self.codereview_api_url = codereview_api_url - self.matches = {} - self.cls_to_ignore = set() - self.matches_lock = Lock() - - def RemoveRevertedCLs(self): - """Removes CLs that are revert.""" - for cl in self.matches: - if cl in self.cls_to_ignore: - del self.matches[cl] diff --git a/chromium/tools/findit/repository_parser_interface.py b/chromium/tools/findit/repository_parser_interface.py deleted file mode 100644 index aca4c62b9c8..00000000000 --- a/chromium/tools/findit/repository_parser_interface.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2014 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. - - -class ParserInterface(object): - """The interface for parsers.""" - - def ParseChangelog(self, component_path, range_start, range_end): - """Parses changelog from the URL stored in the parser object. - - Args: - component_path: A string, path of the component. Path is used because - path is unique while component name is not. - range_start: The start range of the regression. - range_end: The end range of the regression. - - Returns: - A tuple containing revision_map and file_to_revision_map, - revision_map maps a CL number to a dictionary containing revision - information such as author, commit message and the revision url. - file_to_revision_map maps a name of a file to a tuple containing the CL - number and path of the file that CL changes. - """ - raise NotImplementedError() - - def ParseLineDiff(self, path, component, file_action, githash): - """Parses the line diff of the given hash. - - Args: - path: The path of the file. - component: The component the file is from. - file_action: Whether file is modified, deleted or added. - githash: The git hashcode to check the line diff. - - Returns: - url: The URL of the diff page, returns the changelog page for the - file if the diff cannot be retrieved. - changed_line_numbers: The list of the line numbers that has been - changed. - changed_line_contents: The content of the changed lines. - """ - raise NotImplementedError() - - def ParseBlameInfo(self, component, file_path, line, revision): - """Parses blame information of the given file/line in revision. - - Args: - component: The component this line is from. - file_path: The path of the file. - line: The line that caused the crash. - revision: The revision to parse blame information for. - - Returns: - The content of the line, the last changed revision of the line, author - and the url of the revision. - """ - raise NotImplementedError() diff --git a/chromium/tools/findit/result.py b/chromium/tools/findit/result.py deleted file mode 100644 index 360a69bb6be..00000000000 --- a/chromium/tools/findit/result.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2014 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. - - -class Result(object): - - def __init__(self, suspected_cl, revision_url, component_name, author, - reason, review_url, reviewers, line_content, message, time): - self.suspected_cl = suspected_cl - self.revision_url = revision_url - self.component_name = component_name - self.author = author - self.reason = reason - self.review_url = review_url - self.reviewers = reviewers - self.line_content = line_content - self.commit_message = message - self.time = time diff --git a/chromium/tools/findit/run_all_tests.py b/chromium/tools/findit/run_all_tests.py deleted file mode 100755 index 230537a6176..00000000000 --- a/chromium/tools/findit/run_all_tests.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2014 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. - -import sys -import unittest - -from chromium_deps_unittest import ChromiumDEPSTest -from common.http_client_local_unittest import HttpClientLocalTest - - -if __name__ == '__main__': - all_tests_suite = unittest.defaultTestLoader.loadTestsFromModule( - sys.modules[__name__]) - tests = unittest.TestSuite(all_tests_suite) - result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(tests) - sys.exit(len(result.failures) + len(result.errors)) diff --git a/chromium/tools/findit/stacktrace.py b/chromium/tools/findit/stacktrace.py deleted file mode 100644 index 137e6fc92f9..00000000000 --- a/chromium/tools/findit/stacktrace.py +++ /dev/null @@ -1,321 +0,0 @@ -# Copyright (c) 2014 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. - -import re - -import crash_utils - - -SYZYASAN_STACK_FRAME_PATTERN = re.compile( - r'(CF: )?(.*?)( \(FPO: .*\) )?( \(CONV: .*\) )?\[(.*) @ (\d+)\]') -FILE_PATH_AND_LINE_PATTERN = re.compile(r'(.*?):(\d+)(:\d+)?') - - -class StackFrame(object): - """Represents a frame in stacktrace. - - Attributes: - index: An index of the stack frame. - component_path: The path of the component this frame represents. - component_name: The name of the component this frame represents. - file_name: The name of the file that crashed. - function: The function that caused the crash. - file_path: The path of the crashed file. - crashed_line_range: The line of the file that caused the crash. - """ - - def __init__(self, stack_frame_index, component_path, component_name, - file_name, function, file_path, crashed_line_range): - self.index = stack_frame_index - self.component_path = component_path - self.component_name = component_name - self.file_name = file_name - self.function = function - self.file_path = file_path - self.crashed_line_range = crashed_line_range - - -class CallStack(object): - """Represents a call stack within a stacktrace. - - It is a list of StackFrame object, and the object keeps track of whether - the stack is crash stack, freed or previously-allocated. - """ - - def __init__(self, stack_priority): - self.frame_list = [] - self.priority = stack_priority - - def Add(self, stacktrace_line): - self.frame_list.append(stacktrace_line) - - def GetTopNFrames(self, n): - return self.frame_list[:n] - - -class Stacktrace(object): - """Represents Stacktrace object. - - Contains a list of callstacks, because one stacktrace might have more than - one callstacks. - """ - - def __init__(self, stacktrace, build_type, parsed_deps): - self.stack_list = None - self.ParseStacktrace(stacktrace, build_type, parsed_deps) - - def ParseStacktrace(self, stacktrace, build_type, parsed_deps): - """Parses stacktrace and normalizes it. - - If there are multiple callstacks within the stacktrace, - it will parse each of them separately, and store them in the stack_list - variable. - - Args: - stacktrace: A string containing stacktrace. - build_type: A string containing the build type of the crash. - parsed_deps: A parsed DEPS file to normalize path with. - """ - # If the passed in string is empty, the object does not represent anything. - if not stacktrace: - return - # Reset the stack list. - self.stack_list = [] - reached_new_callstack = False - # Note that we do not need exact stack frame index, we only need relative - # position of a frame within a callstack. The reason for not extracting - # index from a line is that some stack frames do not have index. - stack_frame_index = 0 - current_stack = CallStack(-1) - - for line in stacktrace: - line = line.strip() - (is_new_callstack, stack_priority) = self.__IsStartOfNewCallStack( - line, build_type) - if is_new_callstack: - # If this callstack is crash stack, update the boolean. - if not reached_new_callstack: - reached_new_callstack = True - current_stack = CallStack(stack_priority) - - # If this is from freed or allocation, add the callstack we have - # to the list of callstacks, and increment the stack priority. - else: - stack_frame_index = 0 - if current_stack and current_stack.frame_list: - self.stack_list.append(current_stack) - current_stack = CallStack(stack_priority) - - # Generate stack frame object from the line. - parsed_stack_frame = self.__GenerateStackFrame( - stack_frame_index, line, build_type, parsed_deps) - - # If the line does not represent the stack frame, ignore this line. - if not parsed_stack_frame: - continue - - # Add the parsed stack frame object to the current stack. - current_stack.Add(parsed_stack_frame) - stack_frame_index += 1 - - # Add the current callstack only if there are frames in it. - if current_stack and current_stack.frame_list: - self.stack_list.append(current_stack) - - def __IsStartOfNewCallStack(self, line, build_type): - """Check if this line is the start of the new callstack. - - Since each builds have different format of stacktrace, the logic for - checking the line for all builds is handled in here. - - Args: - line: Line to check for. - build_type: The name of the build. - - Returns: - True if the line is the start of new callstack, False otherwise. If True, - it also returns the priority of the line. - """ - if 'syzyasan' in build_type: - # In syzyasan build, new stack starts with 'crash stack:', - # 'freed stack:', etc. - callstack_start_pattern = re.compile(r'^(.*) stack:$') - match = callstack_start_pattern.match(line) - - # If the line matches the callstack start pattern. - if match: - # Check the type of the new match. - stack_type = match.group(1) - - # Crash stack gets priority 0. - if stack_type == 'Crash': - return (True, 0) - - # Other callstacks all get priority 1. - else: - return (True, 1) - - elif 'tsan' in build_type: - # Create patterns for each callstack type. - crash_callstack_start_pattern1 = re.compile( - r'^(Read|Write) of size \d+') - - crash_callstack_start_pattern2 = re.compile( - r'^[A-Z]+: ThreadSanitizer') - - allocation_callstack_start_pattern = re.compile( - r'^Previous (write|read) of size \d+') - - location_callstack_start_pattern = re.compile( - r'^Location is heap block of size \d+') - - # Crash stack gets priority 0. - if (crash_callstack_start_pattern1.match(line) or - crash_callstack_start_pattern2.match(line)): - return (True, 0) - - # All other stacks get priority 1. - if allocation_callstack_start_pattern.match(line): - return (True, 1) - - if location_callstack_start_pattern.match(line): - return (True, 1) - - else: - # In asan and other build types, crash stack can start - # in two different ways. - crash_callstack_start_pattern1 = re.compile(r'^==\d+== ?[A-Z]+:') - crash_callstack_start_pattern2 = re.compile( - r'^(READ|WRITE) of size \d+ at') - crash_callstack_start_pattern3 = re.compile(r'^backtrace:') - - freed_callstack_start_pattern = re.compile( - r'^freed by thread T\d+ (.* )?here:') - - allocation_callstack_start_pattern = re.compile( - r'^previously allocated by thread T\d+ (.* )?here:') - - other_callstack_start_pattern = re.compile( - r'^Thread T\d+ (.* )?created by') - - # Crash stack gets priority 0. - if (crash_callstack_start_pattern1.match(line) or - crash_callstack_start_pattern2.match(line) or - crash_callstack_start_pattern3.match(line)): - return (True, 0) - - # All other callstack gets priority 1. - if freed_callstack_start_pattern.match(line): - return (True, 1) - - if allocation_callstack_start_pattern.match(line): - return (True, 1) - - if other_callstack_start_pattern.match(line): - return (True, 1) - - # If the line does not match any pattern, return false and a dummy for - # stack priority. - return (False, -1) - - def __GenerateStackFrame(self, stack_frame_index, line, build_type, - parsed_deps): - """Extracts information from a line in stacktrace. - - Args: - stack_frame_index: A stack frame index of this line. - line: A stacktrace string to extract data from. - build_type: A string containing the build type - of this crash (e.g. linux_asan_chrome_mp). - parsed_deps: A parsed DEPS file to normalize path with. - - Returns: - A triple containing the name of the function, the path of the file and - the crashed line number. - """ - line_parts = line.split() - try: - - if 'syzyasan' in build_type: - stack_frame_match = SYZYASAN_STACK_FRAME_PATTERN.match(line) - - if not stack_frame_match: - return None - file_path = stack_frame_match.group(5) - crashed_line_range = [int(stack_frame_match.group(6))] - function = stack_frame_match.group(2) - - else: - if not line_parts[0].startswith('#'): - return None - - if 'tsan' in build_type: - file_path_and_line = line_parts[-2] - function = ' '.join(line_parts[1:-2]) - else: - file_path_and_line = line_parts[-1] - function = ' '.join(line_parts[3:-1]) - - # Get file path and line info from the line. - file_path_and_line_match = FILE_PATH_AND_LINE_PATTERN.match( - file_path_and_line) - - # Return None if the file path information is not available - if not file_path_and_line_match: - return None - - file_path = file_path_and_line_match.group(1) - - # Get the crashed line range. For example, file_path:line_number:range. - crashed_line_range_num = file_path_and_line_match.group(3) - - if crashed_line_range_num: - # Strip ':' prefix. - crashed_line_range_num = int(crashed_line_range_num[1:]) - else: - crashed_line_range_num = 0 - - crashed_line_number = int(file_path_and_line_match.group(2)) - # For example, 655:1 has crashed lines 655 and 656. - crashed_line_range = \ - range(crashed_line_number, - crashed_line_number + crashed_line_range_num + 1) - - # Return None if the line is malformed. - except IndexError: - return None - except ValueError: - return None - - # Normalize the file path so that it can be compared to repository path. - (component_path, component_name, file_path) = ( - crash_utils.NormalizePath(file_path, parsed_deps)) - - # Return a new stack frame object with the parsed information. - file_name = file_path.split('/')[-1] - - # If we have the common stack frame index pattern, then use it - # since it is more reliable. - index_match = re.match('\s*#(\d+)\s.*', line) - if index_match: - stack_frame_index = int(index_match.group(1)) - - return StackFrame(stack_frame_index, component_path, component_name, - file_name, function, file_path, crashed_line_range) - - def __getitem__(self, index): - return self.stack_list[index] - - def GetCrashStack(self): - """Returns the callstack with the highest priority. - - Crash stack has priority 0, and allocation/freed/other thread stacks - get priority 1. - - Returns: - The highest priority callstack in the stacktrace. - """ - sorted_stacklist = sorted(self.stack_list, - key=lambda callstack: callstack.priority) - return sorted_stacklist[0] diff --git a/chromium/tools/findit/svn_repository_parser.py b/chromium/tools/findit/svn_repository_parser.py deleted file mode 100644 index 64a4503d495..00000000000 --- a/chromium/tools/findit/svn_repository_parser.py +++ /dev/null @@ -1,250 +0,0 @@ -# Copyright (c) 2014 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. - -import xml.dom.minidom as minidom -from xml.parsers.expat import ExpatError - -import crash_utils -from repository_parser_interface import ParserInterface - - -# This number is 6 because each linediff page in src.chromium.org should -# contain the following tables: table with revision number, table with actual -# diff, table with dropdown menu, table with legend, a border table and a table -# containing page information. -NUM_TABLES_IN_LINEDIFF_PAGE = 6 -# Each of the linediff info should contain 3 tds, one for changed line number, -# and two for line contents before/after. -NUM_TDS_IN_LINEDIFF_PAGE = 3 - - -class SVNParser(ParserInterface): - """Parser for SVN repository using chromium.org, for components in config. - - Attributes: - url_map: A map from component to the urls, where urls are for changelog, - revision, line diff and annotation. - """ - - def __init__(self, url_map): - self.component_to_urls_map = url_map - - def ParseChangelog(self, component, range_start, range_end): - file_to_revision_map = {} - revision_map = {} - - # Check if the current component is supported by reading the components - # parsed from config file. If it is not, fail. - - url_map = self.component_to_urls_map.get(component) - if not url_map: - return (revision_map, file_to_revision_map) - - # Retrieve data from the url, return empty map if fails. - revision_range_str = '%s:%s' % (range_start, range_end) - url = url_map['changelog_url'] % revision_range_str - response = crash_utils.GetDataFromURL(url) - if not response: - return (revision_map, file_to_revision_map) - - # Parse xml out of the returned string. If it fails, return empty map. - try: - xml_revisions = minidom.parseString(response) - except ExpatError: - return (revision_map, file_to_revision_map) - - # Iterate through the returned XML object. - revisions = xml_revisions.getElementsByTagName('logentry') - for revision in revisions: - # Create new revision object for each of the revision. - revision_object = {} - - # Set author of the CL. - revision_object['author'] = revision.getElementsByTagName( - 'author')[0].firstChild.nodeValue - - # Get the revision number from xml. - revision_number = int(revision.getAttribute('revision')) - - # Iterate through the changed paths in the CL. - paths = revision.getElementsByTagName('paths') - if paths: - for changed_path in paths[0].getElementsByTagName('path'): - # Get path and file change type from the xml. - file_path = changed_path.firstChild.nodeValue - file_change_type = changed_path.getAttribute('action') - - if file_path.startswith('/trunk/'): - file_path = file_path[len('/trunk/'):] - - # Add file to the map. - if file_path not in file_to_revision_map: - file_to_revision_map[file_path] = [] - file_to_revision_map[file_path].append( - (revision_number, file_change_type)) - - # Set commit message of the CL. - revision_object['message'] = revision.getElementsByTagName('msg')[ - 0].firstChild.nodeValue - - # Set url of this CL. - revision_url = url_map['revision_url'] % revision_number - revision_object['url'] = revision_url - - # Add this CL to the revision map. - revision_map[revision_number] = revision_object - - return (revision_map, file_to_revision_map) - - def ParseLineDiff(self, path, component, file_change_type, revision_number): - changed_line_numbers = [] - changed_line_contents = [] - - url_map = self.component_to_urls_map.get(component) - if not url_map: - return (None, None, None) - - # If the file is added (not modified), treat it as if it is not changed. - backup_url = url_map['revision_url'] % revision_number - if file_change_type == 'A': - return (backup_url, changed_line_numbers, changed_line_contents) - - # Retrieve data from the url. If no data is retrieved, return empty lists. - url = url_map['diff_url'] % (path, revision_number - 1, - revision_number, revision_number) - data = crash_utils.GetDataFromURL(url) - if not data: - return (backup_url, changed_line_numbers, changed_line_contents) - - line_diff_html = minidom.parseString(data) - tables = line_diff_html.getElementsByTagName('table') - # If there are not NUM_TABLES tables in the html page, there should be an - # error in the html page. - if len(tables) != NUM_TABLES_IN_LINEDIFF_PAGE: - return (backup_url, changed_line_numbers, changed_line_contents) - - # Diff content is in the second table. Each line of the diff content - # is in <tr>. - trs = tables[1].getElementsByTagName('tr') - prefix_len = len('vc_diff_') - - # Filter trs so that it only contains diff chunk with contents. - filtered_trs = [] - for tr in trs: - tr_class = tr.getAttribute('class') - - # Check for the classes of the <tr>s. - if tr_class: - tr_class = tr_class[prefix_len:] - - # Do not have to add header. - if tr_class == 'header' or tr_class == 'chunk_header': - continue - - # If the class of tr is empty, this page does not have any change. - if tr_class == 'empty': - return (backup_url, changed_line_numbers, changed_line_contents) - - filtered_trs.append(tr) - - # Iterate through filtered trs, and grab line diff information. - for tr in filtered_trs: - tds = tr.getElementsByTagName('td') - - # If there aren't 3 tds, this line does should not contain line diff. - if len(tds) != NUM_TDS_IN_LINEDIFF_PAGE: - continue - - # If line number information is not in hyperlink, ignore this line. - try: - line_num = tds[0].getElementsByTagName('a')[0].firstChild.nodeValue - left_diff_type = tds[1].getAttribute('class')[prefix_len:] - right_diff_type = tds[2].getAttribute('class')[prefix_len:] - except IndexError: - continue - - # Treat the line as modified only if both left and right diff has type - # changed or both have different change type, and if the change is not - # deletion. - if (left_diff_type != right_diff_type) or ( - left_diff_type == 'change' and right_diff_type == 'change'): - - # Check if the line content is not empty. - try: - new_line = tds[2].firstChild.nodeValue - except AttributeError: - new_line = '' - - if not (left_diff_type == 'remove' and right_diff_type == 'empty'): - changed_line_numbers.append(int(line_num)) - changed_line_contents.append(new_line.strip()) - - return (url, changed_line_numbers, changed_line_contents) - - def ParseBlameInfo(self, component, file_path, line, revision): - url_map = self.component_to_urls_map.get(component) - if not url_map: - return None - - # Retrieve blame data from url, return None if fails. - url = url_map['blame_url'] % (file_path, revision, revision) - data = crash_utils.GetDataFromURL(url) - if not data: - return None - - blame_html = minidom.parseString(data) - - title = blame_html.getElementsByTagName('title') - # If the returned html page is an exception page, return None. - if title[0].firstChild.nodeValue == 'ViewVC Exception': - return None - - # Each of the blame result is in <tr>. - blame_results = blame_html.getElementsByTagName('tr') - try: - blame_result = blame_results[line] - except IndexError: - return None - - # There must be 4 <td> for each <tr>. If not, this page is wrong. - tds = blame_result.getElementsByTagName('td') - if len(tds) != 4: - return None - - # The third <td> has the line content, separated by <span>s. Combine - # those to get a string of changed line. If it has nothing, the line - # is empty. - line_content = '' - if tds[3].hasChildNodes(): - contents = tds[3].childNodes - - for content in contents: - # Nodetype 3 means it is text node. - if content.nodeType == minidom.Node.TEXT_NODE: - line_content += content.nodeValue - else: - line_content += content.firstChild.nodeValue - - line_content = line_content.strip() - - # If the current line has the same author/revision as the previous lines, - # the result is not shown. Propagate up until we find the line with info. - while not tds[1].firstChild: - line -= 1 - blame_result = blame_results[line] - tds = blame_result.getElementsByTagName('td') - author = tds[1].firstChild.nodeValue - - # Revision can either be in hyperlink or plain text. - try: - revision = tds[2].getElementsByTagName('a')[0].firstChild.nodeValue - except IndexError: - revision = tds[2].firstChild.nodeValue - - (revision_info, _) = self.ParseChangelog(component, revision, revision) - message = revision_info[int(revision)]['message'] - - # Return the parsed information. - revision_url = url_map['revision_url'] % int(revision) - return (line_content, revision, author, revision_url, message) diff --git a/chromium/tools/gdb/gdb_chrome.py b/chromium/tools/gdb/gdb_chrome.py index dc6514944fe..9d727437b6e 100644 --- a/chromium/tools/gdb/gdb_chrome.py +++ b/chromium/tools/gdb/gdb_chrome.py @@ -211,7 +211,7 @@ pp_set.add_printer('base::TimeDelta', '^base::TimeDelta$', TimeDeltaPrinter) class TimeTicksPrinter(TimeDeltaPrinter): def __init__(self, val): - self._timedelta = datetime.timedelta(microseconds=int(val['ticks_'])) + self._timedelta = datetime.timedelta(microseconds=int(val['us_'])) pp_set.add_printer('base::TimeTicks', '^base::TimeTicks$', TimeTicksPrinter) diff --git a/chromium/tools/generate_shim_headers/generate_shim_headers.py b/chromium/tools/generate_shim_headers/generate_shim_headers.py index 81c531b2e6a..1b8e27f7682 100755 --- a/chromium/tools/generate_shim_headers/generate_shim_headers.py +++ b/chromium/tools/generate_shim_headers/generate_shim_headers.py @@ -65,7 +65,11 @@ def GeneratorMain(argv): if options.outputs: yield os.path.join(target_directory, header_filename) if options.generate: - with open(os.path.join(target_directory, header_filename), 'w') as f: + header_path = os.path.join(target_directory, header_filename) + header_dir = os.path.dirname(header_path) + if not os.path.exists(header_dir): + os.makedirs(header_dir) + with open(header_path, 'w') as f: f.write(SHIM_TEMPLATE) if options.define: diff --git a/chromium/tools/gn/BUILD.gn b/chromium/tools/gn/BUILD.gn index 2728c0d0906..2dfcf7f9f47 100644 --- a/chromium/tools/gn/BUILD.gn +++ b/chromium/tools/gn/BUILD.gn @@ -146,6 +146,8 @@ static_library("gn_lib") { "path_output.h", "pattern.cc", "pattern.h", + "qt_creator_writer.cc", + "qt_creator_writer.h", "runtime_deps.cc", "runtime_deps.h", "scheduler.cc", @@ -207,6 +209,10 @@ static_library("gn_lib") { "visual_studio_utils.h", "visual_studio_writer.cc", "visual_studio_writer.h", + "xcode_object.cc", + "xcode_object.h", + "xcode_writer.cc", + "xcode_writer.h", "xml_element_writer.cc", "xml_element_writer.h", ] @@ -252,6 +258,7 @@ executable("gn") { ":last_commit_position", "//base", "//build/config/sanitizers:deps", + "//build/win:default_exe_manifest", ] } @@ -277,7 +284,6 @@ test("gn_unittests") { "function_write_file_unittest.cc", "functions_target_unittest.cc", "functions_unittest.cc", - "group_target_generator_unittest.cc", "header_checker_unittest.cc", "inherited_libraries_unittest.cc", "input_conversion_unittest.cc", diff --git a/chromium/tools/gn/DEPS b/chromium/tools/gn/DEPS new file mode 100644 index 00000000000..0de07bbaf08 --- /dev/null +++ b/chromium/tools/gn/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+third_party/re2", +] diff --git a/chromium/tools/gn/args.cc b/chromium/tools/gn/args.cc index 60ee7b2ce33..d83c6789793 100644 --- a/chromium/tools/gn/args.cc +++ b/chromium/tools/gn/args.cc @@ -194,25 +194,12 @@ bool Args::VerifyAllOverridesUsed(Err* err) const { if (all_overrides.empty()) return true; - // Get a list of all possible overrides for help with error finding. - // - // It might be nice to do edit distance checks to see if we can find one close - // to what you typed. - std::string all_declared_str; - for (const auto& map_pair : declared_arguments_per_toolchain_) { - for (const auto& cur_str : map_pair.second) { - if (!all_declared_str.empty()) - all_declared_str += ", "; - all_declared_str += cur_str.first.as_string(); - } - } - *err = Err( all_overrides.begin()->second.origin(), "Build argument has no effect.", "The variable \"" + all_overrides.begin()->first.as_string() + "\" was set as a build argument\nbut never appeared in a " + - "declare_args() block in any buildfile.\n\nPossible arguments: " + - all_declared_str); + "declare_args() block in any buildfile.\n\n" + "To view possible args, run \"gn args --list <builddir>\""); return false; } @@ -245,6 +232,7 @@ void Args::SetSystemVarsLocked(Scope* dest) const { static const char kX86[] = "x86"; static const char kX64[] = "x64"; static const char kArm[] = "arm"; + static const char kMips[] = "mipsel"; const char* arch = nullptr; // Set the host CPU architecture based on the underlying OS, not @@ -254,8 +242,10 @@ void Args::SetSystemVarsLocked(Scope* dest) const { arch = kX86; else if (os_arch == "x86_64") arch = kX64; - else if (os_arch.substr(3) == "arm") + else if (os_arch.substr(0, 3) == "arm") arch = kArm; + else if (os_arch == "mips") + arch = kMips; else CHECK(false) << "OS architecture not handled."; diff --git a/chromium/tools/gn/bin/gn-format.py b/chromium/tools/gn/bin/gn-format.py index c835753eefb..4769640297f 100644 --- a/chromium/tools/gn/bin/gn-format.py +++ b/chromium/tools/gn/bin/gn-format.py @@ -38,7 +38,7 @@ def main(): p = subprocess.Popen([binary, 'format', '--stdin'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, startupinfo=startupinfo, - universal_newlines=True) + shell=True, universal_newlines=True) stdout, stderr = p.communicate(input=text) if p.returncode != 0: print 'Formatting failed, please report to gn-dev@chromium.org.' diff --git a/chromium/tools/gn/bin/roll_gn.py b/chromium/tools/gn/bin/roll_gn.py index 10b218c43af..b15aaf0b6ae 100755 --- a/chromium/tools/gn/bin/roll_gn.py +++ b/chromium/tools/gn/bin/roll_gn.py @@ -432,8 +432,7 @@ class GNRoller(object): '\n' 'TBR=%s\n' 'CQ_EXTRA_TRYBOTS=tryserver.chromium.mac:mac_chromium_gn_dbg;' - 'tryserver.chromium.win:win8_chromium_gn_dbg,' - 'win_chromium_gn_x64_rel\n' % ( + 'tryserver.chromium.win:win8_chromium_gn_dbg\n' % ( old_buildtools_commitish[:COMMITISH_DIGITS], new_buildtools_commitish[:COMMITISH_DIGITS], self.old_gn_commitish[:COMMITISH_DIGITS], diff --git a/chromium/tools/gn/binary_target_generator.cc b/chromium/tools/gn/binary_target_generator.cc index 7c81232dacc..78280132bed 100644 --- a/chromium/tools/gn/binary_target_generator.cc +++ b/chromium/tools/gn/binary_target_generator.cc @@ -7,8 +7,10 @@ #include "tools/gn/config_values_generator.h" #include "tools/gn/deps_iterator.h" #include "tools/gn/err.h" +#include "tools/gn/filesystem_utils.h" #include "tools/gn/functions.h" #include "tools/gn/scope.h" +#include "tools/gn/settings.h" #include "tools/gn/value_extractors.h" #include "tools/gn/variables.h" @@ -34,6 +36,9 @@ void BinaryTargetGenerator::DoRun() { if (!FillOutputPrefixOverride()) return; + if (!FillOutputDir()) + return; + if (!FillOutputExtension()) return; @@ -98,6 +103,29 @@ bool BinaryTargetGenerator::FillOutputPrefixOverride() { return true; } +bool BinaryTargetGenerator::FillOutputDir() { + const Value* value = scope_->GetValue(variables::kOutputDir, true); + if (!value) + return true; + if (!value->VerifyTypeIs(Value::STRING, err_)) + return false; + + if (value->string_value().empty()) + return true; // Treat empty string as the default and do nothing. + + const BuildSettings* build_settings = scope_->settings()->build_settings(); + SourceDir dir = scope_->GetSourceDir().ResolveRelativeDir( + *value, err_, build_settings->root_path_utf8()); + if (err_->has_error()) + return false; + + if (!EnsureStringIsInOutputDir(build_settings->build_dir(), + dir.value(), value->origin(), err_)) + return false; + target_->set_output_dir(dir); + return true; +} + bool BinaryTargetGenerator::FillOutputExtension() { const Value* value = scope_->GetValue(variables::kOutputExtension, true); if (!value) diff --git a/chromium/tools/gn/binary_target_generator.h b/chromium/tools/gn/binary_target_generator.h index 40ed432b228..0788a2042c0 100644 --- a/chromium/tools/gn/binary_target_generator.h +++ b/chromium/tools/gn/binary_target_generator.h @@ -27,6 +27,7 @@ class BinaryTargetGenerator : public TargetGenerator { bool FillCompleteStaticLib(); bool FillOutputName(); bool FillOutputPrefixOverride(); + bool FillOutputDir(); bool FillOutputExtension(); bool FillAllowCircularIncludesFrom(); diff --git a/chromium/tools/gn/bootstrap/bootstrap.py b/chromium/tools/gn/bootstrap/bootstrap.py index f1988331b3a..fea931245da 100755 --- a/chromium/tools/gn/bootstrap/bootstrap.py +++ b/chromium/tools/gn/bootstrap/bootstrap.py @@ -114,22 +114,31 @@ def main(argv): return 0 +def write_buildflag_header_manually(root_gen_dir, header, flags): + mkdir_p(os.path.join(root_gen_dir, os.path.dirname(header))) + with tempfile.NamedTemporaryFile() as f: + f.write('--flags') + for name,value in flags.items(): + f.write(' ' + name + '=' + value) + f.flush() + + check_call([ + os.path.join(SRC_ROOT, 'build', 'write_buildflag_header.py'), + '--output', header, + '--gen-dir', root_gen_dir, + '--definitions', f.name, + ]) + + def build_gn_with_ninja_manually(tempdir, options): root_gen_dir = os.path.join(tempdir, 'gen') mkdir_p(root_gen_dir) - if is_linux: - mkdir_p(os.path.join(root_gen_dir, 'base', 'allocator')) - with tempfile.NamedTemporaryFile() as f: - f.write('--flags USE_EXPERIMENTAL_ALLOCATOR_SHIM=true') - f.flush() - - check_call([ - os.path.join(SRC_ROOT, 'build', 'write_buildflag_header.py'), - '--output', 'base/allocator/features.h', - '--gen-dir', root_gen_dir, - '--definitions', f.name, - ]) + write_buildflag_header_manually(root_gen_dir, 'base/allocator/features.h', + {'USE_EXPERIMENTAL_ALLOCATOR_SHIM': 'true' if is_linux else 'false'}) + + write_buildflag_header_manually(root_gen_dir, 'base/debug/debugging_flags.h', + {'ENABLE_PROFILING': 'false'}) if is_mac: # //base/build_time.cc needs base/generated_build_date.h, @@ -198,8 +207,8 @@ def write_ninja(path, root_gen_dir, options): 'base/third_party/superfasthash/superfasthash.c', ]) static_libraries['base']['sources'].extend([ + 'base/allocator/allocator_check.cc', 'base/allocator/allocator_extension.cc', - 'base/allocator/allocator_shim.cc', 'base/at_exit.cc', 'base/base_paths.cc', 'base/base_switches.cc', @@ -215,6 +224,7 @@ def write_ninja(path, root_gen_dir, options): 'base/files/file_path_constants.cc', 'base/files/file_tracing.cc', 'base/files/file_util.cc', + 'base/files/important_file_writer.cc', 'base/files/memory_mapped_file.cc', 'base/files/scoped_file.cc', 'base/hash.cc', @@ -279,9 +289,9 @@ def write_ninja(path, root_gen_dir, options): 'base/third_party/dmg_fp/g_fmt.cc', 'base/third_party/icu/icu_utf.cc', 'base/third_party/nspr/prtime.cc', - 'base/thread_task_runner_handle.cc', 'base/threading/non_thread_safe_impl.cc', 'base/threading/post_task_and_reply_impl.cc', + 'base/threading/sequenced_task_runner_handle.cc', 'base/threading/sequenced_worker_pool.cc', 'base/threading/simple_thread.cc', 'base/threading/thread.cc', @@ -290,6 +300,7 @@ def write_ninja(path, root_gen_dir, options): 'base/threading/thread_id_name_manager.cc', 'base/threading/thread_local_storage.cc', 'base/threading/thread_restrictions.cc', + 'base/threading/thread_task_runner_handle.cc', 'base/threading/worker_pool.cc', 'base/time/time.cc', 'base/timer/elapsed_timer.cc', @@ -385,6 +396,7 @@ def write_ninja(path, root_gen_dir, options): 'tool': 'cxx', } static_libraries['base']['sources'].extend([ + 'base/allocator/allocator_shim.cc', 'base/allocator/allocator_shim_default_dispatch_to_glibc.cc', 'base/memory/shared_memory_posix.cc', 'base/nix/xdg_util.cc', diff --git a/chromium/tools/gn/bundle_data.cc b/chromium/tools/gn/bundle_data.cc index 7faccbdc51a..e1823653ba4 100644 --- a/chromium/tools/gn/bundle_data.cc +++ b/chromium/tools/gn/bundle_data.cc @@ -5,6 +5,7 @@ #include "tools/gn/bundle_data.h" #include "base/logging.h" +#include "tools/gn/filesystem_utils.h" #include "tools/gn/output_file.h" #include "tools/gn/settings.h" #include "tools/gn/target.h" @@ -103,10 +104,33 @@ void BundleData::GetOutputsAsSourceFiles( if (!asset_catalog_sources_.empty()) outputs_as_source->push_back(GetCompiledAssetCatalogPath()); + + if (!root_dir_.is_null()) + outputs_as_source->push_back(GetBundleRootDirOutput(settings)); } SourceFile BundleData::GetCompiledAssetCatalogPath() const { DCHECK(!asset_catalog_sources_.empty()); - std::string assets_car_path = resources_dir_ + "/Assets.car"; + std::string assets_car_path = resources_dir_.value() + "/Assets.car"; return SourceFile(SourceFile::SWAP_IN, &assets_car_path); } + +SourceFile BundleData::GetBundleRootDirOutput(const Settings* settings) const { + const SourceDir& build_dir = settings->build_settings()->build_dir(); + std::string bundle_root_relative = RebasePath(root_dir().value(), build_dir); + + size_t first_component = bundle_root_relative.find('/'); + if (first_component != std::string::npos) { + base::StringPiece outermost_bundle_dir = + base::StringPiece(bundle_root_relative).substr(0, first_component); + std::string return_value(build_dir.value()); + outermost_bundle_dir.AppendToString(&return_value); + return SourceFile(SourceFile::SWAP_IN, &return_value); + } + return SourceFile(root_dir().value()); +} + +SourceDir BundleData::GetBundleRootDirOutputAsDir( + const Settings* settings) const { + return SourceDir(GetBundleRootDirOutput(settings).value()); +} diff --git a/chromium/tools/gn/bundle_data.h b/chromium/tools/gn/bundle_data.h index e78589e9e91..3a1ce95ab7c 100644 --- a/chromium/tools/gn/bundle_data.h +++ b/chromium/tools/gn/bundle_data.h @@ -9,6 +9,7 @@ #include <vector> #include "tools/gn/bundle_file_rule.h" +#include "tools/gn/source_dir.h" #include "tools/gn/unique_vector.h" class OutputFile; @@ -64,6 +65,21 @@ class BundleData { // asset_catalog_sources() is not empty. SourceFile GetCompiledAssetCatalogPath() const; + // Returns the path to the top-level directory of the bundle. This is + // based on root_dir(), but since that can be Bundle.app/Contents/ or + // any other subpath, this is just the most top-level directory (e.g., + // just Bundle.app/). + // + // Note that this is a SourceFile instead of a SourceDir. This is because + // the output of a create_bundle rule is a single logical unit, even though + // it is really a directory containing many outputs. This allows other + // targets to treat the bundle as a single unit, rather than a collection + // of its contents. + SourceFile GetBundleRootDirOutput(const Settings* settings) const; + + // Performs GetBundleRootDirOutput but returns the result as a directory. + SourceDir GetBundleRootDirOutputAsDir(const Settings* settings) const; + // Returns the list of inputs for the compilation of the asset catalog. SourceFiles& asset_catalog_sources() { return asset_catalog_sources_; } const SourceFiles& asset_catalog_sources() const { @@ -73,17 +89,20 @@ class BundleData { BundleFileRules& file_rules() { return file_rules_; } const BundleFileRules& file_rules() const { return file_rules_; } - std::string& root_dir() { return root_dir_; } - const std::string& root_dir() const { return root_dir_; } + SourceDir& root_dir() { return root_dir_; } + const SourceDir& root_dir() const { return root_dir_; } + + SourceDir& resources_dir() { return resources_dir_; } + const SourceDir& resources_dir() const { return resources_dir_; } - std::string& resources_dir() { return resources_dir_; } - const std::string& resources_dir() const { return resources_dir_; } + SourceDir& executable_dir() { return executable_dir_; } + const SourceDir& executable_dir() const { return executable_dir_; } - std::string& executable_dir() { return executable_dir_; } - const std::string& executable_dir() const { return executable_dir_; } + SourceDir& plugins_dir() { return plugins_dir_; } + const SourceDir& plugins_dir() const { return plugins_dir_; } - std::string& plugins_dir() { return plugins_dir_; } - const std::string& plugins_dir() const { return plugins_dir_; } + std::string& product_type() { return product_type_; } + const std::string& product_type() const { return product_type_; } // Recursive collection of all bundle_data that the target depends on. const UniqueTargets& bundle_deps() const { return bundle_deps_; } @@ -95,10 +114,16 @@ class BundleData { // All those values are subdirectories relative to root_build_dir, and apart // from root_dir, they are either equal to root_dir_ or subdirectories of it. - std::string root_dir_; - std::string resources_dir_; - std::string executable_dir_; - std::string plugins_dir_; + SourceDir root_dir_; + SourceDir resources_dir_; + SourceDir executable_dir_; + SourceDir plugins_dir_; + + // This is the target type as known to Xcode. This is only used to generate + // the Xcode project file when using --ide=xcode. + std::string product_type_; + + DISALLOW_COPY_AND_ASSIGN(BundleData); }; #endif // TOOLS_GN_BUNDLE_DATA_H_ diff --git a/chromium/tools/gn/bundle_file_rule.cc b/chromium/tools/gn/bundle_file_rule.cc index 7684196c356..9f78667779d 100644 --- a/chromium/tools/gn/bundle_file_rule.cc +++ b/chromium/tools/gn/bundle_file_rule.cc @@ -29,16 +29,16 @@ SourceFile BundleFileRule::ApplyPatternToSource( output_path.append(subrange.literal); break; case SUBSTITUTION_BUNDLE_ROOT_DIR: - output_path.append(bundle_data.root_dir()); + output_path.append(bundle_data.root_dir().value()); break; case SUBSTITUTION_BUNDLE_RESOURCES_DIR: - output_path.append(bundle_data.resources_dir()); + output_path.append(bundle_data.resources_dir().value()); break; case SUBSTITUTION_BUNDLE_EXECUTABLE_DIR: - output_path.append(bundle_data.executable_dir()); + output_path.append(bundle_data.executable_dir().value()); break; case SUBSTITUTION_BUNDLE_PLUGINS_DIR: - output_path.append(bundle_data.plugins_dir()); + output_path.append(bundle_data.plugins_dir().value()); break; default: output_path.append(SubstitutionWriter::GetSourceSubstitution( diff --git a/chromium/tools/gn/command_desc.cc b/chromium/tools/gn/command_desc.cc index 15efe77cd6e..f2371e9d7cb 100644 --- a/chromium/tools/gn/command_desc.cc +++ b/chromium/tools/gn/command_desc.cc @@ -21,6 +21,7 @@ #include "tools/gn/setup.h" #include "tools/gn/standard_out.h" #include "tools/gn/substitution_writer.h" +#include "tools/gn/switches.h" #include "tools/gn/target.h" #include "tools/gn/variables.h" @@ -119,7 +120,7 @@ void PrintDeps(const Target* target, bool display_header) { // Tree mode is separate. if (cmdline->HasSwitch(kTree)) { if (display_header) - OutputString("\nDependency tree:\n"); + OutputString("\nDependency tree\n"); if (cmdline->HasSwitch("all")) { // Show all tree deps with no eliding. @@ -136,7 +137,7 @@ void PrintDeps(const Target* target, bool display_header) { if (cmdline->HasSwitch("all")) { // Show all dependencies. if (display_header) - OutputString("\nAll recursive dependencies:\n"); + OutputString("\nAll recursive dependencies\n"); std::set<const Target*> all_deps; RecursiveCollectChildDeps(target, &all_deps); @@ -147,7 +148,7 @@ void PrintDeps(const Target* target, bool display_header) { if (display_header) { OutputString( "\nDirect dependencies " - "(try also \"--all\", \"--tree\", or even \"--all --tree\"):\n"); + "(try also \"--all\", \"--tree\", or even \"--all --tree\")\n"); } for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) deps.push_back(pair.ptr); @@ -185,7 +186,7 @@ void PrintLibs(const Target* target, bool display_header) { void PrintPublic(const Target* target, bool display_header) { if (display_header) - OutputString("\npublic:\n"); + OutputString("\npublic\n"); if (target->all_headers_public()) { OutputString(" [All headers listed in the sources are public.]\n"); @@ -200,7 +201,7 @@ void PrintPublic(const Target* target, bool display_header) { void PrintCheckIncludes(const Target* target, bool display_header) { if (display_header) - OutputString("\ncheck_includes:\n"); + OutputString("\ncheck_includes\n"); if (target->check_includes()) OutputString(" true\n"); @@ -210,7 +211,7 @@ void PrintCheckIncludes(const Target* target, bool display_header) { void PrintAllowCircularIncludesFrom(const Target* target, bool display_header) { if (display_header) - OutputString("\nallow_circular_includes_from:\n"); + OutputString("\nallow_circular_includes_from\n"); Label toolchain_label = target->label().GetToolchainLabel(); for (const auto& cur : target->allow_circular_includes_from()) @@ -219,14 +220,14 @@ void PrintAllowCircularIncludesFrom(const Target* target, bool display_header) { void PrintVisibility(const Target* target, bool display_header) { if (display_header) - OutputString("\nvisibility:\n"); + OutputString("\nvisibility\n"); OutputString(target->visibility().Describe(2, false)); } void PrintTestonly(const Target* target, bool display_header) { if (display_header) - OutputString("\ntestonly:\n"); + OutputString("\ntestonly\n"); if (target->testonly()) OutputString(" true\n"); @@ -251,7 +252,7 @@ void PrintSubConfigs(const Config* config, int indent_level) { // This allows configs stored as either std::vector<LabelConfigPair> or // UniqueVector<LabelConfigPair> to be printed. template <class VectorType> -void PrintConfigsVector(const Target* target, +void PrintConfigsVector(const Item* item, const VectorType& configs, const std::string& heading, bool display_header) { @@ -263,12 +264,12 @@ void PrintConfigsVector(const Target* target, // Don't sort since the order determines how things are processed. if (display_header) { if (tree) - OutputString("\n" + heading + " tree (in order applying):\n"); + OutputString("\n" + heading + " tree (in order applying)\n"); else - OutputString("\n" + heading + " (in order applying, try also --tree):\n"); + OutputString("\n" + heading + " (in order applying, try also --tree)\n"); } - Label toolchain_label = target->label().GetToolchainLabel(); + Label toolchain_label = item->label().GetToolchainLabel(); for (const auto& config : configs) { OutputString(" " + config.label.GetUserVisibleName(toolchain_label) + "\n"); @@ -282,6 +283,11 @@ void PrintConfigs(const Target* target, bool display_header) { display_header); } +void PrintConfigs(const Config* config, bool display_header) { + PrintConfigsVector(config, config->configs().vector(), "configs", + display_header); +} + void PrintPublicConfigs(const Target* target, bool display_header) { PrintConfigsVector(target, target->public_configs(), "public_configs", display_header); @@ -300,7 +306,7 @@ void PrintFileList(const Target::FileList& files, return; if (display_header) - OutputString("\n" + header + ":\n"); + OutputString("\n" + header + "\n"); std::string indent = indent_extra ? " " : " "; @@ -320,7 +326,7 @@ void PrintInputs(const Target* target, bool display_header) { void PrintOutputs(const Target* target, bool display_header) { if (display_header) - OutputString("\noutputs:\n"); + OutputString("\noutputs\n"); if (target->output_type() == Target::ACTION) { // Action, print out outputs, don't apply sources to it. @@ -337,12 +343,12 @@ void PrintOutputs(const Target* target, bool display_header) { if (!outputs.required_types().empty()) { // Display the pattern and resolved pattern separately, since there are // subtitutions used. - OutputString(" Output pattern:\n"); + OutputString(" Output pattern\n"); for (const auto& elem : outputs.list()) OutputString(" " + elem.AsString() + "\n"); // Now display what that resolves to given the sources. - OutputString("\n Resolved output file list:\n"); + OutputString("\n Resolved output file list\n"); } // Resolved output list. @@ -355,13 +361,13 @@ void PrintOutputs(const Target* target, bool display_header) { void PrintScript(const Target* target, bool display_header) { if (display_header) - OutputString("\nscript:\n"); + OutputString("\nscript\n"); OutputString(" " + target->action_values().script().value() + "\n"); } void PrintArgs(const Target* target, bool display_header) { if (display_header) - OutputString("\nargs:\n"); + OutputString("\nargs\n"); for (const auto& elem : target->action_values().args().list()) { OutputString(" " + elem.AsString() + "\n"); } @@ -371,7 +377,7 @@ void PrintDepfile(const Target* target, bool display_header) { if (target->action_values().depfile().empty()) return; if (display_header) - OutputString("\ndepfile:\n"); + OutputString("\ndepfile\n"); OutputString(" " + target->action_values().depfile().AsString() + "\n"); } @@ -392,12 +398,22 @@ template<> struct DescValueWriter<std::string> { out << " " << str << "\n"; } }; + template<> struct DescValueWriter<SourceDir> { void operator()(const SourceDir& dir, std::ostream& out) const { out << " " << FormatSourceDir(dir) << "\n"; } }; +template<> struct DescValueWriter<LibFile> { + void operator()(const LibFile& lib, std::ostream& out) const { + if (lib.is_source_file()) + out << " " << lib.source_file().value() << "\n"; + else + out << " " << lib.value() << "\n"; + } +}; + // Writes a given config value type to the string, optionally with attribution. // This should match RecursiveTargetConfigToStream in the order it traverses. template<typename T> void OutputRecursiveTargetConfig( @@ -433,7 +449,26 @@ template<typename T> void OutputRecursiveTargetConfig( std::string out_str = out.str(); if (!out_str.empty()) { - OutputString("\n" + std::string(header_name) + "\n"); + if (header_name) + OutputString("\n" + std::string(header_name) + "\n"); + OutputString(out_str); + } +} + +template<typename T> void OutputConfigValueArray( + const ConfigValues& values, + const char* header_name, + const std::vector<T>& (ConfigValues::* getter)() const) { + std::ostringstream out; + + DescValueWriter<T> writer; + for (const T& cur : (values.*getter)()) + writer(cur, out); + + std::string out_str = out.str(); + if (!out_str.empty()) { + if (header_name) + OutputString("\n" + std::string(header_name) + "\n"); OutputString(out_str); } } @@ -462,78 +497,295 @@ void PrintRuntimeDeps(const Target* target) { } } +// If "what" is empty, prints all PCH info. If "what" is nonempty, prints only +// the things that match (if any). Returns true if anything was printed. +bool PrintPrecompiledHeaderInfo(const ConfigValues& values, + const std::string& what, + bool display_headers) { + bool found_match = false; + if (what == variables::kPrecompiledHeader || what.empty()) { + if (!values.precompiled_header().empty()) { + if (display_headers) + OutputString("\nprecompiled_header\n"); + OutputString(values.precompiled_header() + "\n"); + } + found_match = true; + } + if (what == variables::kPrecompiledSource || what.empty()) { + if (!values.precompiled_source().is_null()) { + if (display_headers) + OutputString("\nprecompiled_source\n"); + OutputString(values.precompiled_source().value() + "\n"); + } + found_match = true; + } + return found_match; +} + +bool PrintTarget(const Target* target, + const std::string& what, + bool display_target_header) { + if (display_target_header) { + OutputString("Target: ", DECORATION_YELLOW); + OutputString(target->label().GetUserVisibleName(false) + "\n"); + OutputString("Type: ", DECORATION_YELLOW); + OutputString(std::string( + Target::GetStringForOutputType(target->output_type())) + "\n"); + OutputString("Toolchain: ", DECORATION_YELLOW); + OutputString( + target->label().GetToolchainLabel().GetUserVisibleName(false) + "\n"); + } + + // Display headers when outputting everything. + bool display_headers = what.empty(); + bool is_binary_output = target->IsBinary(); + + bool found_match = false; + + // General target meta variables. + if (what.empty() || what == variables::kVisibility) { + PrintVisibility(target, display_headers); + found_match = true; + } + if (what.empty() || what == variables::kTestonly) { + PrintTestonly(target, display_headers); + found_match = true; + } + + // Binary target meta variables. + if (is_binary_output) { + if (what.empty() || what == variables::kCheckIncludes) { + PrintCheckIncludes(target, display_headers); + found_match = true; + } + if (what.empty() || what == variables::kAllowCircularIncludesFrom) { + PrintAllowCircularIncludesFrom(target, display_headers); + found_match = true; + } + } + + // Sources and inputs. + if (what.empty() || what == variables::kSources) { + PrintSources(target, display_headers); + found_match = true; + } + if (what.empty() || what == variables::kPublic) { + PrintPublic(target, display_headers); + found_match = true; + } + if (what.empty() || what == variables::kInputs) { + PrintInputs(target, display_headers); + found_match = true; + } + + // Configs. Configs set directly on a target are only relevant for binary + // targets + if (is_binary_output && (what.empty() || what == variables::kConfigs)) { + PrintConfigs(target, display_headers); + found_match = true; + } + + // Dependent/public configs can be applied to anything. + if (what.empty() || what == variables::kPublicConfigs) { + PrintPublicConfigs(target, display_headers); + found_match = true; + } + if (what.empty() || what == variables::kAllDependentConfigs) { + PrintAllDependentConfigs(target, display_headers); + found_match = true; + } + + // Action values. + if (target->output_type() == Target::ACTION || + target->output_type() == Target::ACTION_FOREACH) { + if (what.empty() || what == variables::kScript) { + PrintScript(target, display_headers); + found_match = true; + } + if (what.empty() || what == variables::kArgs) { + PrintArgs(target, display_headers); + found_match = true; + } + if (what.empty() || what == variables::kDepfile) { + PrintDepfile(target, display_headers); + found_match = true; + } + } + + // Outputs. + if (target->output_type() == Target::ACTION || + target->output_type() == Target::ACTION_FOREACH || + target->output_type() == Target::COPY_FILES || + target->output_type() == Target::CREATE_BUNDLE) { + if (what.empty() || what == variables::kOutputs) { + PrintOutputs(target, display_headers); + found_match = true; + } + } + + // Values from configs only apply to binary targets. + if (is_binary_output) { + #define CONFIG_VALUE_ARRAY_HANDLER(name, type) \ + if (what.empty() || what == #name) { \ + OutputRecursiveTargetConfig<type>( \ + target, display_headers ? #name : nullptr, &ConfigValues::name); \ + found_match = true; \ + } + + CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string) + CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string) + CONFIG_VALUE_ARRAY_HANDLER(defines, std::string) + CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir) + CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string) + // Libs and lib_dirs are handled specially below. + + #undef CONFIG_VALUE_ARRAY_HANDLER + + found_match |= PrintPrecompiledHeaderInfo(target->config_values(), + what, display_headers); + } + + // Deps + if (what.empty() || what == "deps") { + PrintDeps(target, display_headers); + found_match = true; + } + + // Runtime deps are special, print only when explicitly asked for and not in + // overview mode. + if (what == "runtime_deps") { + PrintRuntimeDeps(target); + found_match = true; + } + + // Libs can be part of any target and get recursively pushed up the chain, + // so display them regardless of target type. + if (what.empty() || what == variables::kLibs) { + PrintLibs(target, display_headers); + found_match = true; + } + if (what.empty() || what == variables::kLibDirs) { + PrintLibDirs(target, display_headers); + found_match = true; + } + + if (!found_match) { + OutputString("Don't know how to display \"" + what + "\" for \"" + + Target::GetStringForOutputType(target->output_type()) + "\".\n"); + return false; + } + return true; +} + +bool PrintConfig(const Config* config, + const std::string& what, + bool display_config_header) { + const ConfigValues& values = config->resolved_values(); + + if (display_config_header) { + OutputString("Config: ", DECORATION_YELLOW); + OutputString(config->label().GetUserVisibleName(false) + "\n"); + OutputString("Toolchain: ", DECORATION_YELLOW); + OutputString( + config->label().GetToolchainLabel().GetUserVisibleName(false) + "\n"); + if (what.empty() && !config->configs().empty()) { + OutputString( + "(This is a composite config, the values below are after the\n" + "expansion of the child configs.)\n"); + } + } + + // Display headers when outputting everything. + bool display_headers = what.empty(); + + if (what.empty() || what == variables::kConfigs) + PrintConfigs(config, display_headers); + +#define CONFIG_VALUE_ARRAY_HANDLER(name, type) \ + if (what.empty() || what == #name) { \ + OutputConfigValueArray<type>(values, display_headers ? #name : nullptr, \ + &ConfigValues::name); \ + found_match = true; \ + } + + bool found_match = false; + + CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string) + CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string) + CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string) + CONFIG_VALUE_ARRAY_HANDLER(defines, std::string) + CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir) + CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string) + CONFIG_VALUE_ARRAY_HANDLER(lib_dirs, SourceDir) + CONFIG_VALUE_ARRAY_HANDLER(libs, LibFile) + +#undef CONFIG_VALUE_ARRAY_HANDLER + + // Handles all PCH-related variables. + found_match |= PrintPrecompiledHeaderInfo(config->resolved_values(), + what, display_headers); + + if (!found_match) { + OutputString("Don't know how to display \"" + what + "\" for a config.\n"); + return false; + } + return true; +} + } // namespace // desc ------------------------------------------------------------------------ const char kDesc[] = "desc"; const char kDesc_HelpShort[] = - "desc: Show lots of insightful information about a target."; + "desc: Show lots of insightful information about a target or config."; const char kDesc_Help[] = - "gn desc <out_dir> <target label> [<what to show>] [--blame]\n" + "gn desc <out_dir> <label or pattern> [<what to show>] [--blame]\n" "\n" - " Displays information about a given labeled target for the given build.\n" - " The build parameters will be taken for the build in the given\n" - " <out_dir>.\n" + " Displays information about a given target or config. The build\n" + " build parameters will be taken for the build in the given <out_dir>.\n" "\n" - "Possibilities for <what to show>\n" - " (If unspecified an overall summary will be displayed.)\n" - "\n" - " sources\n" - " Source files.\n" - "\n" - " inputs\n" - " Additional input dependencies.\n" - "\n" - " public\n" - " Public header files.\n" - "\n" - " check_includes\n" - " Whether \"gn check\" checks this target for include usage.\n" + " The <label or pattern> can be a target label, a config label, or a\n" + " label pattern (see \"gn help label_pattern\"). A label pattern will\n" + " only match targets.\n" "\n" - " allow_circular_includes_from\n" - " Permit includes from these targets.\n" - "\n" - " visibility\n" - " Prints which targets can depend on this one.\n" - "\n" - " testonly\n" - " Whether this target may only be used in tests.\n" - "\n" - " configs\n" - " Shows configs applied to the given target, sorted in the order\n" - " they're specified. This includes both configs specified in the\n" - " \"configs\" variable, as well as configs pushed onto this target\n" - " via dependencies specifying \"all\" or \"direct\" dependent\n" - " configs.\n" + "Possibilities for <what to show>\n" "\n" - " deps\n" - " Show immediate or recursive dependencies. See below for flags that\n" - " control deps printing.\n" + " (If unspecified an overall summary will be displayed.)\n" "\n" - " public_configs\n" " all_dependent_configs\n" - " Shows the labels of configs applied to targets that depend on this\n" - " one (either directly or all of them).\n" - "\n" - " script\n" + " allow_circular_includes_from\n" + " arflags [--blame]\n" " args\n" + " cflags [--blame]\n" + " cflags_cc [--blame]\n" + " cflags_cxx [--blame]\n" + " check_includes\n" + " configs [--tree] (see below)\n" + " defines [--blame]\n" " depfile\n" - " Actions only. The script and related values.\n" - "\n" - " outputs\n" - " Outputs for script and copy target types.\n" - "\n" - " defines [--blame]\n" - " include_dirs [--blame]\n" - " cflags [--blame]\n" - " cflags_cc [--blame]\n" - " cflags_cxx [--blame]\n" - " ldflags [--blame]\n" + " deps [--all] [--tree] (see below)\n" + " include_dirs [--blame]\n" + " inputs\n" + " ldflags [--blame]\n" " lib_dirs\n" " libs\n" - " Shows the given values taken from the target and all configs\n" - " applying. See \"--blame\" below.\n" + " outputs\n" + " public_configs\n" + " public\n" + " script\n" + " sources\n" + " testonly\n" + " visibility\n" "\n" " runtime_deps\n" " Compute all runtime deps for the given target. This is a\n" @@ -547,13 +799,32 @@ const char kDesc_Help[] = "\n" "Shared flags\n" "\n" + ALL_TOOLCHAINS_SWITCH_HELP + "\n" + "Target flags\n" + "\n" " --blame\n" - " Used with any value specified by a config, this will name\n" - " the config that specified the value. This doesn't currently work\n" - " for libs and lib_dirs because those are inherited and are more\n" - " complicated to figure out the blame (patches welcome).\n" + " Used with any value specified on a config, this will name\n" + " the config that cause that target to get the flag. This doesn't\n" + " currently work for libs and lib_dirs because those are inherited\n" + " and are more complicated to figure out the blame (patches\n" + " welcome).\n" + "\n" + "Configs\n" + "\n" + " The \"configs\" section will list all configs that apply. For targets\n" + " this will include configs specified in the \"configs\" variable of\n" + " the target, and also configs pushed onto this target via public\n" + " or \"all dependent\" configs.\n" + "\n" + " Configs can have child configs. Specifying --tree will show the\n" + " hierarchy.\n" + "\n" + "Printing deps\n" "\n" - "Flags that control how deps are printed\n" + " Deps will include all public, private, and data deps (TODO this could\n" + " be clarified and enhanced) sorted in order applying. The following\n" + " may be used:\n" "\n" " --all\n" " Collects all recursive dependencies and prints a sorted flat list.\n" @@ -597,9 +868,6 @@ const char kDesc_Help[] = " Shows defines set for the //base:base target, annotated by where\n" " each one was set from.\n"; -#define OUTPUT_CONFIG_VALUE(name, type) \ - OutputRecursiveTargetConfig<type>(target, #name, &ConfigValues::name); - int RunDesc(const std::vector<std::string>& args) { if (args.size() != 2 && args.size() != 3) { Err(Location(), "You're holding it wrong.", @@ -607,6 +875,7 @@ int RunDesc(const std::vector<std::string>& args) { .PrintToStdout(); return 1; } + const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); // Deliberately leaked to avoid expensive process teardown. Setup* setup = new Setup; @@ -616,147 +885,48 @@ int RunDesc(const std::vector<std::string>& args) { if (!setup->Run()) return 1; - const Target* target = ResolveTargetFromCommandLineString(setup, args[1]); - if (!target) - return 1; - -#define CONFIG_VALUE_HANDLER(name, type) \ - } else if (what == #name) { OUTPUT_CONFIG_VALUE(name, type) - - if (args.size() == 3) { - // User specified one thing to display. - const std::string& what = args[2]; - if (what == variables::kConfigs) { - PrintConfigs(target, false); - } else if (what == variables::kPublicConfigs) { - PrintPublicConfigs(target, false); - } else if (what == variables::kAllDependentConfigs) { - PrintAllDependentConfigs(target, false); - } else if (what == variables::kSources) { - PrintSources(target, false); - } else if (what == variables::kPublic) { - PrintPublic(target, false); - } else if (what == variables::kCheckIncludes) { - PrintCheckIncludes(target, false); - } else if (what == variables::kAllowCircularIncludesFrom) { - PrintAllowCircularIncludesFrom(target, false); - } else if (what == variables::kVisibility) { - PrintVisibility(target, false); - } else if (what == variables::kTestonly) { - PrintTestonly(target, false); - } else if (what == variables::kInputs) { - PrintInputs(target, false); - } else if (what == variables::kScript) { - PrintScript(target, false); - } else if (what == variables::kArgs) { - PrintArgs(target, false); - } else if (what == variables::kDepfile) { - PrintDepfile(target, false); - } else if (what == variables::kOutputs) { - PrintOutputs(target, false); - } else if (what == variables::kDeps) { - PrintDeps(target, false); - } else if (what == variables::kLibDirs) { - PrintLibDirs(target, false); - } else if (what == variables::kLibs) { - PrintLibs(target, false); - } else if (what == "runtime_deps") { - PrintRuntimeDeps(target); - - CONFIG_VALUE_HANDLER(defines, std::string) - CONFIG_VALUE_HANDLER(include_dirs, SourceDir) - CONFIG_VALUE_HANDLER(asmflags, std::string) - CONFIG_VALUE_HANDLER(cflags, std::string) - CONFIG_VALUE_HANDLER(cflags_c, std::string) - CONFIG_VALUE_HANDLER(cflags_cc, std::string) - CONFIG_VALUE_HANDLER(cflags_objc, std::string) - CONFIG_VALUE_HANDLER(cflags_objcc, std::string) - CONFIG_VALUE_HANDLER(ldflags, std::string) - - } else { - OutputString("Don't know how to display \"" + what + "\".\n"); - return 1; - } - -#undef CONFIG_VALUE_HANDLER - return 0; - } - - // Display summary. - - // Display this only applicable to binary targets. - bool is_binary_output = - target->output_type() != Target::GROUP && - target->output_type() != Target::COPY_FILES && - target->output_type() != Target::ACTION && - target->output_type() != Target::ACTION_FOREACH && - target->output_type() != Target::BUNDLE_DATA && - target->output_type() != Target::CREATE_BUNDLE; + // Resolve target(s) and config from inputs. + UniqueVector<const Target*> target_matches; + UniqueVector<const Config*> config_matches; + UniqueVector<const Toolchain*> toolchain_matches; + UniqueVector<SourceFile> file_matches; - // Generally we only want to display toolchains on labels when the toolchain - // is different than the default one for this target (which we always print - // in the header). - Label target_toolchain = target->label().GetToolchainLabel(); + std::vector<std::string> target_list; + target_list.push_back(args[1]); - // Header. - OutputString("Target: ", DECORATION_YELLOW); - OutputString(target->label().GetUserVisibleName(false) + "\n"); - OutputString("Type: ", DECORATION_YELLOW); - OutputString(std::string( - Target::GetStringForOutputType(target->output_type())) + "\n"); - OutputString("Toolchain: ", DECORATION_YELLOW); - OutputString(target_toolchain.GetUserVisibleName(false) + "\n"); + if (!ResolveFromCommandLineInput( + setup, target_list, cmdline->HasSwitch(switches::kAllToolchains), + &target_matches, &config_matches, &toolchain_matches, &file_matches)) + return 1; - PrintSources(target, true); - if (is_binary_output) { - PrintPublic(target, true); - PrintCheckIncludes(target, true); - PrintAllowCircularIncludesFrom(target, true); - } - PrintVisibility(target, true); - if (is_binary_output) { - PrintTestonly(target, true); - PrintConfigs(target, true); - } + std::string what_to_print; + if (args.size() == 3) + what_to_print = args[2]; - PrintPublicConfigs(target, true); - PrintAllDependentConfigs(target, true); + bool multiple_outputs = (target_matches.size() + config_matches.size()) > 1; - PrintInputs(target, true); + // Display headers for each target when printing all values, or when printing + // multiple targets or configs. + bool display_item_header = multiple_outputs || what_to_print.empty(); - if (is_binary_output) { - OUTPUT_CONFIG_VALUE(defines, std::string) - OUTPUT_CONFIG_VALUE(include_dirs, SourceDir) - OUTPUT_CONFIG_VALUE(asmflags, std::string) - OUTPUT_CONFIG_VALUE(cflags, std::string) - OUTPUT_CONFIG_VALUE(cflags_c, std::string) - OUTPUT_CONFIG_VALUE(cflags_cc, std::string) - OUTPUT_CONFIG_VALUE(cflags_objc, std::string) - OUTPUT_CONFIG_VALUE(cflags_objcc, std::string) - OUTPUT_CONFIG_VALUE(ldflags, std::string) - } + bool printed_output = false; + for (const Target* target : target_matches) { + if (printed_output) + OutputString("\n\n"); + printed_output = true; - if (target->output_type() == Target::ACTION || - target->output_type() == Target::ACTION_FOREACH) { - PrintScript(target, true); - PrintArgs(target, true); - PrintDepfile(target, true); + if (!PrintTarget(target, what_to_print, display_item_header)) + return 1; } + for (const Config* config : config_matches) { + if (printed_output) + OutputString("\n\n"); + printed_output = true; - if (target->output_type() == Target::ACTION || - target->output_type() == Target::ACTION_FOREACH || - target->output_type() == Target::COPY_FILES || - target->output_type() == Target::CREATE_BUNDLE) { - PrintOutputs(target, true); + if (!PrintConfig(config, what_to_print, display_item_header)) + return 1; } - // Libs can be part of any target and get recursively pushed up the chain, - // so always display them, even for groups and such. - PrintLibs(target, true); - PrintLibDirs(target, true); - - PrintDeps(target, true); - return 0; } diff --git a/chromium/tools/gn/command_format.cc b/chromium/tools/gn/command_format.cc index a054b21b9b9..7b8f2f34201 100644 --- a/chromium/tools/gn/command_format.cc +++ b/chromium/tools/gn/command_format.cc @@ -181,7 +181,7 @@ class Printer { // bracket. template <class PARSENODE> // Just for const covariance. void Sequence(SequenceStyle style, - const std::vector<PARSENODE*>& list, + const std::vector<std::unique_ptr<PARSENODE>>& list, const ParseNode* end, bool force_multiline); @@ -194,7 +194,7 @@ class Printer { void InitializeSub(Printer* sub); template <class PARSENODE> - bool ListWillBeMultiline(const std::vector<PARSENODE*>& list, + bool ListWillBeMultiline(const std::vector<std::unique_ptr<PARSENODE>>& list, const ParseNode* end); std::string output_; // Output buffer. @@ -385,7 +385,7 @@ void Printer::Block(const ParseNode* root) { size_t i = 0; for (const auto& stmt : block->statements()) { - Expr(stmt, kPrecedenceLowest, std::string()); + Expr(stmt.get(), kPrecedenceLowest, std::string()); Newline(); if (stmt->comments()) { // Why are before() not printed here too? before() are handled inside @@ -399,8 +399,8 @@ void Printer::Block(const ParseNode* root) { } } if (i < block->statements().size() - 1 && - (ShouldAddBlankLineInBetween(block->statements()[i], - block->statements()[i + 1]))) { + (ShouldAddBlankLineInBetween(block->statements()[i].get(), + block->statements()[i + 1].get()))) { Newline(); } ++i; @@ -648,7 +648,7 @@ int Printer::Expr(const ParseNode* root, template <class PARSENODE> void Printer::Sequence(SequenceStyle style, - const std::vector<PARSENODE*>& list, + const std::vector<std::unique_ptr<PARSENODE>>& list, const ParseNode* end, bool force_multiline) { if (style == kSequenceStyleList) @@ -665,7 +665,7 @@ void Printer::Sequence(SequenceStyle style, // No elements, and not forcing newlines, print nothing. } else if (list.size() == 1 && !force_multiline) { Print(" "); - Expr(list[0], kPrecedenceLowest, std::string()); + Expr(list[0].get(), kPrecedenceLowest, std::string()); CHECK(!list[0]->comments() || list[0]->comments()->after().empty()); Print(" "); } else { @@ -687,11 +687,11 @@ void Printer::Sequence(SequenceStyle style, bool body_of_list = i < list.size() - 1 || style == kSequenceStyleList; bool want_comma = body_of_list && (style == kSequenceStyleList && !x->AsBlockComment()); - Expr(x, kPrecedenceLowest, want_comma ? "," : std::string()); + Expr(x.get(), kPrecedenceLowest, want_comma ? "," : std::string()); CHECK(!x->comments() || x->comments()->after().empty()); if (body_of_list) { if (i < list.size() - 1 && - ShouldAddBlankLineInBetween(list[i], list[i + 1])) + ShouldAddBlankLineInBetween(list[i].get(), list[i + 1].get())) Newline(); } ++i; @@ -734,7 +734,7 @@ int Printer::FunctionCall(const FunctionCallNode* func_call, bool have_block = func_call->block() != nullptr; bool force_multiline = false; - const std::vector<const ParseNode*>& list = func_call->args()->contents(); + const auto& list = func_call->args()->contents(); const ParseNode* end = func_call->args()->End(); if (end && end->comments() && !end->comments()->before().empty()) @@ -767,7 +767,7 @@ int Printer::FunctionCall(const FunctionCallNode* func_call, IndentState(CurrentColumn(), continuation_requires_indent, false)); int penalty_one_line = 0; for (size_t i = 0; i < list.size(); ++i) { - penalty_one_line += sub1.Expr(list[i], kPrecedenceLowest, + penalty_one_line += sub1.Expr(list[i].get(), kPrecedenceLowest, i < list.size() - 1 ? ", " : std::string()); } sub1.Print(terminator); @@ -785,8 +785,9 @@ int Printer::FunctionCall(const FunctionCallNode* func_call, IndentState(CurrentColumn(), continuation_requires_indent, false)); int penalty_multiline_start_same_line = 0; for (size_t i = 0; i < list.size(); ++i) { - penalty_multiline_start_same_line += sub2.Expr( - list[i], kPrecedenceLowest, i < list.size() - 1 ? "," : std::string()); + penalty_multiline_start_same_line += + sub2.Expr(list[i].get(), kPrecedenceLowest, + i < list.size() - 1 ? "," : std::string()); if (i < list.size() - 1) { sub2.Newline(); } @@ -807,8 +808,9 @@ int Printer::FunctionCall(const FunctionCallNode* func_call, std::abs(sub3.CurrentColumn() - start_column) * kPenaltyHorizontalSeparation; } - penalty_multiline_start_next_line += sub3.Expr( - list[i], kPrecedenceLowest, i < list.size() - 1 ? "," : std::string()); + penalty_multiline_start_next_line += + sub3.Expr(list[i].get(), kPrecedenceLowest, + i < list.size() - 1 ? "," : std::string()); if (i < list.size() - 1) { sub3.Newline(); } @@ -852,7 +854,7 @@ int Printer::FunctionCall(const FunctionCallNode* func_call, Newline(); } bool want_comma = i < list.size() - 1 && !x->AsBlockComment(); - Expr(x, kPrecedenceLowest, want_comma ? "," : std::string()); + Expr(x.get(), kPrecedenceLowest, want_comma ? "," : std::string()); CHECK(!x->comments() || x->comments()->after().empty()); if (i < list.size() - 1) { if (!want_comma) @@ -900,8 +902,9 @@ void Printer::InitializeSub(Printer* sub) { } template <class PARSENODE> -bool Printer::ListWillBeMultiline(const std::vector<PARSENODE*>& list, - const ParseNode* end) { +bool Printer::ListWillBeMultiline( + const std::vector<std::unique_ptr<PARSENODE>>& list, + const ParseNode* end) { if (list.size() > 1) return true; diff --git a/chromium/tools/gn/command_gen.cc b/chromium/tools/gn/command_gen.cc index fee3f1a31f8..7bdb6d81fe3 100644 --- a/chromium/tools/gn/command_gen.cc +++ b/chromium/tools/gn/command_gen.cc @@ -13,6 +13,7 @@ #include "tools/gn/eclipse_writer.h" #include "tools/gn/ninja_target_writer.h" #include "tools/gn/ninja_writer.h" +#include "tools/gn/qt_creator_writer.h" #include "tools/gn/runtime_deps.h" #include "tools/gn/scheduler.h" #include "tools/gn/setup.h" @@ -20,6 +21,7 @@ #include "tools/gn/switches.h" #include "tools/gn/target.h" #include "tools/gn/visual_studio_writer.h" +#include "tools/gn/xcode_writer.h" namespace commands { @@ -29,10 +31,15 @@ const char kSwitchCheck[] = "check"; const char kSwitchFilters[] = "filters"; const char kSwitchIde[] = "ide"; const char kSwitchIdeValueEclipse[] = "eclipse"; +const char kSwitchIdeValueQtCreator[] = "qtcreator"; const char kSwitchIdeValueVs[] = "vs"; const char kSwitchIdeValueVs2013[] = "vs2013"; const char kSwitchIdeValueVs2015[] = "vs2015"; +const char kSwitchIdeValueXcode[] = "xcode"; +const char kSwitchNinjaExtraArgs[] = "ninja-extra-args"; +const char kSwitchRootTarget[] = "root-target"; const char kSwitchSln[] = "sln"; +const char kSwitchWorkspace[] = "workspace"; // Called on worker thread to write the ninja file. void BackgroundDoWrite(const Target* target) { @@ -188,6 +195,31 @@ bool RunIdeWriter(const std::string& ide, "ms\n"); } return res; + } else if (ide == kSwitchIdeValueXcode) { + bool res = XcodeWriter::RunAndWriteFiles( + command_line->GetSwitchValueASCII(kSwitchWorkspace), + command_line->GetSwitchValueASCII(kSwitchRootTarget), + command_line->GetSwitchValueASCII(kSwitchNinjaExtraArgs), + command_line->GetSwitchValueASCII(kSwitchFilters), build_settings, + builder, err); + if (res && !command_line->HasSwitch(switches::kQuiet)) { + OutputString("Generating Xcode projects took " + + base::Int64ToString(timer.Elapsed().InMilliseconds()) + + "ms\n"); + } + return res; + } else if (ide == kSwitchIdeValueQtCreator) { + std::string root_target; + if (command_line->HasSwitch(kSwitchRootTarget)) + root_target = command_line->GetSwitchValueASCII(kSwitchRootTarget); + bool res = QtCreatorWriter::RunAndWriteFile(build_settings, builder, err, + root_target); + if (res && !command_line->HasSwitch(switches::kQuiet)) { + OutputString("Generating QtCreator projects took " + + base::Int64ToString(timer.Elapsed().InMilliseconds()) + + "ms\n"); + } + return res; } *err = Err(Location(), "Unknown IDE: " + ide); @@ -225,16 +257,44 @@ const char kGen_Help[] = " (default Visual Studio version: 2015)\n" " \"vs2013\" - Visual Studio 2013 project/solution files.\n" " \"vs2015\" - Visual Studio 2015 project/solution files.\n" - "\n" - " --sln=<file_name>\n" - " Override default sln file name (\"all\"). Solution file is written\n" - " to the root build directory. Only for Visual Studio.\n" + " \"xcode\" - Xcode workspace/solution files.\n" + " \"qtcreator\" - QtCreator project files.\n" "\n" " --filters=<path_prefixes>\n" " Semicolon-separated list of label patterns used to limit the set\n" " of generated projects (see \"gn help label_pattern\"). Only\n" - " matching targets will be included to the solution. Only for Visual\n" - " Studio.\n" + " matching targets will be included to the solution. Only used for\n" + " Visual Studio and Xcode.\n" + "\n" + "Visual Studio Flags\n" + "\n" + " --sln=<file_name>\n" + " Override default sln file name (\"all\"). Solution file is written\n" + " to the root build directory.\n" + "\n" + "Xcode Flags\n" + "\n" + " --workspace=<file_name>\n" + " Override defaut workspace file name (\"all\"). The workspace file\n" + " is written to the root build directory.\n" + "\n" + " --ninja-extra-args=<string>\n" + " This string is passed without any quoting to the ninja invocation\n" + " command-line. Can be used to configure ninja flags, like \"-j\" if\n" + " using goma for example.\n" + "\n" + " --root-target=<target_name>\n" + " Name of the target corresponding to \"All\" target in Xcode.\n" + " If unset, \"All\" invokes ninja without any target\n" + " and builds everything.\n" + "\n" + "QtCreator Flags\n" + "\n" + " --root-target=<target_name>\n" + " Name of the root target for which the QtCreator project will be\n" + " generated to contain files of it and its dependencies. If unset, \n" + " the whole build graph will be emitted.\n" + "\n" "\n" "Eclipse IDE Support\n" "\n" diff --git a/chromium/tools/gn/command_ls.cc b/chromium/tools/gn/command_ls.cc index eddb51c3797..c9b9672cf80 100644 --- a/chromium/tools/gn/command_ls.cc +++ b/chromium/tools/gn/command_ls.cc @@ -10,6 +10,7 @@ #include "tools/gn/label_pattern.h" #include "tools/gn/setup.h" #include "tools/gn/standard_out.h" +#include "tools/gn/switches.h" #include "tools/gn/target.h" namespace commands { @@ -34,11 +35,7 @@ const char kLs_Help[] = "\n" TARGET_PRINTING_MODE_COMMAND_LINE_HELP "\n" - " --all-toolchains\n" - " Matches all toolchains. When set, if the label pattern does not\n" - " specify an explicit toolchain, labels from all toolchains will be\n" - " matched. When unset, only targets in the default toolchain will\n" - " be matched unless an explicit toolchain in the label is set.\n" + ALL_TOOLCHAINS_SWITCH_HELP "\n" TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP "\n" @@ -81,7 +78,7 @@ int RunLs(const std::vector<std::string>& args) { return 1; const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); - bool all_toolchains = cmdline->HasSwitch("all-toolchains"); + bool all_toolchains = cmdline->HasSwitch(switches::kAllToolchains); std::vector<const Target*> matches; if (args.size() > 1) { diff --git a/chromium/tools/gn/command_refs.cc b/chromium/tools/gn/command_refs.cc index 821fd88d7e9..413a98f89c7 100644 --- a/chromium/tools/gn/command_refs.cc +++ b/chromium/tools/gn/command_refs.cc @@ -17,6 +17,7 @@ #include "tools/gn/item.h" #include "tools/gn/setup.h" #include "tools/gn/standard_out.h" +#include "tools/gn/switches.h" #include "tools/gn/target.h" namespace commands { @@ -315,16 +316,7 @@ const char kRefs_Help[] = "\n" " When used with --tree, turns off eliding to show a complete tree.\n" "\n" - " --all-toolchains\n" - " Normally only inputs in the default toolchain will be included.\n" - " This switch will turn on matching all toolchains.\n" - "\n" - " For example, a file is in a target might be compiled twice:\n" - " once in the default toolchain and once in a secondary one. Without\n" - " this flag, only the default toolchain one will be matched and\n" - " printed (potentially with its recursive dependencies, depending on\n" - " the other options). With this flag, both will be printed\n" - " (potentially with both of their recursive dependencies).\n" + ALL_TOOLCHAINS_SWITCH_HELP "\n" TARGET_PRINTING_MODE_COMMAND_LINE_HELP "\n" @@ -397,7 +389,7 @@ int RunRefs(const std::vector<std::string>& args) { const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); bool tree = cmdline->HasSwitch("tree"); bool all = cmdline->HasSwitch("all"); - bool all_toolchains = cmdline->HasSwitch("all-toolchains"); + bool all_toolchains = cmdline->HasSwitch(switches::kAllToolchains); Setup* setup = new Setup; setup->build_settings().set_check_for_bad_items(false); diff --git a/chromium/tools/gn/commands.cc b/chromium/tools/gn/commands.cc index ed7a009d6af..8682d920dfb 100644 --- a/chromium/tools/gn/commands.cc +++ b/chromium/tools/gn/commands.cc @@ -5,6 +5,7 @@ #include "tools/gn/commands.h" #include "base/command_line.h" +#include "base/strings/string_split.h" #include "tools/gn/builder.h" #include "tools/gn/filesystem_utils.h" #include "tools/gn/item.h" @@ -468,6 +469,27 @@ void FilterTargetsByPatterns(const std::vector<const Target*>& input, } } +bool FilterPatternsFromString(const BuildSettings* build_settings, + const std::string& label_list_string, + std::vector<LabelPattern>* filters, + Err* err) { + std::vector<std::string> tokens = base::SplitString( + label_list_string, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + SourceDir root_dir = + SourceDirForCurrentDirectory(build_settings->root_path()); + + filters->reserve(tokens.size()); + for (const std::string& token : tokens) { + LabelPattern pattern = + LabelPattern::GetPattern(root_dir, Value(nullptr, token), err); + if (err->has_error()) + return false; + filters->push_back(pattern); + } + + return true; +} + void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets) { if (targets->empty()) return; diff --git a/chromium/tools/gn/commands.h b/chromium/tools/gn/commands.h index 9d8af5cb7d0..fdd10fcc231 100644 --- a/chromium/tools/gn/commands.h +++ b/chromium/tools/gn/commands.h @@ -140,6 +140,12 @@ void FilterTargetsByPatterns(const std::vector<const Target*>& input, const std::vector<LabelPattern>& filter, UniqueVector<const Target*>* output); +// Builds a list of pattern from a semicolon-separated list of labels. +bool FilterPatternsFromString(const BuildSettings* build_settings, + const std::string& label_list_string, + std::vector<LabelPattern>* filters, + Err* err); + // These are the documentation strings for the command-line flags used by // FilterAndPrintTargets. Commands that call that function should incorporate // these into their help. diff --git a/chromium/tools/gn/config_values.cc b/chromium/tools/gn/config_values.cc index 73486cd84bf..cfcb9e4387b 100644 --- a/chromium/tools/gn/config_values.cc +++ b/chromium/tools/gn/config_values.cc @@ -24,6 +24,7 @@ ConfigValues::~ConfigValues() { void ConfigValues::AppendValues(const ConfigValues& append) { VectorAppend(&asmflags_, append.asmflags_); + VectorAppend(&arflags_, append.arflags_); VectorAppend(&cflags_, append.cflags_); VectorAppend(&cflags_c_, append.cflags_c_); VectorAppend(&cflags_cc_, append.cflags_cc_); diff --git a/chromium/tools/gn/config_values.h b/chromium/tools/gn/config_values.h index 823f1df9fc4..af97c2bc62c 100644 --- a/chromium/tools/gn/config_values.h +++ b/chromium/tools/gn/config_values.h @@ -30,6 +30,11 @@ class ConfigValues { const std::vector<SourceDir>& name() const { return name##_; } \ std::vector<SourceDir>& name() { return name##_; } + // ================================================================= + // IMPORTANT: If you add a new one, be sure to update AppendValues() + // and command_desc.cc. + // ================================================================= + STRING_VALUES_ACCESSOR(arflags) STRING_VALUES_ACCESSOR(asmflags) STRING_VALUES_ACCESSOR(cflags) STRING_VALUES_ACCESSOR(cflags_c) @@ -40,7 +45,10 @@ class ConfigValues { DIR_VALUES_ACCESSOR (include_dirs) STRING_VALUES_ACCESSOR(ldflags) DIR_VALUES_ACCESSOR (lib_dirs) - // If you add a new one, be sure to update AppendValues(). + // ================================================================= + // IMPORTANT: If you add a new one, be sure to update AppendValues() + // and command_desc.cc. + // ================================================================= #undef STRING_VALUES_ACCESSOR #undef DIR_VALUES_ACCESSOR @@ -65,6 +73,7 @@ class ConfigValues { } private: + std::vector<std::string> arflags_; std::vector<std::string> asmflags_; std::vector<std::string> cflags_; std::vector<std::string> cflags_c_; diff --git a/chromium/tools/gn/config_values_generator.cc b/chromium/tools/gn/config_values_generator.cc index 3cc8235face..e92f091352d 100644 --- a/chromium/tools/gn/config_values_generator.cc +++ b/chromium/tools/gn/config_values_generator.cc @@ -67,6 +67,7 @@ void ConfigValuesGenerator::Run() { GetDirList(scope_, #name, config_values_, input_dir_, \ &ConfigValues::name, err_); + FILL_STRING_CONFIG_VALUE(arflags) FILL_STRING_CONFIG_VALUE(asmflags) FILL_STRING_CONFIG_VALUE(cflags) FILL_STRING_CONFIG_VALUE(cflags_c) diff --git a/chromium/tools/gn/create_bundle_target_generator.cc b/chromium/tools/gn/create_bundle_target_generator.cc index 206a91861e9..83749983e6d 100644 --- a/chromium/tools/gn/create_bundle_target_generator.cc +++ b/chromium/tools/gn/create_bundle_target_generator.cc @@ -25,7 +25,7 @@ void CreateBundleTargetGenerator::DoRun() { target_->set_output_type(Target::CREATE_BUNDLE); BundleData& bundle_data = target_->bundle_data(); - if (!GetBundleDir(std::string(), + if (!GetBundleDir(SourceDir(), variables::kBundleRootDir, &bundle_data.root_dir())) return; @@ -41,29 +41,39 @@ void CreateBundleTargetGenerator::DoRun() { variables::kBundlePlugInsDir, &bundle_data.plugins_dir())) return; + + const Value* value = scope_->GetValue(variables::kProductType, true); + if (value) { + if (!value->VerifyTypeIs(Value::STRING, err_)) + return; + + bundle_data.product_type().assign(value->string_value()); + } } bool CreateBundleTargetGenerator::GetBundleDir( - const std::string& bundle_root_dir, + const SourceDir& bundle_root_dir, const base::StringPiece& name, - std::string* bundle_dir) { + SourceDir* bundle_dir) { const Value* value = scope_->GetValue(name, true); if (!value) return true; if (!value->VerifyTypeIs(Value::STRING, err_)) return false; - const std::string& str = value->string_value(); + std::string str = value->string_value(); + if (!str.empty() && str[str.size() - 1] != '/') + str.push_back('/'); if (!EnsureStringIsInOutputDir(GetBuildSettings()->build_dir(), str, value->origin(), err_)) return false; - if (str != bundle_root_dir && - !IsStringInOutputDir(SourceDir(bundle_root_dir), str)) { + if (str != bundle_root_dir.value() && + !IsStringInOutputDir(bundle_root_dir, str)) { *err_ = Err(value->origin(), "Path is not in bundle root dir.", "The given file should be in the bundle root directory or below.\n" "Normally you would do \"$bundle_root_dir/foo\". I interpreted this\n" "as \"" + str + "\"."); return false; } - bundle_dir->assign(value->string_value()); + bundle_dir->SwapValue(&str); return true; } diff --git a/chromium/tools/gn/create_bundle_target_generator.h b/chromium/tools/gn/create_bundle_target_generator.h index db82b8a4c0b..50040b8744d 100644 --- a/chromium/tools/gn/create_bundle_target_generator.h +++ b/chromium/tools/gn/create_bundle_target_generator.h @@ -8,6 +8,8 @@ #include "base/macros.h" #include "tools/gn/target_generator.h" +class SourceDir; + // Populates a Target with the values from a create_bundle rule. class CreateBundleTargetGenerator : public TargetGenerator { public: @@ -21,9 +23,9 @@ class CreateBundleTargetGenerator : public TargetGenerator { void DoRun() override; private: - bool GetBundleDir(const std::string& bundle_root_dir, + bool GetBundleDir(const SourceDir& bundle_root_dir, const base::StringPiece& name, - std::string* bundle_dir); + SourceDir* bundle_dir); DISALLOW_COPY_AND_ASSIGN(CreateBundleTargetGenerator); }; diff --git a/chromium/tools/gn/docs/cookbook.md b/chromium/tools/gn/docs/cookbook.md index febc16c17a6..687d9eb9e01 100644 --- a/chromium/tools/gn/docs/cookbook.md +++ b/chromium/tools/gn/docs/cookbook.md @@ -122,6 +122,7 @@ component("base") { 'sources': [ 'a.cc', 'b.cc', + 'c.cc', ], 'dependencies': [ '<(DEPTH)/base/base.gyp:foo', @@ -149,22 +150,26 @@ component("base") { ``` sources = [ - "a.cc", - "b.cc", + "c.cc", ] deps = [ "//base:foo", ] if (is_win) { - sources -= [ "a.cc" ] - sources += [ "foo.cc" ] + sources += [ + "b.cc", + "foo.cc', + ] deps += [ "//base:bar" ] } else { - sources -= [ "b.cc" ] + sources += [ "a.cc" ] } ``` +Note that in GN we prefer to only add files when needed, and don't add all of +them at first only to remove them later like in gyp. + ## Variable mappings ### Build configuration @@ -279,8 +284,6 @@ places are noted in the table below. | `use_gnome_keyring` (0/1) | `is_desktop_linux` (true/false) | | | `use_goma` (0/1) | `use_goma` (true/false) | `//build/toolchain/goma.gni` | | `use_nss_certs` (0/1) | `use_nss_certs` (true/false) | `//build/config/crypto.gni` (Many of these conditions can be deleted, see the "SSL" notes on targets below.) | -| `use_nss_verifier` (0/1) | `use_nss_verifier` (true/false) | `//build/config/crypto.gni` (Many of these conditions can be deleted, see the "SSL" notes on targets below.) | -| `use_openssl` (0/1) | `use_openssl` (true/false) | `//build/config/crypto.gni` (Many of these conditions can be deleted, see the "SSL" notes on targets below.) | | `use_pango` (0/1) | `use_pango` (true/false) | `//build/config/ui.gni` | | `use_ozone` (0/1) | `use_ozone` (true/false) | `//build/config/ui.gni` | | `use_seccomp_bpf` (0/1) | `use_seccomp_bpf` (true/false) | `//build/config/features.gni` | @@ -302,8 +305,8 @@ targets only, don't add stuff here just because you converted it.) | `base/base.gyp:run_all_unittests` | `//base/test:run_all_unittests` | | | `base/base.gyp:test_support_base` | `//base/test:test_support` | | | `base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations` | `//base/third_party/dynamic_annotations` | | -| `build/linux/system.gyp:*` (except ssl) | `//build/config/linux:*` | Linux system targets | -| `build/linux/system.gyp:ssl` | `//crypto:platform` | SSL | +| `build/linux/system.gyp:*` (except nss) | `//build/config/linux:*` | Linux system targets | +| `build/linux/system.gyp:nss` | `//crypto:platform` | SSL | | `net/third_party/nss/ssl.gyp:libssl` | `//crypto:platform` | SSL | | `skia/skia.gyp:skia` | `//skia` | | | `testing/gmock.gyp:gmock` | `//testing/gmock` | Secondary tree | diff --git a/chromium/tools/gn/docs/reference.md b/chromium/tools/gn/docs/reference.md index 22cbee0aa68..c596b27f25c 100644 --- a/chromium/tools/gn/docs/reference.md +++ b/chromium/tools/gn/docs/reference.md @@ -70,7 +70,29 @@ ``` -## **\--markdown**: write the output in the Markdown format. +## **\--fail-on-unused-args**: Treat unused build args as fatal errors. + +``` + If you set a value in a build's "gn args" and never use it in the + build (in a declare_args() block), GN will normally print an error + but not fail the build. + + In many cases engineers would use build args to enable or disable + features that would sometimes get removed. It would by annoying to + block work for typically benign problems. In Chrome in particular, + flags might be configured for build bots in a separate infrastructure + repository, or a declare_args block might be changed in a third party + repository. Treating these errors as blocking forced complex multi- + way patches to land what would otherwise be simple changes. + + In some cases, such concerns are not as important, and a mismatch + in build flags between the invoker of the build and the build files + represents a critical mismatch that should be immediately fixed. Such + users can set this flag to force GN to fail in that case. + + +``` +## **\--markdown**: Write help output in the Markdown format. ## **\--[no]color**: Forces colored output on or off. @@ -154,6 +176,16 @@ ``` +## **\--script-executable**: Set the executable used to execute scripts. + +``` + By default GN searches the PATH for Python to execute scripts in + action targets and exec_script calls. This flag allows the + specification of a specific Python executable or potentially + a different language interpreter. + + +``` ## **\--threads**: Specify number of worker threads. ``` @@ -414,74 +446,47 @@ ``` -## **gn desc <out_dir> <target label> [<what to show>] [\--blame]** +## **gn desc <out_dir> <label or pattern> [<what to show>] [\--blame]** ``` - Displays information about a given labeled target for the given build. - The build parameters will be taken for the build in the given - <out_dir>. + Displays information about a given target or config. The build + build parameters will be taken for the build in the given <out_dir>. + + The <label or pattern> can be a target label, a config label, or a + label pattern (see "gn help label_pattern"). A label pattern will + only match targets. ``` ### **Possibilities for <what to show>** + ``` (If unspecified an overall summary will be displayed.) - sources - Source files. - - inputs - Additional input dependencies. - - public - Public header files. - - check_includes - Whether "gn check" checks this target for include usage. - - allow_circular_includes_from - Permit includes from these targets. - - visibility - Prints which targets can depend on this one. - - testonly - Whether this target may only be used in tests. - - configs - Shows configs applied to the given target, sorted in the order - they're specified. This includes both configs specified in the - "configs" variable, as well as configs pushed onto this target - via dependencies specifying "all" or "direct" dependent - configs. - - deps - Show immediate or recursive dependencies. See below for flags that - control deps printing. - - public_configs all_dependent_configs - Shows the labels of configs applied to targets that depend on this - one (either directly or all of them). - - script + allow_circular_includes_from + arflags [--blame] args + cflags [--blame] + cflags_cc [--blame] + cflags_cxx [--blame] + check_includes + configs [--tree] (see below) + defines [--blame] depfile - Actions only. The script and related values. - - outputs - Outputs for script and copy target types. - - defines [--blame] - include_dirs [--blame] - cflags [--blame] - cflags_cc [--blame] - cflags_cxx [--blame] - ldflags [--blame] + deps [--all] [--tree] (see below) + include_dirs [--blame] + inputs + ldflags [--blame] lib_dirs libs - Shows the given values taken from the target and all configs - applying. See "--blame" below. + outputs + public_configs + public + script + sources + testonly + visibility runtime_deps Compute all runtime deps for the given target. This is a @@ -498,17 +503,49 @@ ### **Shared flags** ``` + --all-toolchains + Normally only inputs in the default toolchain will be included. + This switch will turn on matching all toolchains. + + For example, a file is in a target might be compiled twice: + once in the default toolchain and once in a secondary one. Without + this flag, only the default toolchain one will be matched by + wildcards. With this flag, both will be matched. + +``` + +### **Target flags** + +``` --blame - Used with any value specified by a config, this will name - the config that specified the value. This doesn't currently work - for libs and lib_dirs because those are inherited and are more - complicated to figure out the blame (patches welcome). + Used with any value specified on a config, this will name + the config that cause that target to get the flag. This doesn't + currently work for libs and lib_dirs because those are inherited + and are more complicated to figure out the blame (patches + welcome). ``` -### **Flags that control how deps are printed** +### **Configs** ``` + The "configs" section will list all configs that apply. For targets + this will include configs specified in the "configs" variable of + the target, and also configs pushed onto this target via public + or "all dependent" configs. + + Configs can have child configs. Specifying --tree will show the + hierarchy. + +``` + +### **Printing deps** + +``` + Deps will include all public, private, and data deps (TODO this could + be clarified and enhanced) sorted in order applying. The following + may be used: + --all Collects all recursive dependencies and prints a sorted flat list. Also usable with --tree (see below). @@ -654,16 +691,53 @@ (default Visual Studio version: 2015) "vs2013" - Visual Studio 2013 project/solution files. "vs2015" - Visual Studio 2015 project/solution files. - - --sln=<file_name> - Override default sln file name ("all"). Solution file is written - to the root build directory. Only for Visual Studio. + "xcode" - Xcode workspace/solution files. + "qtcreator" - QtCreator project files. --filters=<path_prefixes> Semicolon-separated list of label patterns used to limit the set of generated projects (see "gn help label_pattern"). Only - matching targets will be included to the solution. Only for Visual - Studio. + matching targets will be included to the solution. Only used for + Visual Studio and Xcode. + +``` + +### **Visual Studio Flags** + +``` + --sln=<file_name> + Override default sln file name ("all"). Solution file is written + to the root build directory. + +``` + +### **Xcode Flags** + +``` + --workspace=<file_name> + Override defaut workspace file name ("all"). The workspace file + is written to the root build directory. + + --ninja-extra-args=<string> + This string is passed without any quoting to the ninja invocation + command-line. Can be used to configure ninja flags, like "-j" if + using goma for example. + + --root-target=<target_name> + Name of the target corresponding to "All" target in Xcode. + If unset, "All" invokes ninja without any target + and builds everything. + +``` + +### **QtCreator Flags** + +``` + --root-target=<target_name> + Name of the root target for which the QtCreator project will be + generated to contain files of it and its dependencies. If unset, + the whole build graph will be omitted. + ``` @@ -738,10 +812,13 @@ root build directory. --all-toolchains - Matches all toolchains. When set, if the label pattern does not - specify an explicit toolchain, labels from all toolchains will be - matched. When unset, only targets in the default toolchain will - be matched unless an explicit toolchain in the label is set. + Normally only inputs in the default toolchain will be included. + This switch will turn on matching all toolchains. + + For example, a file is in a target might be compiled twice: + once in the default toolchain and once in a secondary one. Without + this flag, only the default toolchain one will be matched by + wildcards. With this flag, both will be matched. --testonly=(true|false) Restrict outputs to targets with the testonly flag set @@ -870,10 +947,8 @@ For example, a file is in a target might be compiled twice: once in the default toolchain and once in a secondary one. Without - this flag, only the default toolchain one will be matched and - printed (potentially with its recursive dependencies, depending on - the other options). With this flag, both will be printed - (potentially with both of their recursive dependencies). + this flag, only the default toolchain one will be matched by + wildcards. With this flag, both will be matched. --as=(buildfile|label|output) How to print targets. @@ -1349,7 +1424,8 @@ ``` bundle_root_dir*, bundle_resources_dir*, bundle_executable_dir*, - bundle_plugins_dir*, deps, data_deps, public_deps, visibility + bundle_plugins_dir*, deps, data_deps, public_deps, visibility, + product_type * = required ``` @@ -1399,6 +1475,7 @@ } create_bundle("${app_name}.app") { + product_type = "com.apple.product-type.application" deps = [ ":${app_name}_bundle_executable", ":${app_name}_bundle_info_plist", @@ -2730,6 +2807,20 @@ The command to run. + default_output_dir [string with substitutions] + Valid for: linker tools + + Default directory name for the output file relative to the + root_build_dir. It can contain other substitution patterns. + This will be the default value for the {{output_dir}} expansion + (discussed below) but will be overridden by the "output_dir" + variable in a target, if one is specified. + + GN doesn't do anything with this string other than pass it + along, potentially with target-specific overrides. It is the + tool's job to use the expansion so that the files will be in + the right place. + default_output_extension [string] Valid for: linker tools @@ -2746,7 +2837,7 @@ Example: default_output_extension = ".exe" - depfile [string] + depfile [string with substitutions] Valid for: compiler tools (optional) If the tool can write ".d" files, this specifies the name of @@ -2808,13 +2899,11 @@ ] Example for a linker tool that produces a .dll and a .lib. The - use of {{output_extension}} rather than hardcoding ".dll" - allows the extension of the library to be overridden on a - target-by-target basis, but in this example, it always - produces a ".lib" import library: + use of {{target_output_name}}, {{output_extension}} and + {{output_dir}} allows the target to override these values. outputs = [ - "{{root_out_dir}}/{{target_output_name}}{{output_extension}}", - "{{root_out_dir}}/{{target_output_name}}.lib", + "{{output_dir}}/{{target_output_name}}{{output_extension}}", + "{{output_dir}}/{{target_output_name}}.lib", ] link_output [string with substitutions] @@ -2827,7 +2916,7 @@ should match entries in the "outputs". If unspecified, the first item in the "outputs" array will be used for all. See "Separate linking and dependencies for shared libraries" - below for more. If link_output is set but runtime_link_output + below for more. If link_output is set but runtime_link_output is not set, runtime_link_output defaults to link_output. On Windows, where the tools produce a .dll shared library and @@ -2937,7 +3026,7 @@ {{target_out_dir}} The directory of the generated file and output directories, respectively, for the current target. There is no trailing - slash. + slash. See also {{output_dir}} for linker tools. Example: "out/base/test" {{target_output_name}} @@ -2991,6 +3080,7 @@ Example: "gen/base/test" Linker tools have multiple inputs and (potentially) multiple outputs + The static library tool ("alink") is not considered a linker tool. The following expansions are available: {{inputs}} @@ -3020,6 +3110,21 @@ Example: "-lfoo -lbar" + {{output_dir}} + The value of the "output_dir" variable in the target, or the + the value of the "default_output_dir" value in the tool if the + target does not override the output directory. This will be + relative to the root_build_dir and will not end in a slash. + Will be "." for output to the root_build_dir. + + This is subtly different than {{target_out_dir}} which is + defined by GN based on the target's path and not overridable. + {{output_dir}} is for the final output, {{target_out_dir}} is + generally for object files and other outputs. + + Usually {{output_dir}} would be defined in terms of either + {{target_out_dir}} or {{root_out_dir}} + {{output_extension}} The value of the "output_extension" variable in the target, or the value of the "default_output_extension" value in the @@ -3035,6 +3140,9 @@ These should generally be treated the same as libs by your tool. Example: "libfoo.so libbar.so" + The static library ("alink") tool allows {{arflags}} plus the common + tool substitutions. + The copy tool allows the common compiler/linker substitutions, plus {{source}} which is the source of the copy. The stamp tool allows only the common tool substitutions. @@ -3075,13 +3183,13 @@ tool("solink") { command = "..." outputs = [ - "{{root_out_dir}}/{{target_output_name}}{{output_extension}}", - "{{root_out_dir}}/{{target_output_name}}{{output_extension}}.TOC", + "{{output_dir}}/{{target_output_name}}{{output_extension}}", + "{{output_dir}}/{{target_output_name}}{{output_extension}}.TOC", ] link_output = - "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" + "{{output_dir}}/{{target_output_name}}{{output_extension}}" depend_output = - "{{root_out_dir}}/{{target_output_name}}{{output_extension}}.TOC" + "{{output_dir}}/{{target_output_name}}{{output_extension}}.TOC" restat = true } @@ -3698,6 +3806,42 @@ ``` +## **arflags**: Arguments passed to static_library archiver. + +``` + A list of flags passed to the archive/lib command that creates static + libraries. + + arflags are NOT pushed to dependents, so applying arflags to source + sets or any other target type will be a no-op. As with ldflags, + you could put the arflags in a config and set that as a public or + "all dependent" config, but that will likely not be what you want. + If you have a chain of static libraries dependent on each other, + this can cause the flags to propagate up to other static libraries. + Due to the nature of how arflags are typically used, you will normally + want to apply them directly on static_library targets themselves. + +``` + +### **Ordering of flags and values** + +``` + 1. Those set on the current target (not in a config). + 2. Those set on the "configs" on the target in order that the + configs appear in the list. + 3. Those set on the "all_dependent_configs" on the target in order + that the configs appear in the list. + 4. Those set on the "public_configs" on the target in order that + those configs appear in the list. + 5. all_dependent_configs pulled from dependencies, in the order of + the "deps" list. This is done recursively. If a config appears + more than once, only the first occurance will be used. + 6. public_configs pulled from dependencies, in the order of the + "deps" list. If a dependency is public, they will be applied + recursively. + + +``` ## **args**: Arguments passed to an action. ``` @@ -4075,9 +4219,16 @@ In some cases the static library might be the final desired output. For example, you may be producing a static library for distribution to third parties. In this case, the static library should include code - for all dependencies in one complete package. Since GN does not unpack - static libraries to forward their contents up the dependency chain, - it is an error for complete static libraries to depend on other static + for all dependencies in one complete package. However, complete static + libraries themselves are never linked into other complete static + libraries. All complete static libraries are for distribution and + linking them in would cause code duplication in this case. If the + static library is not for distribution, it should not be complete. + + GN treats non-complete static libraries as source sets when they are + linked into complete static libraries. This is done because some tools + like AR do not handle dependent static libraries properly. This makes + it easier to write "alink" rules. In rare cases it makes sense to list a header in more than one target if it could be considered conceptually a member of both. @@ -4241,7 +4392,7 @@ generated files both in the "outputs" list as well as the "data" list. - By convention, directories are be listed with a trailing slash: + By convention, directories are listed with a trailing slash: data = [ "test/data/" ] However, no verification is done on these so GN doesn't enforce this. The paths are just rebased and passed along when requested. @@ -4660,6 +4811,36 @@ ``` +## **output_dir**: [directory] Directory to put output file in. + +``` + For library and executable targets, overrides the directory for the + final output. This must be in the root_build_dir or a child thereof. + + This should generally be in the root_out_dir or a subdirectory thereof + (the root_out_dir will be the same as the root_build_dir for the + default toolchain, and will be a subdirectory for other toolchains). + Not putting the output in a subdirectory of root_out_dir can result + in collisions between different toolchains, so you will need to take + steps to ensure that your target is only present in one toolchain. + + Normally the toolchain specifies the output directory for libraries + and executables (see "gn help tool"). You will have to consult that + for the default location. The default location will be used if + output_dir is undefined or empty. + +``` + +### **Example** + +``` + shared_library("doom_melon") { + output_dir = "$root_out_dir/plugin_libs" + ... + } + + +``` ## **output_extension**: Value to use for the output's file extension. ``` @@ -4857,6 +5038,18 @@ ``` +## **product_type**: Product type for Xcode projects. + +``` + Correspond to the type of the product of a create_bundle target. Only + meaningful to Xcode (used as part of the Xcode project generation). + + When generating Xcode project files, only create_bundle target with + a non-empty product_type will have a corresponding target in Xcode + project. + + +``` ## **public**: Declare public header files for a target. ``` @@ -5724,6 +5917,10 @@ ### **Placeholders** ``` + This section discusses only placeholders for actions. There are other + placeholders used in the definition of tools. See "gn help tool" for + those. + {{source}} The name of the source file including directory (*). This will generally be used for specifying inputs to a script in the @@ -5824,11 +6021,13 @@ ** \--args**: Specifies build arguments overrides. ** \--color**: Force colored output. ** \--dotfile**: Override the name of the ".gn" file. -** \--markdown**: write the output in the Markdown format. +** \--fail-on-unused-args**: Treat unused build args as fatal errors. +** \--markdown**: Write help output in the Markdown format. ** \--nocolor**: Force non-colored output. ** -q**: Quiet mode. Don't print output on success. ** \--root**: Explicitly specify source root. ** \--runtime-deps-list-file**: Save runtime dependencies for targets in file. +** \--script-executable**: Set the executable used to execute scripts. ** \--threads**: Specify number of worker threads. ** \--time**: Outputs a summary of how long everything took. ** \--tracelog**: Writes a Chrome-compatible trace log to the given file. diff --git a/chromium/tools/gn/example/build/toolchain/BUILD.gn b/chromium/tools/gn/example/build/toolchain/BUILD.gn index 77e33fecf61..d9457d7eae4 100644 --- a/chromium/tools/gn/example/build/toolchain/BUILD.gn +++ b/chromium/tools/gn/example/build/toolchain/BUILD.gn @@ -37,9 +37,10 @@ toolchain("gcc") { tool("solink") { soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". + sofile = "{{output_dir}}/$soname" rspfile = soname + ".rsp" - command = "g++ -shared {{ldflags}} -o $soname -Wl,-soname=$soname @$rspfile" + command = "g++ -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile" rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}" description = "SOLINK $soname" @@ -49,11 +50,15 @@ toolchain("gcc") { # specifies). default_output_extension = ".so" + # Use this for {{output_dir}} expansions unless a target manually overrides + # it (in which case {{output_dir}} will be what the target specifies). + default_output_dir = "{{root_out_dir}}" + outputs = [ - soname, + sofile, ] - link_output = soname - depend_output = soname + link_output = sofile + depend_output = sofile output_prefix = "lib" } @@ -62,6 +67,7 @@ toolchain("gcc") { rspfile = "$outfile.rsp" command = "g++ {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}" description = "LINK $outfile" + default_output_dir = "{{root_out_dir}}" rspfile_content = "{{inputs}}" outputs = [ outfile, diff --git a/chromium/tools/gn/function_foreach.cc b/chromium/tools/gn/function_foreach.cc index 549ebe407c1..b74fc186af1 100644 --- a/chromium/tools/gn/function_foreach.cc +++ b/chromium/tools/gn/function_foreach.cc @@ -47,7 +47,7 @@ Value RunForEach(Scope* scope, const FunctionCallNode* function, const ListNode* args_list, Err* err) { - const std::vector<const ParseNode*>& args_vector = args_list->contents(); + const auto& args_vector = args_list->contents(); if (args_vector.size() != 2) { *err = Err(function, "Wrong number of arguments to foreach().", "Expecting exactly two."); @@ -57,7 +57,8 @@ Value RunForEach(Scope* scope, // Extract the loop variable. const IdentifierNode* identifier = args_vector[0]->AsIdentifier(); if (!identifier) { - *err = Err(args_vector[0], "Expected an identifier for the loop var."); + *err = + Err(args_vector[0].get(), "Expected an identifier for the loop var."); return Value(); } base::StringPiece loop_var(identifier->value().value()); @@ -69,7 +70,7 @@ Value RunForEach(Scope* scope, if (list_identifier) { list_value = scope->GetValue(list_identifier->value().value(), true); if (!list_value) { - *err = Err(args_vector[1], "Undefined identifier."); + *err = Err(args_vector[1].get(), "Undefined identifier."); return Value(); } } else { diff --git a/chromium/tools/gn/function_forward_variables_from.cc b/chromium/tools/gn/function_forward_variables_from.cc index ee141287715..8f3b90dec71 100644 --- a/chromium/tools/gn/function_forward_variables_from.cc +++ b/chromium/tools/gn/function_forward_variables_from.cc @@ -54,6 +54,18 @@ void ForwardValuesFromList(Scope* source, return; } + // Don't allow clobbering existing values. + const Value* existing_value = dest->GetValue(storage_key); + if (existing_value) { + *err = Err(cur, "Clobbering existing value.", + "The current scope already defines a value \"" + + cur.string_value() + "\".\nforward_variables_from() won't clobber " + "existing values. If you want to\nmerge lists, you'll need to " + "do this explicitly."); + err->AppendSubErr(Err(*existing_value, "value being clobbered.")); + return; + } + // Keep the origin information from the original value. The normal // usage is for this to be used in a template, and if there's an error, // the user expects to see the line where they set the variable @@ -153,7 +165,7 @@ Value RunForwardVariablesFrom(Scope* scope, const FunctionCallNode* function, const ListNode* args_list, Err* err) { - const std::vector<const ParseNode*>& args_vector = args_list->contents(); + const auto& args_vector = args_list->contents(); if (args_vector.size() != 2 && args_vector.size() != 3) { *err = Err(function, "Wrong number of arguments.", "Expecting two or three arguments."); @@ -166,7 +178,7 @@ Value RunForwardVariablesFrom(Scope* scope, // to execute the ParseNode and get the value out if it's not an identifer. const IdentifierNode* identifier = args_vector[0]->AsIdentifier(); if (!identifier) { - *err = Err(args_vector[0], "Expected an identifier for the scope."); + *err = Err(args_vector[0].get(), "Expected an identifier for the scope."); return Value(); } diff --git a/chromium/tools/gn/function_forward_variables_from_unittest.cc b/chromium/tools/gn/function_forward_variables_from_unittest.cc index e5137a48b26..2e6f5a2800c 100644 --- a/chromium/tools/gn/function_forward_variables_from_unittest.cc +++ b/chromium/tools/gn/function_forward_variables_from_unittest.cc @@ -8,28 +8,46 @@ TEST(FunctionForwardVariablesFrom, List) { Scheduler scheduler; - TestWithScope setup; - - // Defines a template and copy the two x and y, and z values out. - TestParseInput input( - "template(\"a\") {\n" - " forward_variables_from(invoker, [\"x\", \"y\", \"z\"])\n" - " assert(!defined(z))\n" // "z" should still be undefined. - " print(\"$target_name, $x, $y\")\n" - "}\n" - "a(\"target\") {\n" - " x = 1\n" - " y = 2\n" - "}\n"); - - ASSERT_FALSE(input.has_error()); - Err err; - input.parsed()->Execute(setup.scope(), &err); - ASSERT_FALSE(err.has_error()) << err.message(); - - EXPECT_EQ("target, 1, 2\n", setup.print_output()); - setup.print_output().clear(); + std::string program = + "template(\"a\") {\n" + " forward_variables_from(invoker, [\"x\", \"y\", \"z\"])\n" + " assert(!defined(z))\n" // "z" should still be undefined. + " print(\"$target_name, $x, $y\")\n" + "}\n" + "a(\"target\") {\n" + " x = 1\n" + " y = 2\n" + "}\n"; + + { + TestWithScope setup; + + // Defines a template and copy the two x and y, and z values out. + TestParseInput input(program); + ASSERT_FALSE(input.has_error()); + + input.parsed()->Execute(setup.scope(), &err); + ASSERT_FALSE(err.has_error()) << err.message(); + + EXPECT_EQ("target, 1, 2\n", setup.print_output()); + setup.print_output().clear(); + } + + { + TestWithScope setup; + + // Test that the same input but forwarding a variable with the name of + // something in the given scope throws an error rather than clobbering it. + // This uses the same known-good program as before, but adds another + // variable in the scope before it. + TestParseInput clobber("x = 1\n" + program); + ASSERT_FALSE(clobber.has_error()); + + clobber.parsed()->Execute(setup.scope(), &err); + ASSERT_TRUE(err.has_error()); // Should thow a clobber error. + EXPECT_EQ("Clobbering existing value.", err.message()); + } } TEST(FunctionForwardVariablesFrom, ListWithExclusion) { diff --git a/chromium/tools/gn/function_toolchain.cc b/chromium/tools/gn/function_toolchain.cc index f3344ffdfe8..aaa9b7efaa7 100644 --- a/chromium/tools/gn/function_toolchain.cc +++ b/chromium/tools/gn/function_toolchain.cc @@ -194,8 +194,8 @@ bool IsCompilerTool(Toolchain::ToolType type) { } bool IsLinkerTool(Toolchain::ToolType type) { - return type == Toolchain::TYPE_ALINK || - type == Toolchain::TYPE_SOLINK || + // "alink" is not counted as in the generic "linker" tool list. + return type == Toolchain::TYPE_SOLINK || type == Toolchain::TYPE_SOLINK_MODULE || type == Toolchain::TYPE_LINK; } @@ -418,6 +418,20 @@ const char kTool_Help[] = "\n" " The command to run.\n" "\n" + " default_output_dir [string with substitutions]\n" + " Valid for: linker tools\n" + "\n" + " Default directory name for the output file relative to the\n" + " root_build_dir. It can contain other substitution patterns.\n" + " This will be the default value for the {{output_dir}} expansion\n" + " (discussed below) but will be overridden by the \"output_dir\"\n" + " variable in a target, if one is specified.\n" + "\n" + " GN doesn't do anything with this string other than pass it\n" + " along, potentially with target-specific overrides. It is the\n" + " tool's job to use the expansion so that the files will be in\n" + " the right place.\n" + "\n" " default_output_extension [string]\n" " Valid for: linker tools\n" "\n" @@ -434,7 +448,7 @@ const char kTool_Help[] = "\n" " Example: default_output_extension = \".exe\"\n" "\n" - " depfile [string]\n" + " depfile [string with substitutions]\n" " Valid for: compiler tools (optional)\n" "\n" " If the tool can write \".d\" files, this specifies the name of\n" @@ -496,14 +510,12 @@ const char kTool_Help[] = " ]\n" "\n" " Example for a linker tool that produces a .dll and a .lib. The\n" - " use of {{output_extension}} rather than hardcoding \".dll\"\n" - " allows the extension of the library to be overridden on a\n" - " target-by-target basis, but in this example, it always\n" - " produces a \".lib\" import library:\n" + " use of {{target_output_name}}, {{output_extension}} and\n" + " {{output_dir}} allows the target to override these values.\n" " outputs = [\n" - " \"{{root_out_dir}}/{{target_output_name}}" + " \"{{output_dir}}/{{target_output_name}}" "{{output_extension}}\",\n" - " \"{{root_out_dir}}/{{target_output_name}}.lib\",\n" + " \"{{output_dir}}/{{target_output_name}}.lib\",\n" " ]\n" "\n" " link_output [string with substitutions]\n" @@ -516,7 +528,7 @@ const char kTool_Help[] = " should match entries in the \"outputs\". If unspecified, the\n" " first item in the \"outputs\" array will be used for all. See\n" " \"Separate linking and dependencies for shared libraries\"\n" - " below for more. If link_output is set but runtime_link_output\n" + " below for more. If link_output is set but runtime_link_output\n" " is not set, runtime_link_output defaults to link_output.\n" "\n" " On Windows, where the tools produce a .dll shared library and\n" @@ -624,7 +636,7 @@ const char kTool_Help[] = " {{target_out_dir}}\n" " The directory of the generated file and output directories,\n" " respectively, for the current target. There is no trailing\n" - " slash.\n" + " slash. See also {{output_dir}} for linker tools.\n" " Example: \"out/base/test\"\n" "\n" " {{target_output_name}}\n" @@ -678,6 +690,7 @@ const char kTool_Help[] = " Example: \"gen/base/test\"\n" "\n" " Linker tools have multiple inputs and (potentially) multiple outputs\n" + " The static library tool (\"alink\") is not considered a linker tool.\n" " The following expansions are available:\n" "\n" " {{inputs}}\n" @@ -707,6 +720,21 @@ const char kTool_Help[] = "\n" " Example: \"-lfoo -lbar\"\n" "\n" + " {{output_dir}}\n" + " The value of the \"output_dir\" variable in the target, or the\n" + " the value of the \"default_output_dir\" value in the tool if the\n" + " target does not override the output directory. This will be\n" + " relative to the root_build_dir and will not end in a slash.\n" + " Will be \".\" for output to the root_build_dir.\n" + "\n" + " This is subtly different than {{target_out_dir}} which is\n" + " defined by GN based on the target's path and not overridable.\n" + " {{output_dir}} is for the final output, {{target_out_dir}} is\n" + " generally for object files and other outputs.\n" + "\n" + " Usually {{output_dir}} would be defined in terms of either\n" + " {{target_out_dir}} or {{root_out_dir}}\n" + "\n" " {{output_extension}}\n" " The value of the \"output_extension\" variable in the target,\n" " or the value of the \"default_output_extension\" value in the\n" @@ -722,6 +750,9 @@ const char kTool_Help[] = " These should generally be treated the same as libs by your tool.\n" " Example: \"libfoo.so libbar.so\"\n" "\n" + " The static library (\"alink\") tool allows {{arflags}} plus the common\n" + " tool substitutions.\n" + "\n" " The copy tool allows the common compiler/linker substitutions, plus\n" " {{source}} which is the source of the copy. The stamp tool allows\n" " only the common tool substitutions.\n" @@ -759,14 +790,14 @@ const char kTool_Help[] = " tool(\"solink\") {\n" " command = \"...\"\n" " outputs = [\n" - " \"{{root_out_dir}}/{{target_output_name}}{{output_extension}}\",\n" - " \"{{root_out_dir}}/{{target_output_name}}" + " \"{{output_dir}}/{{target_output_name}}{{output_extension}}\",\n" + " \"{{output_dir}}/{{target_output_name}}" "{{output_extension}}.TOC\",\n" " ]\n" " link_output =\n" - " \"{{root_out_dir}}/{{target_output_name}}{{output_extension}}\"\n" + " \"{{output_dir}}/{{target_output_name}}{{output_extension}}\"\n" " depend_output =\n" - " \"{{root_out_dir}}/{{target_output_name}}" + " \"{{output_dir}}/{{target_output_name}}" "{{output_extension}}.TOC\"\n" " restat = true\n" " }\n" @@ -832,6 +863,10 @@ Value RunTool(Scope* scope, } else if (IsLinkerTool(tool_type)) { subst_validator = &IsValidLinkerSubstitution; subst_output_validator = &IsValidLinkerOutputsSubstitution; + } else if (tool_type == Toolchain::TYPE_ALINK) { + subst_validator = &IsValidALinkSubstitution; + // ALink uses the standard output file patterns as other linker tools. + subst_output_validator = &IsValidLinkerOutputsSubstitution; } else if (tool_type == Toolchain::TYPE_COPY || tool_type == Toolchain::TYPE_COPY_BUNDLE_DATA) { subst_validator = &IsValidCopySubstitution; @@ -866,6 +901,8 @@ Value RunTool(Scope* scope, tool.get(), &Tool::set_runtime_link_output, err) || !ReadString(&block_scope, "output_prefix", tool.get(), &Tool::set_output_prefix, err) || + !ReadPattern(&block_scope, "default_output_dir", subst_validator, + tool.get(), &Tool::set_default_output_dir, err) || !ReadPrecompiledHeaderType(&block_scope, tool.get(), err) || !ReadBool(&block_scope, "restat", tool.get(), &Tool::set_restat, err) || !ReadPattern(&block_scope, "rspfile", subst_validator, tool.get(), diff --git a/chromium/tools/gn/functions.cc b/chromium/tools/gn/functions.cc index f6d405d0a56..af413d655b3 100644 --- a/chromium/tools/gn/functions.cc +++ b/chromium/tools/gn/functions.cc @@ -464,7 +464,7 @@ Value RunDefined(Scope* scope, const FunctionCallNode* function, const ListNode* args_list, Err* err) { - const std::vector<const ParseNode*>& args_vector = args_list->contents(); + const auto& args_vector = args_list->contents(); if (args_vector.size() != 1) { *err = Err(function, "Wrong number of arguments to defined().", "Expecting exactly one."); diff --git a/chromium/tools/gn/functions_target.cc b/chromium/tools/gn/functions_target.cc index 7ec5a50dd26..a5f55741296 100644 --- a/chromium/tools/gn/functions_target.cc +++ b/chromium/tools/gn/functions_target.cc @@ -331,7 +331,8 @@ const char kCreateBundle_Help[] = "Variables\n" "\n" " bundle_root_dir*, bundle_resources_dir*, bundle_executable_dir*,\n" - " bundle_plugins_dir*, deps, data_deps, public_deps, visibility\n" + " bundle_plugins_dir*, deps, data_deps, public_deps, visibility,\n" + " product_type\n" " * = required\n" "\n" "Example\n" @@ -378,6 +379,7 @@ const char kCreateBundle_Help[] = " }\n" "\n" " create_bundle(\"${app_name}.app\") {\n" + " product_type = \"com.apple.product-type.application\"\n" " deps = [\n" " \":${app_name}_bundle_executable\",\n" " \":${app_name}_bundle_info_plist\",\n" @@ -654,6 +656,7 @@ const char kStaticLibrary_Help[] = "\n" "Variables\n" "\n" + "complete_static_lib\n" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS diff --git a/chromium/tools/gn/gn.gyp b/chromium/tools/gn/gn.gyp index 79f83a719c8..8428948872d 100644 --- a/chromium/tools/gn/gn.gyp +++ b/chromium/tools/gn/gn.gyp @@ -146,6 +146,8 @@ 'path_output.h', 'pattern.cc', 'pattern.h', + 'qt_creator_writer.cc', + 'qt_creator_writer.h', 'runtime_deps.cc', 'runtime_deps.h', 'scheduler.cc', @@ -207,6 +209,10 @@ 'visual_studio_utils.h', 'visual_studio_writer.cc', 'visual_studio_writer.h', + 'xcode_object.cc', + 'xcode_object.h', + 'xcode_writer.cc', + 'xcode_writer.h', 'xml_element_writer.cc', 'xml_element_writer.h', ], diff --git a/chromium/tools/gn/gn_main.cc b/chromium/tools/gn/gn_main.cc index 135ed561a9c..245270ee52d 100644 --- a/chromium/tools/gn/gn_main.cc +++ b/chromium/tools/gn/gn_main.cc @@ -73,9 +73,12 @@ int main(int argc, char** argv) { if (found_command != command_map.end()) { retval = found_command->second.runner(args); } else { - Err(Location(), - "Command \"" + command + "\" unknown.").PrintToStdout(); - commands::RunHelp(std::vector<std::string>()); + Err(Location(), "Command \"" + command + "\" unknown.").PrintToStdout(); + OutputString( + "Available commands (type \"gn help <command>\" for more details):\n"); + for (const auto& cmd : commands::GetCommands()) + PrintShortHelp(cmd.second.help_short); + retval = 1; } diff --git a/chromium/tools/gn/group_target_generator_unittest.cc b/chromium/tools/gn/group_target_generator_unittest.cc deleted file mode 100644 index 3b0c8244368..00000000000 --- a/chromium/tools/gn/group_target_generator_unittest.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2016 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. - -#include "testing/gtest/include/gtest/gtest.h" -#include "tools/gn/group_target_generator.h" -#include "tools/gn/scheduler.h" -#include "tools/gn/test_with_scope.h" - -namespace { - -// Returns true on success, false if write_file signaled an error. -bool ParseWriteRuntimeDeps(Scope* scope, const std::string& value) { - TestParseInput input( - "group(\"foo\") { write_runtime_deps = " + value + "}"); - if (input.has_error()) - return false; - - Err err; - input.parsed()->Execute(scope, &err); - return !err.has_error(); -} - -} // namespace - - -// Tests that actions can't have output substitutions. -TEST(GroupTargetGenerator, WriteRuntimeDeps) { - Scheduler scheduler; - TestWithScope setup; - Scope::ItemVector items_; - setup.scope()->set_item_collector(&items_); - - // Should refuse to write files outside of the output dir. - EXPECT_FALSE(ParseWriteRuntimeDeps(setup.scope(), "\"//foo.txt\"")); - EXPECT_EQ(0U, scheduler.GetWriteRuntimeDepsTargets().size()); - - // Should fail for garbage inputs. - EXPECT_FALSE(ParseWriteRuntimeDeps(setup.scope(), "0")); - EXPECT_EQ(0U, scheduler.GetWriteRuntimeDepsTargets().size()); - - // Should be able to write inside the out dir. - EXPECT_TRUE(ParseWriteRuntimeDeps(setup.scope(), "\"//out/Debug/foo.txt\"")); - EXPECT_EQ(1U, scheduler.GetWriteRuntimeDepsTargets().size()); -} - diff --git a/chromium/tools/gn/import_manager.cc b/chromium/tools/gn/import_manager.cc index 83cc09020cd..01c88b5a68c 100644 --- a/chromium/tools/gn/import_manager.cc +++ b/chromium/tools/gn/import_manager.cc @@ -4,9 +4,7 @@ #include "tools/gn/import_manager.h" -#include <memory> - -#include "base/stl_util.h" +#include "tools/gn/err.h" #include "tools/gn/parse_tree.h" #include "tools/gn/scheduler.h" #include "tools/gn/scope_per_file_provider.h" @@ -14,10 +12,10 @@ namespace { // Returns a newly-allocated scope on success, null on failure. -Scope* UncachedImport(const Settings* settings, - const SourceFile& file, - const ParseNode* node_for_err, - Err* err) { +std::unique_ptr<Scope> UncachedImport(const Settings* settings, + const SourceFile& file, + const ParseNode* node_for_err, + Err* err) { const ParseNode* node = g_scheduler->input_file_manager()->SyncLoadFile( node_for_err->GetRange(), settings->build_settings(), file, err); if (!node) @@ -33,20 +31,39 @@ Scope* UncachedImport(const Settings* settings, scope->SetProcessingImport(); node->Execute(scope.get(), err); - if (err->has_error()) + if (err->has_error()) { + // If there was an error, append the caller location so the error message + // displays a why the file was imported (esp. useful for failed asserts). + err->AppendSubErr(Err(node_for_err, "whence it was imported.")); return nullptr; + } scope->ClearProcessingImport(); - return scope.release(); + return scope; } -} // namesapce +} // namespace + +struct ImportManager::ImportInfo { + ImportInfo() {} + ~ImportInfo() {} + + // This lock protects the unique_ptr. Once the scope is computed, + // it is const and can be accessed read-only outside of the lock. + base::Lock load_lock; + + std::unique_ptr<const Scope> scope; + + // The result of loading the import. If the load failed, the scope will be + // null but this will be set to error. In this case the thread should not + // attempt to load the file, even if the scope is null. + Err load_result; +}; ImportManager::ImportManager() { } ImportManager::~ImportManager() { - STLDeleteContainerPairSecondPointers(imports_.begin(), imports_.end()); } bool ImportManager::DoImport(const SourceFile& file, @@ -55,39 +72,50 @@ bool ImportManager::DoImport(const SourceFile& file, Err* err) { // See if we have a cached import, but be careful to actually do the scope // copying outside of the lock. - const Scope* imported_scope = nullptr; + ImportInfo* import_info = nullptr; { - base::AutoLock lock(lock_); - ImportMap::const_iterator found = imports_.find(file); - if (found != imports_.end()) - imported_scope = found->second; + base::AutoLock lock(imports_lock_); + std::unique_ptr<ImportInfo>& info_ptr = imports_[file]; + if (!info_ptr) + info_ptr.reset(new ImportInfo); + + // Promote the ImportInfo to outside of the imports lock. + import_info = info_ptr.get(); } - if (!imported_scope) { - // Do a new import of the file. - imported_scope = UncachedImport(scope->settings(), file, - node_for_err, err); - if (!imported_scope) - return false; - - // We loaded the file outside the lock. This means that there could be a - // race and the file was already loaded on a background thread. Recover - // from this and use the existing one if that happens. - { - base::AutoLock lock(lock_); - ImportMap::const_iterator found = imports_.find(file); - if (found != imports_.end()) { - delete imported_scope; - imported_scope = found->second; - } else { - imports_[file] = imported_scope; + // Now use the per-import-file lock to block this thread if another thread + // is already processing the import. + const Scope* import_scope = nullptr; + { + base::AutoLock lock(import_info->load_lock); + + if (!import_info->scope) { + // Only load if the import hasn't already failed. + if (!import_info->load_result.has_error()) { + import_info->scope = UncachedImport( + scope->settings(), file, node_for_err, &import_info->load_result); + } + if (import_info->load_result.has_error()) { + *err = import_info->load_result; + return false; } } + + // Promote the now-read-only scope to outside the load lock. + import_scope = import_info->scope.get(); } Scope::MergeOptions options; options.skip_private_vars = true; options.mark_dest_used = true; // Don't require all imported values be used. - return imported_scope->NonRecursiveMergeTo(scope, options, node_for_err, - "import", err); + return import_scope->NonRecursiveMergeTo(scope, options, node_for_err, + "import", err); +} + +std::vector<SourceFile> ImportManager::GetImportedFiles() const { + std::vector<SourceFile> imported_files; + imported_files.resize(imports_.size()); + std::transform(imports_.begin(), imports_.end(), imported_files.begin(), + [](const ImportMap::value_type& val) { return val.first; }); + return imported_files; } diff --git a/chromium/tools/gn/import_manager.h b/chromium/tools/gn/import_manager.h index 70aeee727c5..f371520df8c 100644 --- a/chromium/tools/gn/import_manager.h +++ b/chromium/tools/gn/import_manager.h @@ -6,6 +6,8 @@ #define TOOLS_GN_IMPORT_MANAGER_H_ #include <map> +#include <memory> +#include <vector> #include "base/macros.h" #include "base/synchronization/lock.h" @@ -29,11 +31,16 @@ class ImportManager { Scope* scope, Err* err); + std::vector<SourceFile> GetImportedFiles() const; + private: - base::Lock lock_; + struct ImportInfo; + + // Protects access to imports_. Do not hold when actually executing imports. + base::Lock imports_lock_; // Owning pointers to the scopes. - typedef std::map<SourceFile, const Scope*> ImportMap; + typedef std::map<SourceFile, std::unique_ptr<ImportInfo>> ImportMap; ImportMap imports_; DISALLOW_COPY_AND_ASSIGN(ImportManager); diff --git a/chromium/tools/gn/input_file_manager.cc b/chromium/tools/gn/input_file_manager.cc index a3e64606b0d..36c0bf3c264 100644 --- a/chromium/tools/gn/input_file_manager.cc +++ b/chromium/tools/gn/input_file_manager.cc @@ -94,9 +94,6 @@ InputFileManager::InputFileManager() { InputFileManager::~InputFileManager() { // Should be single-threaded by now. - STLDeleteContainerPairSecondPointers(input_files_.begin(), - input_files_.end()); - STLDeleteContainerPointers(dynamic_inputs_.begin(), dynamic_inputs_.end()); } bool InputFileManager::AsyncLoadFile(const LocationRange& origin, @@ -114,18 +111,18 @@ bool InputFileManager::AsyncLoadFile(const LocationRange& origin, InputFileMap::const_iterator found = input_files_.find(file_name); if (found == input_files_.end()) { // New file, schedule load. - InputFileData* data = new InputFileData(file_name); + std::unique_ptr<InputFileData> data(new InputFileData(file_name)); data->scheduled_callbacks.push_back(callback); - input_files_[file_name] = data; - schedule_this = base::Bind(&InputFileManager::BackgroundLoadFile, this, origin, build_settings, file_name, &data->file); + input_files_[file_name] = std::move(data); + } else { - InputFileData* data = found->second; + InputFileData* data = found->second.get(); // Prevent mixing async and sync loads. See SyncLoadFile for discussion. if (data->sync_invocation) { @@ -167,16 +164,17 @@ const ParseNode* InputFileManager::SyncLoadFile( InputFileMap::iterator found = input_files_.find(file_name); if (found == input_files_.end()) { // Haven't seen this file yet, start loading right now. - data = new InputFileData(file_name); + std::unique_ptr<InputFileData> new_data(new InputFileData(file_name)); + data = new_data.get(); data->sync_invocation = true; - input_files_[file_name] = data; + input_files_[file_name] = std::move(new_data); base::AutoUnlock unlock(lock_); if (!LoadFile(origin, build_settings, file_name, &data->file, err)) return nullptr; } else { // This file has either been loaded or is pending loading. - data = found->second; + data = found->second.get(); if (!data->sync_invocation) { // Don't allow mixing of sync and async loads. If an async load is @@ -231,14 +229,14 @@ void InputFileManager::AddDynamicInput( InputFile** file, std::vector<Token>** tokens, std::unique_ptr<ParseNode>** parse_root) { - InputFileData* data = new InputFileData(name); - { - base::AutoLock lock(lock_); - dynamic_inputs_.push_back(data); - } + std::unique_ptr<InputFileData> data(new InputFileData(name)); *file = &data->file; *tokens = &data->tokens; *parse_root = &data->parsed_root; + { + base::AutoLock lock(lock_); + dynamic_inputs_.push_back(std::move(data)); + } } int InputFileManager::GetInputFileCount() const { @@ -286,7 +284,7 @@ bool InputFileManager::LoadFile(const LocationRange& origin, base::AutoLock lock(lock_); DCHECK(input_files_.find(name) != input_files_.end()); - InputFileData* data = input_files_[name]; + InputFileData* data = input_files_[name].get(); data->loaded = true; if (success) { data->tokens.swap(tokens); diff --git a/chromium/tools/gn/input_file_manager.h b/chromium/tools/gn/input_file_manager.h index ba055e219c5..dd166048e9b 100644 --- a/chromium/tools/gn/input_file_manager.h +++ b/chromium/tools/gn/input_file_manager.h @@ -137,7 +137,8 @@ class InputFileManager : public base::RefCountedThreadSafe<InputFileManager> { mutable base::Lock lock_; // Maps repo-relative filenames to the corresponding owned pointer. - typedef base::hash_map<SourceFile, InputFileData*> InputFileMap; + typedef base::hash_map<SourceFile, std::unique_ptr<InputFileData>> + InputFileMap; InputFileMap input_files_; // Tracks all dynamic inputs. The data are holders for memory management @@ -146,9 +147,7 @@ class InputFileManager : public base::RefCountedThreadSafe<InputFileManager> { // charge of the threadsafety requirements. // // See AddDynamicInput(). - // - // Owning pointers. - std::vector<InputFileData*> dynamic_inputs_; + std::vector<std::unique_ptr<InputFileData>> dynamic_inputs_; DISALLOW_COPY_AND_ASSIGN(InputFileManager); }; diff --git a/chromium/tools/gn/loader.cc b/chromium/tools/gn/loader.cc index 9061be82a0b..e3165b9c6f7 100644 --- a/chromium/tools/gn/loader.cc +++ b/chromium/tools/gn/loader.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" -#include "base/stl_util.h" #include "tools/gn/build_settings.h" #include "tools/gn/err.h" #include "tools/gn/filesystem_utils.h" @@ -106,8 +105,6 @@ LoaderImpl::LoaderImpl(const BuildSettings* build_settings) } LoaderImpl::~LoaderImpl() { - STLDeleteContainerPairSecondPointers(toolchain_records_.begin(), - toolchain_records_.end()); } void LoaderImpl::Load(const SourceFile& file, @@ -120,13 +117,14 @@ void LoaderImpl::Load(const SourceFile& file, return; // Already in set, so this file was already loaded or schedulerd. if (toolchain_records_.empty()) { - // Nothing loaded, need to load the default build config. The intial load + // Nothing loaded, need to load the default build config. The initial load // should not specify a toolchain. DCHECK(toolchain_name.is_null()); - ToolchainRecord* record = - new ToolchainRecord(build_settings_, Label(), Label()); - toolchain_records_[Label()] = record; + std::unique_ptr<ToolchainRecord> new_record( + new ToolchainRecord(build_settings_, Label(), Label())); + ToolchainRecord* record = new_record.get(); + toolchain_records_[Label()] = std::move(new_record); // The default build config is no dependent on the toolchain definition, // since we need to load the build config before we know what the default @@ -135,22 +133,24 @@ void LoaderImpl::Load(const SourceFile& file, record->waiting_on_me.push_back(SourceFileAndOrigin(file, origin)); ScheduleLoadBuildConfig(&record->settings, Scope::KeyValueMap()); + return; } ToolchainRecord* record; if (toolchain_name.is_null()) - record = toolchain_records_[default_toolchain_label_]; + record = toolchain_records_[default_toolchain_label_].get(); else - record = toolchain_records_[toolchain_name]; + record = toolchain_records_[toolchain_name].get(); if (!record) { DCHECK(!default_toolchain_label_.is_null()); // No reference to this toolchain found yet, make one. - record = new ToolchainRecord(build_settings_, toolchain_name, - default_toolchain_label_); - toolchain_records_[toolchain_name] = record; + std::unique_ptr<ToolchainRecord> new_record(new ToolchainRecord( + build_settings_, toolchain_name, default_toolchain_label_)); + record = new_record.get(); + toolchain_records_[toolchain_name] = std::move(new_record); // Schedule a load of the toolchain using the default one. Load(BuildFileForLabel(toolchain_name), origin, default_toolchain_label_); @@ -163,12 +163,13 @@ void LoaderImpl::Load(const SourceFile& file, } void LoaderImpl::ToolchainLoaded(const Toolchain* toolchain) { - ToolchainRecord* record = toolchain_records_[toolchain->label()]; + ToolchainRecord* record = toolchain_records_[toolchain->label()].get(); if (!record) { DCHECK(!default_toolchain_label_.is_null()); - record = new ToolchainRecord(build_settings_, toolchain->label(), - default_toolchain_label_); - toolchain_records_[toolchain->label()] = record; + std::unique_ptr<ToolchainRecord> new_record(new ToolchainRecord( + build_settings_, toolchain->label(), default_toolchain_label_)); + record = new_record.get(); + toolchain_records_[toolchain->label()] = std::move(new_record); } record->is_toolchain_loaded = true; @@ -210,7 +211,7 @@ void LoaderImpl::ScheduleLoadFile(const Settings* settings, pending_loads_++; if (!AsyncLoadFile(origin, settings->build_settings(), file, base::Bind(&LoaderImpl::BackgroundLoadFile, this, - settings, file), + settings, file, origin), &err)) { g_scheduler->FailWithError(err); DecrementPendingLoads(); @@ -234,6 +235,7 @@ void LoaderImpl::ScheduleLoadBuildConfig( void LoaderImpl::BackgroundLoadFile(const Settings* settings, const SourceFile& file_name, + const LocationRange& origin, const ParseNode* root) { if (!root) { main_loop_->PostTask(FROM_HERE, @@ -259,11 +261,15 @@ void LoaderImpl::BackgroundLoadFile(const Settings* settings, Err err; root->Execute(&our_scope, &err); - if (err.has_error()) - g_scheduler->FailWithError(err); + if (!err.has_error()) + our_scope.CheckForUnusedVars(&err); - if (!our_scope.CheckForUnusedVars(&err)) + if (err.has_error()) { + if (!origin.is_null()) + err.AppendSubErr(Err(origin, "which caused the file to be included.")); g_scheduler->FailWithError(err); + } + // Pass all of the items that were defined off to the builder. for (auto& item : collected_items) { @@ -356,8 +362,10 @@ void LoaderImpl::DidLoadBuildConfig(const Label& label) { CHECK(empty_label != toolchain_records_.end()); // Fix up the toolchain record. - record = empty_label->second; - toolchain_records_[label] = record; + std::unique_ptr<ToolchainRecord> moved_record = + std::move(empty_label->second); + record = moved_record.get(); + toolchain_records_[label] = std::move(moved_record); toolchain_records_.erase(empty_label); // Save the default toolchain label. @@ -383,7 +391,7 @@ void LoaderImpl::DidLoadBuildConfig(const Label& label) { } } } else { - record = found_toolchain->second; + record = found_toolchain->second.get(); } DCHECK(!record->is_config_loaded); diff --git a/chromium/tools/gn/loader.h b/chromium/tools/gn/loader.h index 3d61fe4b4e8..a610835aa39 100644 --- a/chromium/tools/gn/loader.h +++ b/chromium/tools/gn/loader.h @@ -6,6 +6,7 @@ #define TOOLS_GN_LOADER_H_ #include <map> +#include <memory> #include <set> #include "base/callback.h" @@ -128,6 +129,7 @@ class LoaderImpl : public Loader { // input file manager. void BackgroundLoadFile(const Settings* settings, const SourceFile& file_name, + const LocationRange& origin, const ParseNode* root); void BackgroundLoadBuildConfig( Settings* settings, @@ -173,8 +175,7 @@ class LoaderImpl : public Loader { Label default_toolchain_label_; // Records for the build config file loads. - // Owning pointers. - typedef std::map<Label, ToolchainRecord*> ToolchainRecordMap; + typedef std::map<Label, std::unique_ptr<ToolchainRecord>> ToolchainRecordMap; ToolchainRecordMap toolchain_records_; }; diff --git a/chromium/tools/gn/location.h b/chromium/tools/gn/location.h index 44d1a6fe68f..647c6f71227 100644 --- a/chromium/tools/gn/location.h +++ b/chromium/tools/gn/location.h @@ -19,6 +19,7 @@ class Location { int line_number() const { return line_number_; } int column_number() const { return column_number_; } int byte() const { return byte_; } + bool is_null() const { return *this == Location(); } bool operator==(const Location& other) const; bool operator!=(const Location& other) const; @@ -45,6 +46,10 @@ class LocationRange { const Location& begin() const { return begin_; } const Location& end() const { return end_; } + bool is_null() const { + return begin_.is_null(); // No need to check both for the null case. + } + LocationRange Union(const LocationRange& other) const; diff --git a/chromium/tools/gn/misc/emacs/gn-mode.el b/chromium/tools/gn/misc/emacs/gn-mode.el index 66822907c67..435e872c9ad 100644 --- a/chromium/tools/gn/misc/emacs/gn-mode.el +++ b/chromium/tools/gn/misc/emacs/gn-mode.el @@ -36,6 +36,11 @@ :group 'gn :type 'integer) +(defcustom gn-format-command "gn format --stdin" + "The command to run to format gn files in place." + :group 'gn + :type 'string) + (defgroup gn-faces nil "Faces used in Generate Ninja mode." :group 'gn @@ -123,6 +128,20 @@ variable name or the '{{' and '}}' which surround it." ;; if we do. t)) +(defun gn-run-format () + "Run 'gn format' on the buffer in place." + (interactive) + ;; We can't `save-excursion' here; that will put us at the beginning of the + ;; shell output, aka the beginning of the document. + (let ((my-start-line (line-number-at-pos))) + (shell-command-on-region (point-min) (point-max) gn-format-command nil t) + (goto-line my-start-line))) + +(defvar gn-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "\C-c\C-f" 'gn-run-format) + map)) + ;;;###autoload (define-derived-mode gn-mode prog-mode "GN" "Major mode for editing gn (Generate Ninja)." diff --git a/chromium/tools/gn/ninja_binary_target_writer.cc b/chromium/tools/gn/ninja_binary_target_writer.cc index eaae098ef71..30658f21ed1 100644 --- a/chromium/tools/gn/ninja_binary_target_writer.cc +++ b/chromium/tools/gn/ninja_binary_target_writer.cc @@ -51,12 +51,6 @@ namespace { EscapeOptions GetFlagOptions() { EscapeOptions opts; opts.mode = ESCAPE_NINJA_COMMAND; - - // Some flag strings are actually multiple flags that expect to be just - // added to the command line. We assume that quoting is done by the - // buildfiles if it wants such things quoted. - opts.inhibit_quoting = true; - return opts; } @@ -109,14 +103,15 @@ const char* GetPCHLangSuffixForToolType(Toolchain::ToolType type) { } } -std::string GetWindowsPCHObjectExtension(Toolchain::ToolType tool_type) { +std::string GetWindowsPCHObjectExtension(Toolchain::ToolType tool_type, + const std::string& obj_extension) { const char* lang_suffix = GetPCHLangSuffixForToolType(tool_type); std::string result = "."; // For MSVC, annotate the obj files with the language type. For example: - // obj/foo/target_name.precompile.o -> - // obj/foo/target_name.precompile.cc.o + // obj/foo/target_name.precompile.obj -> + // obj/foo/target_name.precompile.cc.obj result += lang_suffix; - result += ".o"; + result += obj_extension; return result; } @@ -188,7 +183,8 @@ void GetPCHOutputFiles(const Target* target, Tool::PrecompiledHeaderType header_type = tool->precompiled_header_type(); switch (header_type) { case Tool::PCH_MSVC: - output_extension = GetWindowsPCHObjectExtension(tool_type); + output_extension = GetWindowsPCHObjectExtension( + tool_type, output_value.substr(extension_offset - 1)); break; case Tool::PCH_GCC: output_extension = GetGCCPCHOutputExtension(tool_type); @@ -627,7 +623,7 @@ void NinjaBinaryTargetWriter::WriteSources( if (tool_type != Toolchain::TYPE_NONE) { // Only include PCH deps that correspond to the tool type, for instance, - // do not specify target_name.precompile.cc.o (a CXX PCH file) as a dep + // do not specify target_name.precompile.cc.obj (a CXX PCH file) as a dep // for the output of a C tool type. // // This makes the assumption that pch_deps only contains pch output files @@ -637,9 +633,13 @@ void NinjaBinaryTargetWriter::WriteSources( if (tool->precompiled_header_type() != Tool::PCH_NONE) { for (const auto& dep : pch_deps) { const std::string& output_value = dep.value(); + size_t extension_offset = FindExtensionOffset(output_value); + if (extension_offset == std::string::npos) + continue; std::string output_extension; if (tool->precompiled_header_type() == Tool::PCH_MSVC) { - output_extension = GetWindowsPCHObjectExtension(tool_type); + output_extension = GetWindowsPCHObjectExtension( + tool_type, output_value.substr(extension_offset - 1)); } else if (tool->precompiled_header_type() == Tool::PCH_GCC) { output_extension = GetGCCPCHOutputExtension(tool_type); } @@ -785,8 +785,13 @@ void NinjaBinaryTargetWriter::WriteLinkerStuff( target_->output_type() == Target::LOADABLE_MODULE) { WriteLinkerFlags(optional_def_file); WriteLibs(); + } else if (target_->output_type() == Target::STATIC_LIBRARY) { + out_ << " arflags ="; + RecursiveTargetConfigStringsToStream(target_, &ConfigValues::arflags, + GetFlagOptions(), out_); + out_ << std::endl; } - WriteOutputExtension(); + WriteOutputSubstitutions(); WriteSolibs(solibs); } @@ -795,9 +800,8 @@ void NinjaBinaryTargetWriter::WriteLinkerFlags( out_ << " ldflags ="; // First the ldflags from the target and its config. - EscapeOptions flag_options = GetFlagOptions(); RecursiveTargetConfigStringsToStream(target_, &ConfigValues::ldflags, - flag_options, out_); + GetFlagOptions(), out_); // Followed by library search paths that have been recursively pushed // through the dependency tree. @@ -853,11 +857,15 @@ void NinjaBinaryTargetWriter::WriteLibs() { out_ << std::endl; } -void NinjaBinaryTargetWriter::WriteOutputExtension() { +void NinjaBinaryTargetWriter::WriteOutputSubstitutions() { out_ << " output_extension = " << SubstitutionWriter::GetLinkerSubstitution( target_, tool_, SUBSTITUTION_OUTPUT_EXTENSION); out_ << std::endl; + out_ << " output_dir = " + << SubstitutionWriter::GetLinkerSubstitution( + target_, tool_, SUBSTITUTION_OUTPUT_DIR); + out_ << std::endl; } void NinjaBinaryTargetWriter::WriteSolibs( @@ -930,7 +938,14 @@ void NinjaBinaryTargetWriter::ClassifyDependency( // don't link at all. bool can_link_libs = target_->IsFinal(); - if (dep->output_type() == Target::SOURCE_SET) { + if (dep->output_type() == Target::SOURCE_SET || + // If a complete static library depends on an incomplete static library, + // manually link in the object files of the dependent library as if it + // were a source set. This avoids problems with braindead tools such as + // ar which don't properly link dependent static libraries. + (target_->complete_static_lib() && + dep->output_type() == Target::STATIC_LIBRARY && + !dep->complete_static_lib())) { // Source sets have their object files linked into final targets // (shared libraries, executables, loadable modules, and complete static // libraries). Intermediate static libraries and other source sets @@ -946,6 +961,8 @@ void NinjaBinaryTargetWriter::ClassifyDependency( // can be complete. Otherwise, these will be skipped since this target // will depend only on the source set's object files. non_linkable_deps->push_back(dep); + } else if (target_->complete_static_lib() && dep->IsFinal()) { + non_linkable_deps->push_back(dep); } else if (can_link_libs && dep->IsLinkable()) { linkable_deps->push_back(dep); } else { diff --git a/chromium/tools/gn/ninja_binary_target_writer.h b/chromium/tools/gn/ninja_binary_target_writer.h index db2b15d12af..1876486ff1f 100644 --- a/chromium/tools/gn/ninja_binary_target_writer.h +++ b/chromium/tools/gn/ninja_binary_target_writer.h @@ -99,7 +99,7 @@ class NinjaBinaryTargetWriter : public NinjaTargetWriter { const std::vector<SourceFile>& other_files); void WriteLinkerFlags(const SourceFile* optional_def_file); void WriteLibs(); - void WriteOutputExtension(); + void WriteOutputSubstitutions(); void WriteSolibs(const std::vector<OutputFile>& solibs); // Writes the stamp line for a source set. These are not linked. diff --git a/chromium/tools/gn/ninja_binary_target_writer_unittest.cc b/chromium/tools/gn/ninja_binary_target_writer_unittest.cc index 1e02446dfe3..f2297fbf206 100644 --- a/chromium/tools/gn/ninja_binary_target_writer_unittest.cc +++ b/chromium/tools/gn/ninja_binary_target_writer_unittest.cc @@ -82,7 +82,8 @@ TEST(NinjaBinaryTargetWriter, SourceSet) { "|| obj/foo/bar.stamp\n" " ldflags =\n" " libs =\n" - " output_extension = .so\n"; + " output_extension = .so\n" + " output_dir = \n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -110,7 +111,9 @@ TEST(NinjaBinaryTargetWriter, SourceSet) { // There are no sources so there are no params to alink. (In practice // this will probably fail in the archive tool.) "build obj/foo/libstlib.a: alink || obj/foo/bar.stamp\n" - " output_extension = \n"; + " arflags =\n" + " output_extension = \n" + " output_dir = \n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -136,15 +139,124 @@ TEST(NinjaBinaryTargetWriter, SourceSet) { "build obj/foo/libstlib.a: alink obj/foo/bar.input1.o " "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj " "|| obj/foo/bar.stamp\n" - " output_extension = \n"; + " arflags =\n" + " output_extension = \n" + " output_dir = \n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } } -// This tests that output extension overrides apply, and input dependencies -// are applied. -TEST(NinjaBinaryTargetWriter, ProductExtensionAndInputDeps) { +TEST(NinjaBinaryTargetWriter, StaticLibrary) { + TestWithScope setup; + Err err; + + TestTarget target(setup, "//foo:bar", Target::STATIC_LIBRARY); + target.sources().push_back(SourceFile("//foo/input1.cc")); + target.config_values().arflags().push_back("--asdf"); + ASSERT_TRUE(target.OnResolved(&err)); + + std::ostringstream out; + NinjaBinaryTargetWriter writer(&target, out); + writer.Run(); + + const char expected[] = + "defines =\n" + "include_dirs =\n" + "cflags =\n" + "cflags_cc =\n" + "root_out_dir = .\n" + "target_out_dir = obj/foo\n" + "target_output_name = libbar\n" + "\n" + "build obj/foo/libbar.input1.o: cxx ../../foo/input1.cc\n" + "\n" + "build obj/foo/libbar.a: alink obj/foo/libbar.input1.o\n" + " arflags = --asdf\n" + " output_extension = \n" + " output_dir = \n"; + std::string out_str = out.str(); + EXPECT_EQ(expected, out_str); +} + +TEST(NinjaBinaryTargetWriter, CompleteStaticLibrary) { + TestWithScope setup; + Err err; + + TestTarget target(setup, "//foo:bar", Target::STATIC_LIBRARY); + target.sources().push_back(SourceFile("//foo/input1.cc")); + target.config_values().arflags().push_back("--asdf"); + target.set_complete_static_lib(true); + + TestTarget baz(setup, "//foo:baz", Target::STATIC_LIBRARY); + baz.sources().push_back(SourceFile("//foo/input2.cc")); + + target.public_deps().push_back(LabelTargetPair(&baz)); + + ASSERT_TRUE(target.OnResolved(&err)); + ASSERT_TRUE(baz.OnResolved(&err)); + + // A complete static library that depends on an incomplete static library + // should link in the dependent object files as if the dependent target + // were a source set. + { + std::ostringstream out; + NinjaBinaryTargetWriter writer(&target, out); + writer.Run(); + + const char expected[] = + "defines =\n" + "include_dirs =\n" + "cflags =\n" + "cflags_cc =\n" + "root_out_dir = .\n" + "target_out_dir = obj/foo\n" + "target_output_name = libbar\n" + "\n" + "build obj/foo/libbar.input1.o: cxx ../../foo/input1.cc\n" + "\n" + "build obj/foo/libbar.a: alink obj/foo/libbar.input1.o " + "obj/foo/libbaz.input2.o || obj/foo/libbaz.a\n" + " arflags = --asdf\n" + " output_extension = \n" + " output_dir = \n"; + std::string out_str = out.str(); + EXPECT_EQ(expected, out_str); + } + + // Make the dependent static library complete. + baz.set_complete_static_lib(true); + + // Dependent complete static libraries should not be linked directly. + { + std::ostringstream out; + NinjaBinaryTargetWriter writer(&target, out); + writer.Run(); + + const char expected[] = + "defines =\n" + "include_dirs =\n" + "cflags =\n" + "cflags_cc =\n" + "root_out_dir = .\n" + "target_out_dir = obj/foo\n" + "target_output_name = libbar\n" + "\n" + "build obj/foo/libbar.input1.o: cxx ../../foo/input1.cc\n" + "\n" + "build obj/foo/libbar.a: alink obj/foo/libbar.input1.o " + "|| obj/foo/libbaz.a\n" + " arflags = --asdf\n" + " output_extension = \n" + " output_dir = \n"; + std::string out_str = out.str(); + EXPECT_EQ(expected, out_str); + } +} + +// This tests that output extension and output dir overrides apply, and input +// dependencies are applied. +TEST(NinjaBinaryTargetWriter, OutputExtensionAndInputDeps) { TestWithScope setup; Err err; @@ -157,10 +269,11 @@ TEST(NinjaBinaryTargetWriter, ProductExtensionAndInputDeps) { action.SetToolchain(setup.toolchain()); ASSERT_TRUE(action.OnResolved(&err)); - // A shared library w/ the product_extension set to a custom value. + // A shared library w/ the output_extension set to a custom value. Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib")); target.set_output_type(Target::SHARED_LIBRARY); target.set_output_extension(std::string("so.6")); + target.set_output_dir(SourceDir("//out/Debug/foo/")); target.sources().push_back(SourceFile("//foo/input1.cc")); target.sources().push_back(SourceFile("//foo/input2.cc")); target.public_deps().push_back(LabelTargetPair(&action)); @@ -192,7 +305,8 @@ TEST(NinjaBinaryTargetWriter, ProductExtensionAndInputDeps) { "obj/foo/libshlib.input2.o || obj/foo/action.stamp\n" " ldflags =\n" " libs =\n" - " output_extension = .so.6\n"; + " output_extension = .so.6\n" + " output_dir = foo\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); @@ -229,19 +343,20 @@ TEST(NinjaBinaryTargetWriter, LibsAndLibDirs) { "build ./libshlib.so: solink | ../../foo/lib1.a\n" " ldflags = -L../../foo/bar\n" " libs = ../../foo/lib1.a -lfoo\n" - " output_extension = .so\n"; + " output_extension = .so\n" + " output_dir = \n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } -TEST(NinjaBinaryTargetWriter, EmptyProductExtension) { +TEST(NinjaBinaryTargetWriter, EmptyOutputExtension) { TestWithScope setup; Err err; setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); - // This test is the same as ProductExtension, except that we call + // This test is the same as OutputExtensionAndInputDeps, except that we call // set_output_extension("") and ensure that we get an empty one and override // the output prefix so that the name matches the target exactly. Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib")); @@ -274,7 +389,8 @@ TEST(NinjaBinaryTargetWriter, EmptyProductExtension) { "obj/foo/shlib.input2.o\n" " ldflags =\n" " libs =\n" - " output_extension = \n"; + " output_extension = \n" + " output_dir = \n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); @@ -357,7 +473,8 @@ TEST(NinjaBinaryTargetWriter, SourceSetDataDeps) { "obj/foo/inter.stamp\n" " ldflags =\n" " libs =\n" - " output_extension = \n"; + " output_extension = \n" + " output_dir = \n"; EXPECT_EQ(final_expected, final_out.str()); } @@ -392,7 +509,8 @@ TEST(NinjaBinaryTargetWriter, SharedLibraryModuleDefinitionFile) { "build ./libbar.so: solink obj/foo/libbar.sources.o | ../../foo/bar.def\n" " ldflags = /DEF:../../foo/bar.def\n" " libs =\n" - " output_extension = .so\n"; + " output_extension = .so\n" + " output_dir = \n"; EXPECT_EQ(expected, out.str()); } @@ -427,7 +545,8 @@ TEST(NinjaBinaryTargetWriter, LoadableModule) { "build ./libbar.so: solink_module obj/foo/libbar.sources.o\n" " ldflags =\n" " libs =\n" - " output_extension = .so\n"; + " output_extension = .so\n" + " output_dir = \n"; EXPECT_EQ(loadable_expected, out.str()); // Final target. @@ -458,7 +577,8 @@ TEST(NinjaBinaryTargetWriter, LoadableModule) { "build ./exe: link obj/foo/exe.final.o || ./libbar.so\n" " ldflags =\n" " libs =\n" - " output_extension = \n"; + " output_extension = \n" + " output_dir = \n"; EXPECT_EQ(final_expected, final_out.str()); } diff --git a/chromium/tools/gn/ninja_build_writer.cc b/chromium/tools/gn/ninja_build_writer.cc index d28969084ee..2cbb245c0dd 100644 --- a/chromium/tools/gn/ninja_build_writer.cc +++ b/chromium/tools/gn/ninja_build_writer.cc @@ -8,6 +8,7 @@ #include <fstream> #include <map> +#include <sstream> #include "base/command_line.h" #include "base/files/file_util.h" @@ -33,6 +34,16 @@ namespace { +struct Counts { + Counts() : count(0), last_seen(nullptr) {} + + // Number of targets of this type. + int count; + + // The last one we encountered. + const Target* last_seen; +}; + std::string GetSelfInvocationCommand(const BuildSettings* build_settings) { base::FilePath executable; PathService::Get(base::FILE_EXE, &executable); @@ -79,35 +90,6 @@ std::string GetSelfInvocationCommand(const BuildSettings* build_settings) { #endif } -OutputFile GetTargetOutputFile(const Target* target) { - OutputFile result(target->dependency_output_file()); - - // The output files may have leading "./" so normalize those away. - NormalizePath(&result.value()); - return result; -} - -bool HasOutputIdenticalToLabel(const Target* target, - const std::string& short_name) { - if (target->output_type() != Target::ACTION && - target->output_type() != Target::ACTION_FOREACH) - return false; - - // Rather than convert all outputs to be relative to the build directory - // and then compare to the short name, convert the short name to look like a - // file in the output directory since this is only one conversion. - SourceFile short_name_as_source_file( - target->settings()->build_settings()->build_dir().value() + short_name); - - std::vector<SourceFile> outputs_as_source; - target->action_values().GetOutputsAsSourceFiles(target, &outputs_as_source); - for (const SourceFile& output_as_source : outputs_as_source) { - if (output_as_source == short_name_as_source_file) - return true; - } - return false; -} - // Given an output that appears more than once, generates an error message // that describes the problem and which targets generate it. Err GetDuplicateOutputError(const std::vector<const Target*>& all_targets, @@ -178,29 +160,36 @@ bool NinjaBuildWriter::RunAndWriteFile( Err* err) { ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, "build.ninja"); - base::FilePath ninja_file(build_settings->GetFullPath( - SourceFile(build_settings->build_dir().value() + "build.ninja"))); - base::CreateDirectory(ninja_file.DirName()); + std::stringstream file; + std::stringstream depfile; + NinjaBuildWriter gen(build_settings, all_settings, default_toolchain, + default_toolchain_targets, file, depfile); + if (!gen.Run(err)) + return false; - std::ofstream file; - file.open(FilePathToUTF8(ninja_file).c_str(), - std::ios_base::out | std::ios_base::binary); - if (file.fail()) { - *err = Err(Location(), "Couldn't open build.ninja for writing"); + // Unconditionally write the build.ninja. Ninja's build-out-of-date checking + // will re-run GN when any build input is newer than build.ninja, so any time + // the build is updated, build.ninja's timestamp needs to updated also, even + // if the contents haven't been changed. + base::FilePath ninja_file_name(build_settings->GetFullPath( + SourceFile(build_settings->build_dir().value() + "build.ninja"))); + base::CreateDirectory(ninja_file_name.DirName()); + std::string ninja_contents = file.str(); + if (base::WriteFile(ninja_file_name, ninja_contents.data(), + static_cast<int>(ninja_contents.size())) != + static_cast<int>(ninja_contents.size())) return false; - } - std::ofstream depfile; - depfile.open((FilePathToUTF8(ninja_file) + ".d").c_str(), - std::ios_base::out | std::ios_base::binary); - if (depfile.fail()) { - *err = Err(Location(), "Couldn't open depfile for writing"); + // Dep file listing build dependencies. + base::FilePath dep_file_name(build_settings->GetFullPath( + SourceFile(build_settings->build_dir().value() + "build.ninja.d"))); + std::string dep_contents = depfile.str(); + if (base::WriteFile(dep_file_name, dep_contents.data(), + static_cast<int>(dep_contents.size())) != + static_cast<int>(dep_contents.size())) return false; - } - NinjaBuildWriter gen(build_settings, all_settings, default_toolchain, - default_toolchain_targets, file, depfile); - return gen.Run(err); + return true; } void NinjaBuildWriter::WriteNinjaRules() { @@ -251,149 +240,166 @@ void NinjaBuildWriter::WriteSubninjas() { } bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) { - std::string all_rules; - // Track rules as we generate them so we don't accidentally write a phony // rule that collides with something else. // GN internally generates an "all" target, so don't duplicate it. - std::set<std::string> written_rules; + base::hash_set<std::string> written_rules; written_rules.insert("all"); - // Write phony rules for all uniquely-named targets in the default toolchain. - // Don't do other toolchains or we'll get naming conflicts, and if the name - // isn't unique, also skip it. The exception is for the toplevel targets - // which we also find. - std::map<std::string, int> small_name_count; - std::map<std::string, int> exe_count; + // Set if we encounter a target named "//:default". + bool default_target_exists = false; + + // Targets in the root build file. std::vector<const Target*> toplevel_targets; - base::hash_set<std::string> target_files; - for (const auto& target : default_toolchain_targets_) { + + // Targets with names matching their toplevel directories. For example + // "//foo:foo". Expect this is the naming scheme for "big components." + std::vector<const Target*> toplevel_dir_targets; + + // Tracks the number of each target with the given short name, as well + // as the short names of executables (which will be a subset of short_names). + std::map<std::string, Counts> short_names; + std::map<std::string, Counts> exes; + + for (const Target* target : default_toolchain_targets_) { const Label& label = target->label(); - small_name_count[label.name()]++; + const std::string& short_name = label.name(); + + if (label.dir().value() == "//" && label.name() == "default") + default_target_exists = true; + + // Count the number of targets with the given short name. + Counts& short_names_counts = short_names[short_name]; + short_names_counts.count++; + short_names_counts.last_seen = target; + + // Count executables with the given short name. + if (target->output_type() == Target::EXECUTABLE) { + Counts& exes_counts = exes[short_name]; + exes_counts.count++; + exes_counts.last_seen = target; + } - // Look for targets with a name of the form - // dir = "//foo/", name = "foo" - // i.e. where the target name matches the top level directory. We will - // always write phony rules for these even if there is another target with - // the same short name. + // Find targets in "important" directories. const std::string& dir_string = label.dir().value(); - if (dir_string.size() == label.name().size() + 3 && // Size matches. + if (dir_string.size() == 2 && + dir_string[0] == '/' && dir_string[1] == '/') { + toplevel_targets.push_back(target); + } else if ( + dir_string.size() == label.name().size() + 3 && // Size matches. dir_string[0] == '/' && dir_string[1] == '/' && // "//" at beginning. dir_string[dir_string.size() - 1] == '/' && // "/" at end. - dir_string.compare(2, label.name().size(), label.name()) == 0) - toplevel_targets.push_back(target); - - // Look for executables; later we will generate phony rules for them - // even if there are non-executable targets with the same name. - if (target->output_type() == Target::EXECUTABLE) - exe_count[label.name()]++; - - // Add the files to the list of generated targets so we don't write phony - // rules that collide. - std::string target_file(target->dependency_output_file().value()); - NormalizePath(&target_file); - written_rules.insert(target_file); - } + dir_string.compare(2, label.name().size(), label.name()) == 0) { + toplevel_dir_targets.push_back(target); + } - for (const auto& target : default_toolchain_targets_) { - const Label& label = target->label(); + // Add the output files from each target to the written rules so that + // we don't write phony rules that collide with anything generated by the + // build. + // + // If at this point there is a collision (no phony rules have been + // generated yet), two targets make the same output so throw an error. for (const auto& output : target->computed_outputs()) { - if (!target_files.insert(output.value()).second) { + // Need to normalize because many toolchain outputs will be preceeded + // with "./". + std::string output_string(output.value()); + NormalizePath(&output_string); + if (!written_rules.insert(output_string).second) { *err = GetDuplicateOutputError(default_toolchain_targets_, output); return false; } } + } + + // First prefer the short names of toplevel targets. + for (const Target* target : toplevel_targets) { + if (written_rules.insert(target->label().name()).second) + WritePhonyRule(target, target->label().name()); + } + + // Next prefer short names of toplevel dir targets. + for (const Target* target : toplevel_dir_targets) { + if (written_rules.insert(target->label().name()).second) + WritePhonyRule(target, target->label().name()); + } + + // Write out the names labels of executables. Many toolchains will produce + // executables in the root build directory with no extensions, so the names + // will already exist and this will be a no-op. But on Windows such programs + // will have extensions, and executables may override the output directory to + // go into some other place. + // + // Putting this after the "toplevel" rules above also means that you can + // steal the short name from an executable by outputting the executable to + // a different directory or using a different output name, and writing a + // toplevel build rule. + for (const auto& pair : exes) { + const Counts& counts = pair.second; + const std::string& short_name = counts.last_seen->label().name(); + if (counts.count == 1 && written_rules.insert(short_name).second) + WritePhonyRule(counts.last_seen, short_name); + } + + // Write short names when those names are unique and not already taken. + for (const auto& pair : short_names) { + const Counts& counts = pair.second; + const std::string& short_name = counts.last_seen->label().name(); + if (counts.count == 1 && written_rules.insert(short_name).second) + WritePhonyRule(counts.last_seen, short_name); + } + + // Write the label variants of the target name. + for (const Target* target : default_toolchain_targets_) { + const Label& label = target->label(); - OutputFile target_file = GetTargetOutputFile(target); // Write the long name "foo/bar:baz" for the target "//foo/bar:baz". std::string long_name = label.GetUserVisibleName(false); base::TrimString(long_name, "/", &long_name); - WritePhonyRule(target, target_file, long_name, &written_rules); + if (written_rules.insert(long_name).second) + WritePhonyRule(target, long_name); // Write the directory name with no target name if they match // (e.g. "//foo/bar:bar" -> "foo/bar"). if (FindLastDirComponent(label.dir()) == label.name()) { - std::string medium_name = DirectoryWithNoLastSlash(label.dir()); + std::string medium_name = DirectoryWithNoLastSlash(label.dir()); base::TrimString(medium_name, "/", &medium_name); // That may have generated a name the same as the short name of the // target which we already wrote. - if (medium_name != label.name()) - WritePhonyRule(target, target_file, medium_name, &written_rules); - } - - // Write short names for ones which are either completely unique or there - // at least only one of them in the default toolchain that is an exe. - if (small_name_count[label.name()] == 1 || - (target->output_type() == Target::EXECUTABLE && - exe_count[label.name()] == 1)) { - // It's reasonable to generate output files in the root build directory - // with the same name as the target. Don't generate phony rules for - // these cases. - // - // All of this does not do the general checking of all target's outputs - // which may theoretically collide. But it's not very reasonable for - // a script target named "foo" to generate a file named "bar" with no - // extension in the root build directory while another target is named - // "bar". If this does occur, the user is likely to be confused when - // building "bar" that is builds foo anyway, so you probably just - // shouldn't do that. - // - // We should fix this however, and build up all generated script outputs - // and check everything against that. There are other edge cases that the - // current phony rule generator doesn't check. We may need to make a big - // set of every possible generated file in the build for this purpose. - if (!HasOutputIdenticalToLabel(target, label.name())) - WritePhonyRule(target, target_file, label.name(), &written_rules); + if (medium_name != label.name() && + written_rules.insert(medium_name).second) + WritePhonyRule(target, medium_name); } - if (!all_rules.empty()) - all_rules.append(" $\n "); - all_rules.append(target_file.value()); - } - - // Pick up phony rules for the toplevel targets with non-unique names (which - // would have been skipped in the above loop). - for (const auto& toplevel_target : toplevel_targets) { - if (small_name_count[toplevel_target->label().name()] > 1) { - WritePhonyRule(toplevel_target, toplevel_target->dependency_output_file(), - toplevel_target->label().name(), &written_rules); - } + // Write the short name if no other target shares that short name and + // non of the higher-priority rules above claimed it. + if (short_names[label.name()].count == 1 && + written_rules.insert(label.name()).second) + WritePhonyRule(target, label.name()); } - // Figure out if the BUILD file wants to declare a custom "default" - // target (rather than building 'all' by default). By convention - // we use group("default") but it doesn't have to be a group. - bool default_target_exists = false; - for (const auto& target : default_toolchain_targets_) { - const Label& label = target->label(); - if (label.dir().value() == "//" && label.name() == "default") - default_target_exists = true; - } + // Write the autogenerated "all" rule. + if (!default_toolchain_targets_.empty()) { + out_ << "\nbuild all: phony"; - if (!all_rules.empty()) { - out_ << "\nbuild all: phony " << all_rules << std::endl; + EscapeOptions ninja_escape; + ninja_escape.mode = ESCAPE_NINJA; + for (const Target* target : default_toolchain_targets_) { + out_ << " $\n "; + path_output_.WriteFile(out_, target->dependency_output_file()); + } } + out_ << std::endl; - if (default_target_exists) { - out_ << "default default" << std::endl; - } else if (!all_rules.empty()) { - out_ << "default all" << std::endl; - } + if (default_target_exists) + out_ << "\ndefault default" << std::endl; + else if (!default_toolchain_targets_.empty()) + out_ << "\ndefault all" << std::endl; return true; } void NinjaBuildWriter::WritePhonyRule(const Target* target, - const OutputFile& target_file, - const std::string& phony_name, - std::set<std::string>* written_rules) { - if (target_file.value() == phony_name) - return; // No need for a phony rule. - - if (written_rules->find(phony_name) != written_rules->end()) - return; // Already exists. - written_rules->insert(phony_name); - + const std::string& phony_name) { EscapeOptions ninja_escape; ninja_escape.mode = ESCAPE_NINJA; @@ -401,6 +407,6 @@ void NinjaBuildWriter::WritePhonyRule(const Target* target, std::string escaped = EscapeString(phony_name, ninja_escape, nullptr); out_ << "build " << escaped << ": phony "; - path_output_.WriteFile(out_, target_file); + path_output_.WriteFile(out_, target->dependency_output_file()); out_ << std::endl; } diff --git a/chromium/tools/gn/ninja_build_writer.h b/chromium/tools/gn/ninja_build_writer.h index 0d5b40eef70..e94f93de24e 100644 --- a/chromium/tools/gn/ninja_build_writer.h +++ b/chromium/tools/gn/ninja_build_writer.h @@ -46,12 +46,7 @@ class NinjaBuildWriter { void WriteSubninjas(); bool WritePhonyAndAllRules(Err* err); - // Writes a phony rule for the given target with the given name. Adds the new - // name to the given set. If the name is already in the set, does nothing. - void WritePhonyRule(const Target* target, - const OutputFile& target_file, - const std::string& phony_name, - std::set<std::string>* written_rules); + void WritePhonyRule(const Target* target, const std::string& phony_name); const BuildSettings* build_settings_; std::vector<const Settings*> all_settings_; diff --git a/chromium/tools/gn/ninja_build_writer_unittest.cc b/chromium/tools/gn/ninja_build_writer_unittest.cc index f82dc835521..48d73028e17 100644 --- a/chromium/tools/gn/ninja_build_writer_unittest.cc +++ b/chromium/tools/gn/ninja_build_writer_unittest.cc @@ -53,13 +53,15 @@ TEST(NinjaBuildWriter, TwoTargets) { "subninja toolchain.ninja\n" "\n"; const char expected_targets[] = + "build bar: phony obj/bar/bar.stamp\n" "build foo$:bar: phony obj/foo/bar.stamp\n" "build bar$:bar: phony obj/bar/bar.stamp\n" - "build bar: phony obj/bar/bar.stamp\n" "\n"; const char expected_root_target[] = - "build all: phony obj/foo/bar.stamp $\n" + "build all: phony $\n" + " obj/foo/bar.stamp $\n" " obj/bar/bar.stamp\n" + "\n" "default all\n"; std::string out_str = ninja_out.str(); #define EXPECT_SNIPPET(expected) \ diff --git a/chromium/tools/gn/ninja_create_bundle_target_writer.cc b/chromium/tools/gn/ninja_create_bundle_target_writer.cc index d85f2401ae5..84da2ff2d4b 100644 --- a/chromium/tools/gn/ninja_create_bundle_target_writer.cc +++ b/chromium/tools/gn/ninja_create_bundle_target_writer.cc @@ -116,4 +116,15 @@ void NinjaCreateBundleTargetWriter::Run() { for (const auto& pair : target_->data_deps()) order_only_deps.push_back(pair.ptr->dependency_output_file()); WriteStampForTarget(output_files, order_only_deps); + + // Write a phony target for the outer bundle directory. This allows other + // targets to treat the entire bundle as a single unit, even though it is + // a directory, so that it can be depended upon as a discrete build edge. + out_ << "build "; + path_output_.WriteFile( + out_, + OutputFile(settings_->build_settings(), + target_->bundle_data().GetBundleRootDirOutput(settings_))); + out_ << ": phony " << target_->dependency_output_file().value(); + out_ << std::endl; } diff --git a/chromium/tools/gn/ninja_create_bundle_target_writer_unittest.cc b/chromium/tools/gn/ninja_create_bundle_target_writer_unittest.cc index 88e6fbab34d..d35b519adc2 100644 --- a/chromium/tools/gn/ninja_create_bundle_target_writer_unittest.cc +++ b/chromium/tools/gn/ninja_create_bundle_target_writer_unittest.cc @@ -14,10 +14,11 @@ namespace { void SetupBundleDataDir(BundleData* bundle_data, const std::string& root_dir) { - bundle_data->root_dir().assign(root_dir + "/bar.bundle"); - bundle_data->resources_dir().assign(bundle_data->root_dir() + "/Resources"); - bundle_data->executable_dir().assign(bundle_data->root_dir() + "/Executable"); - bundle_data->plugins_dir().assign(bundle_data->root_dir() + "/PlugIns"); + std::string bundle_root_dir = root_dir + "/bar.bundle"; + bundle_data->root_dir() = SourceDir(bundle_root_dir); + bundle_data->resources_dir() = SourceDir(bundle_root_dir + "/Resources"); + bundle_data->executable_dir() = SourceDir(bundle_root_dir + "/Executable"); + bundle_data->plugins_dir() = SourceDir(bundle_root_dir + "/PlugIns"); } } // namespace @@ -55,7 +56,8 @@ TEST(NinjaCreateBundleTargetWriter, Run) { "\n" "build obj/baz/bar.stamp: stamp " "bar.bundle/Resources/input1.txt " - "bar.bundle/Resources/input2.txt\n"; + "bar.bundle/Resources/input2.txt\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -97,7 +99,53 @@ TEST(NinjaCreateBundleTargetWriter, AssetCatalog) { "../../foo/Foo.xcassets/foo.imageset/FooIcon-29@2x.png " "../../foo/Foo.xcassets/foo.imageset/FooIcon-29@3x.png\n" "\n" - "build obj/baz/bar.stamp: stamp bar.bundle/Resources/Assets.car\n"; + "build obj/baz/bar.stamp: stamp bar.bundle/Resources/Assets.car\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; + std::string out_str = out.str(); + EXPECT_EQ(expected, out_str); +} + +// Tests that the phony target for the top-level bundle directory is generated +// correctly. +TEST(NinjaCreateBundleTargetWriter, BundleRootDirOutput) { + TestWithScope setup; + Err err; + + setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); + Target target(setup.settings(), Label(SourceDir("//baz/"), "bar")); + target.set_output_type(Target::CREATE_BUNDLE); + + const std::string bundle_root_dir("//out/Debug/bar.bundle/Contents"); + target.bundle_data().root_dir() = SourceDir(bundle_root_dir); + target.bundle_data().resources_dir() = + SourceDir(bundle_root_dir + "/Resources"); + target.bundle_data().executable_dir() = SourceDir(bundle_root_dir + "/MacOS"); + target.bundle_data().plugins_dir() = SourceDir(bundle_root_dir + "/Plug Ins"); + + std::vector<SourceFile> sources; + sources.push_back(SourceFile("//foo/input1.txt")); + sources.push_back(SourceFile("//foo/input2.txt")); + target.bundle_data().file_rules().push_back(BundleFileRule( + sources, SubstitutionPattern::MakeForTest( + "{{bundle_resources_dir}}/{{source_file_part}}"))); + + target.SetToolchain(setup.toolchain()); + ASSERT_TRUE(target.OnResolved(&err)); + + std::ostringstream out; + NinjaCreateBundleTargetWriter writer(&target, out); + writer.Run(); + + const char expected[] = + "build bar.bundle/Contents/Resources/input1.txt: copy_bundle_data " + "../../foo/input1.txt\n" + "build bar.bundle/Contents/Resources/input2.txt: copy_bundle_data " + "../../foo/input2.txt\n" + "\n" + "build obj/baz/bar.stamp: stamp " + "bar.bundle/Contents/Resources/input1.txt " + "bar.bundle/Contents/Resources/input2.txt\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } @@ -167,7 +215,8 @@ TEST(NinjaCreateBundleTargetWriter, OrderOnlyDeps) { "bar.bundle/Resources/input1.txt " "bar.bundle/Resources/input2.txt " "bar.bundle/Info.plist " - "bar.bundle/Resources/Assets.car\n"; + "bar.bundle/Resources/Assets.car\n" + "build bar.bundle: phony obj/baz/bar.stamp\n"; std::string out_str = out.str(); EXPECT_EQ(expected, out_str); } diff --git a/chromium/tools/gn/parse_tree.cc b/chromium/tools/gn/parse_tree.cc index 167531c93fe..dc80514639a 100644 --- a/chromium/tools/gn/parse_tree.cc +++ b/chromium/tools/gn/parse_tree.cc @@ -297,7 +297,6 @@ BlockNode::BlockNode() { } BlockNode::~BlockNode() { - STLDeleteContainerPointers(statements_.begin(), statements_.end()); } const BlockNode* BlockNode::AsBlock() const { @@ -307,7 +306,7 @@ const BlockNode* BlockNode::AsBlock() const { Value BlockNode::Execute(Scope* scope, Err* err) const { for (size_t i = 0; i < statements_.size() && !err->has_error(); i++) { // Check for trying to execute things with no side effects in a block. - const ParseNode* cur = statements_[i]; + const ParseNode* cur = statements_[i].get(); if (cur->AsList() || cur->AsLiteral() || cur->AsUnaryOp() || cur->AsIdentifier()) { *err = cur->MakeErrorDescribing( @@ -492,7 +491,6 @@ ListNode::ListNode() : prefer_multiline_(false) { } ListNode::~ListNode() { - STLDeleteContainerPointers(contents_.begin(), contents_.end()); } const ListNode* ListNode::AsList() const { @@ -547,7 +545,7 @@ void ListNode::SortList(Comparator comparator) { bool skip = false; for (size_t i = sr.begin; i != sr.end; ++i) { // Bails out if any of the nodes are unsupported. - const ParseNode* node = contents_[i]; + const ParseNode* node = contents_[i].get(); if (!node->AsLiteral() && !node->AsIdentifier() && !node->AsAccessor()) { skip = true; continue; @@ -561,15 +559,19 @@ void ListNode::SortList(Comparator comparator) { // to determine whether two nodes were initially separated by a blank line // or not. int start_line = contents_[sr.begin]->GetRange().begin().line_number(); - const ParseNode* original_first = contents_[sr.begin]; + const ParseNode* original_first = contents_[sr.begin].get(); std::sort(contents_.begin() + sr.begin, contents_.begin() + sr.end, - comparator); + [&comparator](const std::unique_ptr<const ParseNode>& a, + const std::unique_ptr<const ParseNode>& b) { + return comparator(a.get(), b.get()); + }); // If the beginning of the range had before comments, and the first node // moved during the sort, then move its comments to the new head of the // range. - if (original_first->comments() && contents_[sr.begin] != original_first) { + if (original_first->comments() && + contents_[sr.begin].get() != original_first) { for (const auto& hc : original_first->comments()->before()) { - const_cast<ParseNode*>(contents_[sr.begin]) + const_cast<ParseNode*>(contents_[sr.begin].get()) ->comments_mutable() ->append_before(hc); } @@ -579,7 +581,7 @@ void ListNode::SortList(Comparator comparator) { } const ParseNode* prev = nullptr; for (size_t i = sr.begin; i != sr.end; ++i) { - const ParseNode* node = contents_[i]; + const ParseNode* node = contents_[i].get(); DCHECK(node->AsLiteral() || node->AsIdentifier() || node->AsAccessor()); int line_number = prev ? prev->GetRange().end().line_number() + 1 : start_line; @@ -627,8 +629,8 @@ std::vector<ListNode::SortRange> ListNode::GetSortRanges() const { std::vector<SortRange> ranges; const ParseNode* prev = nullptr; size_t begin = 0; - for (size_t i = begin; i < contents_.size(); prev = contents_[i++]) { - if (IsSortRangeSeparator(contents_[i], prev)) { + for (size_t i = begin; i < contents_.size(); prev = contents_[i++].get()) { + if (IsSortRangeSeparator(contents_[i].get(), prev)) { if (i > begin) { ranges.push_back(SortRange(begin, i)); // If |i| is an item with an attached comment, then we start the next diff --git a/chromium/tools/gn/parse_tree.h b/chromium/tools/gn/parse_tree.h index 28537992068..48313bea7f2 100644 --- a/chromium/tools/gn/parse_tree.h +++ b/chromium/tools/gn/parse_tree.h @@ -227,9 +227,11 @@ class BlockNode : public ParseNode { void set_end(std::unique_ptr<EndNode> e) { end_ = std::move(e); } const EndNode* End() const { return end_.get(); } - const std::vector<ParseNode*>& statements() const { return statements_; } + const std::vector<std::unique_ptr<ParseNode>>& statements() const { + return statements_; + } void append_statement(std::unique_ptr<ParseNode> s) { - statements_.push_back(s.release()); + statements_.push_back(std::move(s)); } private: @@ -238,8 +240,7 @@ class BlockNode : public ParseNode { Token begin_token_; std::unique_ptr<EndNode> end_; - // Owning pointers, use unique_ptr when we can use C++11. - std::vector<ParseNode*> statements_; + std::vector<std::unique_ptr<ParseNode>> statements_; DISALLOW_COPY_AND_ASSIGN(BlockNode); }; @@ -364,9 +365,11 @@ class ListNode : public ParseNode { const EndNode* End() const { return end_.get(); } void append_item(std::unique_ptr<ParseNode> s) { - contents_.push_back(s.release()); + contents_.push_back(std::move(s)); + } + const std::vector<std::unique_ptr<const ParseNode>>& contents() const { + return contents_; } - const std::vector<const ParseNode*>& contents() const { return contents_; } void SortAsStringsList(); void SortAsDepsList(); @@ -397,8 +400,7 @@ class ListNode : public ParseNode { std::unique_ptr<EndNode> end_; bool prefer_multiline_; - // Owning pointers, use unique_ptr when we can use C++11. - std::vector<const ParseNode*> contents_; + std::vector<std::unique_ptr<const ParseNode>> contents_; DISALLOW_COPY_AND_ASSIGN(ListNode); }; diff --git a/chromium/tools/gn/parser.cc b/chromium/tools/gn/parser.cc index 33abfd0b2f0..977ddad6e7b 100644 --- a/chromium/tools/gn/parser.cc +++ b/chromium/tools/gn/parser.cc @@ -671,7 +671,7 @@ void Parser::TraverseOrder(const ParseNode* root, TraverseOrder(binop->right(), pre, post); } else if (const BlockNode* block = root->AsBlock()) { for (const auto& statement : block->statements()) - TraverseOrder(statement, pre, post); + TraverseOrder(statement.get(), pre, post); TraverseOrder(block->End(), pre, post); } else if (const ConditionNode* condition = root->AsConditionNode()) { TraverseOrder(condition->condition(), pre, post); @@ -684,7 +684,7 @@ void Parser::TraverseOrder(const ParseNode* root, // Nothing. } else if (const ListNode* list = root->AsList()) { for (const auto& node : list->contents()) - TraverseOrder(node, pre, post); + TraverseOrder(node.get(), pre, post); TraverseOrder(list->End(), pre, post); } else if (root->AsLiteral()) { // Nothing. diff --git a/chromium/tools/gn/qt_creator_writer.cc b/chromium/tools/gn/qt_creator_writer.cc new file mode 100644 index 00000000000..96f247f5719 --- /dev/null +++ b/chromium/tools/gn/qt_creator_writer.cc @@ -0,0 +1,174 @@ +// Copyright (c) 2016 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. + +#include "tools/gn/qt_creator_writer.h" + +#include <set> +#include <sstream> +#include <string> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/strings/utf_string_conversions.h" + +#include "tools/gn/builder.h" +#include "tools/gn/config_values_extractors.h" +#include "tools/gn/deps_iterator.h" +#include "tools/gn/filesystem_utils.h" +#include "tools/gn/label.h" +#include "tools/gn/loader.h" + +namespace { +base::FilePath::CharType kProjectDirName[] = + FILE_PATH_LITERAL("qtcreator_project"); +base::FilePath::CharType kProjectName[] = FILE_PATH_LITERAL("all"); +base::FilePath::CharType kMainProjectFileSuffix[] = + FILE_PATH_LITERAL(".creator"); +base::FilePath::CharType kSourcesFileSuffix[] = FILE_PATH_LITERAL(".files"); +base::FilePath::CharType kIncludesFileSuffix[] = FILE_PATH_LITERAL(".includes"); +base::FilePath::CharType kDefinesFileSuffix[] = FILE_PATH_LITERAL(".config"); +} + +// static +bool QtCreatorWriter::RunAndWriteFile(const BuildSettings* build_settings, + const Builder* builder, + Err* err, + const std::string& root_target) { + base::FilePath project_dir = + build_settings->GetFullPath(build_settings->build_dir()) + .Append(kProjectDirName); + if (!base::DirectoryExists(project_dir)) { + base::File::Error error; + if (!base::CreateDirectoryAndGetError(project_dir, &error)) { + *err = + Err(Location(), "Could not create the QtCreator project directory '" + + FilePathToUTF8(project_dir) + "': " + + base::File::ErrorToString(error)); + return false; + } + } + + base::FilePath project_prefix = project_dir.Append(kProjectName); + QtCreatorWriter gen(build_settings, builder, project_prefix, root_target); + gen.Run(); + if (gen.err_.has_error()) { + *err = gen.err_; + return false; + } + return true; +} + +QtCreatorWriter::QtCreatorWriter(const BuildSettings* build_settings, + const Builder* builder, + const base::FilePath& project_prefix, + const std::string& root_target_name) + : build_settings_(build_settings), + builder_(builder), + project_prefix_(project_prefix), + root_target_name_(root_target_name) {} + +QtCreatorWriter::~QtCreatorWriter() {} + +void QtCreatorWriter::CollectDeps(const Target* target) { + for (const auto& dep : target->GetDeps(Target::DEPS_ALL)) { + const Target* dep_target = dep.ptr; + if (targets_.count(dep_target)) + continue; + targets_.insert(dep_target); + CollectDeps(dep_target); + } +} + +bool QtCreatorWriter::DiscoverTargets() { + auto all_targets = builder_->GetAllResolvedTargets(); + + if (root_target_name_.empty()) { + targets_ = std::set<const Target*>(all_targets.begin(), all_targets.end()); + return true; + } + + const Target* root_target = nullptr; + for (const Target* target : all_targets) { + if (target->label().name() == root_target_name_) { + root_target = target; + break; + } + } + + if (!root_target) { + err_ = Err(Location(), "Target '" + root_target_name_ + "' not found."); + return false; + } + + targets_.insert(root_target); + CollectDeps(root_target); + return true; +} + +void QtCreatorWriter::AddToSources(const Target::FileList& files) { + for (const SourceFile& file : files) { + const std::string& file_path = + FilePathToUTF8(build_settings_->GetFullPath(file)); + sources_.insert(file_path); + } +} + +void QtCreatorWriter::HandleTarget(const Target* target) { + SourceFile build_file = Loader::BuildFileForLabel(target->label()); + sources_.insert(FilePathToUTF8(build_settings_->GetFullPath(build_file))); + AddToSources(target->settings()->import_manager().GetImportedFiles()); + + AddToSources(target->sources()); + AddToSources(target->public_headers()); + AddToSources(target->inputs()); + + for (ConfigValuesIterator it(target); !it.done(); it.Next()) { + SourceFile precompiled_source = it.cur().precompiled_source(); + if (!precompiled_source.is_null()) { + sources_.insert( + FilePathToUTF8(build_settings_->GetFullPath(precompiled_source))); + } + + for (const SourceDir& include_dir : it.cur().include_dirs()) { + includes_.insert( + FilePathToUTF8(build_settings_->GetFullPath(include_dir))); + } + + for (std::string define : it.cur().defines()) { + size_t equal_pos = define.find('='); + if (equal_pos != std::string::npos) + define[equal_pos] = ' '; + define.insert(0, "#define "); + defines_.insert(define); + } + } +} + +void QtCreatorWriter::GenerateFile(const base::FilePath::CharType* suffix, + const std::set<std::string>& items) { + const base::FilePath file_path = project_prefix_.AddExtension(suffix); + std::ostringstream output; + for (const std::string& item : items) + output << item << std::endl; + WriteFileIfChanged(file_path, output.str(), &err_); +} + +void QtCreatorWriter::Run() { + if (!DiscoverTargets()) + return; + + for (const Target* target : targets_) { + if (target->toolchain()->label() != + builder_->loader()->GetDefaultToolchain()) + continue; + HandleTarget(target); + } + + std::set<std::string> empty_list; + + GenerateFile(kMainProjectFileSuffix, empty_list); + GenerateFile(kSourcesFileSuffix, sources_); + GenerateFile(kIncludesFileSuffix, includes_); + GenerateFile(kDefinesFileSuffix, defines_); +} diff --git a/chromium/tools/gn/qt_creator_writer.h b/chromium/tools/gn/qt_creator_writer.h new file mode 100644 index 00000000000..cea75fd1814 --- /dev/null +++ b/chromium/tools/gn/qt_creator_writer.h @@ -0,0 +1,56 @@ +// Copyright (c) 2016 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. + +#ifndef TOOLS_GN_QT_CREATOR_WRITER_H_ +#define TOOLS_GN_QT_CREATOR_WRITER_H_ + +#include <set> +#include <string> + +#include "base/files/file_path.h" +#include "base/macros.h" +#include "tools/gn/err.h" +#include "tools/gn/target.h" + +class Builder; +class BuildSettings; + +class QtCreatorWriter { + public: + static bool RunAndWriteFile(const BuildSettings* build_settings, + const Builder* builder, + Err* err, + const std::string& root_target); + + private: + QtCreatorWriter(const BuildSettings* build_settings, + const Builder* builder, + const base::FilePath& project_prefix, + const std::string& root_target_name); + ~QtCreatorWriter(); + + void Run(); + + bool DiscoverTargets(); + void HandleTarget(const Target* target); + + void CollectDeps(const Target* target); + void AddToSources(const Target::FileList& files); + void GenerateFile(const base::FilePath::CharType* suffix, + const std::set<std::string>& items); + + const BuildSettings* build_settings_; + const Builder* builder_; + base::FilePath project_prefix_; + std::string root_target_name_; + std::set<const Target*> targets_; + std::set<std::string> sources_; + std::set<std::string> includes_; + std::set<std::string> defines_; + Err err_; + + DISALLOW_COPY_AND_ASSIGN(QtCreatorWriter); +}; + +#endif // TOOLS_GN_QT_CREATOR_WRITER_H_ diff --git a/chromium/tools/gn/runtime_deps.cc b/chromium/tools/gn/runtime_deps.cc index 17b9c075227..5352de3aadd 100644 --- a/chromium/tools/gn/runtime_deps.cc +++ b/chromium/tools/gn/runtime_deps.cc @@ -104,6 +104,15 @@ void RecursiveCollectRuntimeDeps(const Target* target, AddIfNew(output_file.value(), target, deps, found_files); } + // Do not recurse into bundle targets. A bundle's dependencies should be + // copied into the bundle itself for run-time access. + if (target->output_type() == Target::CREATE_BUNDLE) { + SourceDir bundle_root_dir = + target->bundle_data().GetBundleRootDirOutputAsDir(target->settings()); + AddIfNew(bundle_root_dir.value(), target, deps, found_files); + return; + } + // Non-data dependencies (both public and private). for (const auto& dep_pair : target->GetDeps(Target::DEPS_LINKED)) { if (dep_pair.ptr->output_type() == Target::EXECUTABLE) diff --git a/chromium/tools/gn/runtime_deps_unittest.cc b/chromium/tools/gn/runtime_deps_unittest.cc index 915fbc28302..8b68bd85c4d 100644 --- a/chromium/tools/gn/runtime_deps_unittest.cc +++ b/chromium/tools/gn/runtime_deps_unittest.cc @@ -8,6 +8,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "tools/gn/runtime_deps.h" +#include "tools/gn/scheduler.h" #include "tools/gn/target.h" #include "tools/gn/test_with_scope.h" @@ -257,6 +258,83 @@ TEST(RuntimeDeps, ActionOutputs) { EXPECT_TRUE(MakePair("../../dep.data", &dep) == result[0]); } +// Tests that the search for dependencies terminates at a bundle target, +// ignoring any shared libraries or loadable modules that get copied into the +// bundle. +TEST(RuntimeDeps, CreateBundle) { + TestWithScope setup; + Err err; + + // Dependency hierarchy: + // main(exe) -> dep(bundle) -> dep(shared_library) -> dep(source set) + // -> dep(bundle_data) -> dep(loadable_module) + + const SourceDir source_dir("//"); + const std::string& build_dir = setup.build_settings()->build_dir().value(); + + Target loadable_module(setup.settings(), + Label(source_dir, "loadable_module")); + InitTargetWithType(setup, &loadable_module, Target::LOADABLE_MODULE); + ASSERT_TRUE(loadable_module.OnResolved(&err)); + + Target module_data(setup.settings(), Label(source_dir, "module_data")); + InitTargetWithType(setup, &module_data, Target::BUNDLE_DATA); + module_data.private_deps().push_back(LabelTargetPair(&loadable_module)); + module_data.bundle_data().file_rules().push_back(BundleFileRule( + std::vector<SourceFile>{SourceFile(build_dir + "loadable_module.so")}, + SubstitutionPattern::MakeForTest("{{bundle_resources_dir}}"))); + ASSERT_TRUE(module_data.OnResolved(&err)); + + Target source_set(setup.settings(), Label(source_dir, "sources")); + InitTargetWithType(setup, &source_set, Target::SOURCE_SET); + source_set.sources().push_back(SourceFile(source_dir.value() + "foo.cc")); + ASSERT_TRUE(source_set.OnResolved(&err)); + + Target dylib(setup.settings(), Label(source_dir, "dylib")); + dylib.set_output_prefix_override(true); + dylib.set_output_extension(""); + dylib.set_output_name("Bundle"); + InitTargetWithType(setup, &dylib, Target::SHARED_LIBRARY); + dylib.private_deps().push_back(LabelTargetPair(&source_set)); + ASSERT_TRUE(dylib.OnResolved(&err)); + + Target dylib_data(setup.settings(), Label(source_dir, "dylib_data")); + InitTargetWithType(setup, &dylib_data, Target::BUNDLE_DATA); + dylib_data.private_deps().push_back(LabelTargetPair(&dylib)); + dylib_data.bundle_data().file_rules().push_back(BundleFileRule( + std::vector<SourceFile>{SourceFile(build_dir + "dylib")}, + SubstitutionPattern::MakeForTest("{{bundle_executable_dir}}"))); + ASSERT_TRUE(dylib_data.OnResolved(&err)); + + Target bundle(setup.settings(), Label(source_dir, "bundle")); + InitTargetWithType(setup, &bundle, Target::CREATE_BUNDLE); + const std::string root_dir(build_dir + "Bundle.framework/Versions/A/"); + bundle.bundle_data().root_dir() = SourceDir(root_dir); + bundle.bundle_data().resources_dir() = SourceDir(root_dir + "Resources"); + bundle.bundle_data().executable_dir() = SourceDir(root_dir + "MacOS"); + bundle.private_deps().push_back(LabelTargetPair(&dylib_data)); + bundle.private_deps().push_back(LabelTargetPair(&module_data)); + ASSERT_TRUE(bundle.OnResolved(&err)); + + Target main(setup.settings(), Label(source_dir, "main")); + InitTargetWithType(setup, &main, Target::EXECUTABLE); + main.data_deps().push_back(LabelTargetPair(&bundle)); + ASSERT_TRUE(main.OnResolved(&err)); + + std::vector<std::pair<OutputFile, const Target*>> result = + ComputeRuntimeDeps(&main); + + // The result should have deps of main, datadep, final_in.dat + ASSERT_EQ(2u, result.size()) << GetVectorDescription(result); + + // The first one should always be the main exe. + EXPECT_EQ(MakePair("./main", &main), result[0]); + + // The second one should be the framework bundle, not its included + // loadable_module or its intermediate shared_library. + EXPECT_EQ(MakePair("Bundle.framework/", &bundle), result[1]); +} + // Tests that a dependency duplicated in regular and data deps is processed // as a data dep. TEST(RuntimeDeps, Dupe) { @@ -282,3 +360,31 @@ TEST(RuntimeDeps, Dupe) { MakePair("../../action.output", &action)) != result.end()) << GetVectorDescription(result); } + +// Tests that actions can't have output substitutions. +TEST(RuntimeDeps, WriteRuntimeDepsVariable) { + Scheduler scheduler; + TestWithScope setup; + Err err; + + // Should refuse to write files outside of the output dir. + EXPECT_FALSE(setup.ExecuteSnippet( + "group(\"foo\") { write_runtime_deps = \"//foo.txt\" }", &err)); + + // Should fail for garbage inputs. + err = Err(); + EXPECT_FALSE(setup.ExecuteSnippet( + "group(\"foo\") { write_runtime_deps = 0 }", &err)); + + // Should be able to write inside the out dir, and shouldn't write the one + // in the else clause. + err = Err(); + EXPECT_TRUE(setup.ExecuteSnippet( + "if (true) {\n" + " group(\"foo\") { write_runtime_deps = \"//out/Debug/foo.txt\" }\n" + "} else {\n" + " group(\"bar\") { write_runtime_deps = \"//out/Debug/bar.txt\" }\n" + "}", &err)); + EXPECT_EQ(1U, setup.items().size()); + EXPECT_EQ(1U, scheduler.GetWriteRuntimeDepsTargets().size()); +} diff --git a/chromium/tools/gn/scheduler.cc b/chromium/tools/gn/scheduler.cc index a711df1cf02..b2e2a006b96 100644 --- a/chromium/tools/gn/scheduler.cc +++ b/chromium/tools/gn/scheduler.cc @@ -54,10 +54,13 @@ int GetThreadCount() { // // One less worker thread than the number of physical CPUs seems to be a // good value, both theoretically and experimentally. But always use at - // least three workers to prevent us from being too sensitive to I/O latency + // least some workers to prevent us from being too sensitive to I/O latency // on low-end systems. + // + // The minimum thread count is based on measuring the optimal threads for the + // Chrome build on a several-year-old 4-core MacBook. int num_cores = GetCPUCount() / 2; // Almost all CPUs now are hyperthreaded. - return std::max(num_cores - 1, 3); + return std::max(num_cores - 1, 8); } } // namespace diff --git a/chromium/tools/gn/scope.cc b/chromium/tools/gn/scope.cc index d3d29d44927..93ce966e4f3 100644 --- a/chromium/tools/gn/scope.cc +++ b/chromium/tools/gn/scope.cc @@ -5,7 +5,7 @@ #include "tools/gn/scope.h" #include "base/logging.h" -#include "base/stl_util.h" +#include "base/memory/ptr_util.h" #include "tools/gn/parse_tree.h" #include "tools/gn/template.h" @@ -64,8 +64,6 @@ Scope::Scope(const Scope* parent) } Scope::~Scope() { - STLDeleteContainerPairSecondPointers(target_defaults_.begin(), - target_defaults_.end()); } const Value* Scope::GetValue(const base::StringPiece& ident, @@ -315,12 +313,9 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, } } - // Be careful to delete any pointer we're about to clobber. - Scope** dest_scope = &dest->target_defaults_[current_name]; - if (*dest_scope) - delete *dest_scope; - *dest_scope = new Scope(settings_); - pair.second->NonRecursiveMergeTo(*dest_scope, options, node_for_err, + std::unique_ptr<Scope>& dest_scope = dest->target_defaults_[current_name]; + dest_scope = base::WrapUnique(new Scope(settings_)); + pair.second->NonRecursiveMergeTo(dest_scope.get(), options, node_for_err, "<SHOULDN'T HAPPEN>", err); } @@ -412,19 +407,19 @@ Scope* Scope::MakeTargetDefaults(const std::string& target_type) { if (GetTargetDefaults(target_type)) return nullptr; - Scope** dest = &target_defaults_[target_type]; - if (*dest) { + std::unique_ptr<Scope>& dest = target_defaults_[target_type]; + if (dest) { NOTREACHED(); // Already set. - return *dest; + return dest.get(); } - *dest = new Scope(settings_); - return *dest; + dest = base::WrapUnique(new Scope(settings_)); + return dest.get(); } const Scope* Scope::GetTargetDefaults(const std::string& target_type) const { NamedScopeMap::const_iterator found = target_defaults_.find(target_type); if (found != target_defaults_.end()) - return found->second; + return found->second.get(); if (containing()) return containing()->GetTargetDefaults(target_type); return nullptr; diff --git a/chromium/tools/gn/scope.h b/chromium/tools/gn/scope.h index 72aa0c3e2fb..e9bd1397cc9 100644 --- a/chromium/tools/gn/scope.h +++ b/chromium/tools/gn/scope.h @@ -333,10 +333,9 @@ class Scope { RecordMap; RecordMap values_; - // Owning pointers. Note that this can't use string pieces since the names - // are constructed from Values which might be deallocated before this goes - // out of scope. - typedef base::hash_map<std::string, Scope*> NamedScopeMap; + // Note that this can't use string pieces since the names are constructed from + // Values which might be deallocated before this goes out of scope. + typedef base::hash_map<std::string, std::unique_ptr<Scope>> NamedScopeMap; NamedScopeMap target_defaults_; // Null indicates not set and that we should fallback to the containing diff --git a/chromium/tools/gn/setup.cc b/chromium/tools/gn/setup.cc index 384a2af17ea..ea7cb240908 100644 --- a/chromium/tools/gn/setup.cc +++ b/chromium/tools/gn/setup.cc @@ -299,7 +299,7 @@ bool Setup::DoSetup(const std::string& build_dir, bool force_create) { if (!FillArguments(*cmdline)) return false; } - FillPythonPath(); + FillPythonPath(*cmdline); return true; } @@ -332,9 +332,13 @@ bool Setup::RunPostMessageLoop() { } if (!build_settings_.build_args().VerifyAllOverridesUsed(&err)) { - // TODO(brettw) implement a system of warnings. Until we have a better - // system, print the error but don't return failure. + // TODO(brettw) implement a system to have a different marker for + // warnings. Until we have a better system, print the error but don't + // return failure unless requested on the command line. err.PrintToStdout(); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kFailOnUnusedArgs)) + return false; return true; } } @@ -590,20 +594,25 @@ bool Setup::FillBuildDir(const std::string& build_dir, bool require_exists) { return true; } -void Setup::FillPythonPath() { +void Setup::FillPythonPath(const base::CommandLine& cmdline) { // Trace this since it tends to be a bit slow on Windows. ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Fill Python Path"); + if (cmdline.HasSwitch(switches::kScriptExecutable)) { + build_settings_.set_python_path( + cmdline.GetSwitchValuePath(switches::kScriptExecutable)); + } else { #if defined(OS_WIN) - base::FilePath python_path = FindWindowsPython(); - if (python_path.empty()) { - scheduler_.Log("WARNING", "Could not find python on path, using " - "just \"python.exe\""); - python_path = base::FilePath(kPythonExeName); - } - build_settings_.set_python_path(python_path.NormalizePathSeparatorsTo('/')); + base::FilePath python_path = FindWindowsPython(); + if (python_path.empty()) { + scheduler_.Log("WARNING", "Could not find python on path, using " + "just \"python.exe\""); + python_path = base::FilePath(kPythonExeName); + } + build_settings_.set_python_path(python_path.NormalizePathSeparatorsTo('/')); #else - build_settings_.set_python_path(base::FilePath("python")); + build_settings_.set_python_path(base::FilePath("python")); #endif + } } bool Setup::RunConfigFile() { diff --git a/chromium/tools/gn/setup.h b/chromium/tools/gn/setup.h index 4f2d8859951..22e655745b1 100644 --- a/chromium/tools/gn/setup.h +++ b/chromium/tools/gn/setup.h @@ -119,7 +119,7 @@ class Setup { // Fills the python path portion of the command line. On failure, sets // it to just "python". - void FillPythonPath(); + void FillPythonPath(const base::CommandLine& cmdline); // Run config file. bool RunConfigFile(); diff --git a/chromium/tools/gn/source_file_type.cc b/chromium/tools/gn/source_file_type.cc index 72b872c5cae..328b2abbac3 100644 --- a/chromium/tools/gn/source_file_type.cc +++ b/chromium/tools/gn/source_file_type.cc @@ -11,7 +11,8 @@ SourceFileType GetSourceFileType(const SourceFile& file) { base::StringPiece extension = FindExtension(&file.value()); if (extension == "cc" || extension == "cpp" || extension == "cxx") return SOURCE_CPP; - if (extension == "h") + if (extension == "h" || extension == "hpp" || extension == "hxx" || + extension == "hh") return SOURCE_H; if (extension == "c") return SOURCE_C; diff --git a/chromium/tools/gn/substitution_type.cc b/chromium/tools/gn/substitution_type.cc index e1ea14de947..fcca19dac06 100644 --- a/chromium/tools/gn/substitution_type.cc +++ b/chromium/tools/gn/substitution_type.cc @@ -43,9 +43,12 @@ const char* kSubstitutionNames[SUBSTITUTION_NUM_TYPES] = { "{{inputs_newline}}", // SUBSTITUTION_LINKER_INPUTS_NEWLINE "{{ldflags}}", // SUBSTITUTION_LDFLAGS "{{libs}}", // SUBSTITUTION_LIBS + "{{output_dir}}", // SUBSTITUTION_OUTPUT_DIR "{{output_extension}}", // SUBSTITUTION_OUTPUT_EXTENSION "{{solibs}}", // SUBSTITUTION_SOLIBS + "{{arflags}}", // SUBSTITUTION_ARFLAGS + "{{bundle_root_dir}}", // SUBSTITUTION_BUNDLE_ROOT_DIR "{{bundle_resources_dir}}", // SUBSTITUTION_BUNDLE_RESOURCES_DIR "{{bundle_executable_dir}}", // SUBSTITUTION_BUNDLE_EXECUTABLE_DIR @@ -91,9 +94,12 @@ const char* kSubstitutionNinjaNames[SUBSTITUTION_NUM_TYPES] = { "in_newline", // SUBSTITUTION_LINKER_INPUTS_NEWLINE "ldflags", // SUBSTITUTION_LDFLAGS "libs", // SUBSTITUTION_LIBS + "output_dir", // SUBSTITUTION_OUTPUT_DIR "output_extension", // SUBSTITUTION_OUTPUT_EXTENSION "solibs", // SUBSTITUTION_SOLIBS + "arflags", // SUBSTITUTION_ARFLAGS + "bundle_root_dir", // SUBSTITUTION_BUNDLE_ROOT_DIR "bundle_resources_dir", // SUBSTITUTION_BUNDLE_RESOURCES_DIR "bundle_executable_dir", // SUBSTITUTION_BUNDLE_EXECUTABLE_DIR @@ -193,6 +199,7 @@ bool IsValidLinkerSubstitution(SubstitutionType type) { type == SUBSTITUTION_LINKER_INPUTS_NEWLINE || type == SUBSTITUTION_LDFLAGS || type == SUBSTITUTION_LIBS || + type == SUBSTITUTION_OUTPUT_DIR || type == SUBSTITUTION_OUTPUT_EXTENSION || type == SUBSTITUTION_SOLIBS; } @@ -200,6 +207,16 @@ bool IsValidLinkerSubstitution(SubstitutionType type) { bool IsValidLinkerOutputsSubstitution(SubstitutionType type) { // All valid compiler outputs plus the output extension. return IsValidCompilerOutputsSubstitution(type) || + type == SUBSTITUTION_OUTPUT_DIR || + type == SUBSTITUTION_OUTPUT_EXTENSION; +} + +bool IsValidALinkSubstitution(SubstitutionType type) { + return IsValidToolSubstitution(type) || + type == SUBSTITUTION_LINKER_INPUTS || + type == SUBSTITUTION_LINKER_INPUTS_NEWLINE || + type == SUBSTITUTION_ARFLAGS || + type == SUBSTITUTION_OUTPUT_DIR || type == SUBSTITUTION_OUTPUT_EXTENSION; } diff --git a/chromium/tools/gn/substitution_type.h b/chromium/tools/gn/substitution_type.h index 3f7ec971abd..e82ecd61073 100644 --- a/chromium/tools/gn/substitution_type.h +++ b/chromium/tools/gn/substitution_type.h @@ -56,9 +56,13 @@ enum SubstitutionType { SUBSTITUTION_LINKER_INPUTS_NEWLINE, // {{inputs_newline}} SUBSTITUTION_LDFLAGS, // {{ldflags}} SUBSTITUTION_LIBS, // {{libs}} + SUBSTITUTION_OUTPUT_DIR, // {{output_dir}} SUBSTITUTION_OUTPUT_EXTENSION, // {{output_extension}} SUBSTITUTION_SOLIBS, // {{solibs}} + // Valid for alink only. + SUBSTITUTION_ARFLAGS, // {{arflags}} + // Valid for bundle_data targets. SUBSTITUTION_BUNDLE_ROOT_DIR, // {{bundle_root_dir}} SUBSTITUTION_BUNDLE_RESOURCES_DIR, // {{bundle_resources_dir}} @@ -116,6 +120,7 @@ bool IsValidCompilerSubstitution(SubstitutionType type); bool IsValidCompilerOutputsSubstitution(SubstitutionType type); bool IsValidLinkerSubstitution(SubstitutionType type); bool IsValidLinkerOutputsSubstitution(SubstitutionType type); +bool IsValidALinkSubstitution(SubstitutionType type); bool IsValidCopySubstitution(SubstitutionType type); bool IsValidCompileXCassetsSubstitution(SubstitutionType type); diff --git a/chromium/tools/gn/substitution_writer.cc b/chromium/tools/gn/substitution_writer.cc index 23d6914ac4e..a82e7ee2e75 100644 --- a/chromium/tools/gn/substitution_writer.cc +++ b/chromium/tools/gn/substitution_writer.cc @@ -56,6 +56,10 @@ const char kSourceExpansion_Help[] = "\n" "Placeholders\n" "\n" + " This section discusses only placeholders for actions. There are other\n" + " placeholders used in the definition of tools. See \"gn help tool\" for\n" + " those.\n" + "\n" " {{source}}\n" " The name of the source file including directory (*). This will\n" " generally be used for specifying inputs to a script in the\n" @@ -546,6 +550,23 @@ std::string SubstitutionWriter::GetLinkerSubstitution( // Fall-through to the linker-specific ones. switch (type) { + case SUBSTITUTION_OUTPUT_DIR: + // Use the target's value if there is one (it will have no expansion + // patterns since it can directly use GN variables to compute whatever + // path it wants), or the tool's default (which will contain further + // expansions). + if (target->output_dir().is_null()) { + return ApplyPatternToLinkerAsOutputFile( + target, tool, tool->default_output_dir()).value(); + } else { + SetDirOrDotWithNoSlash(RebasePath( + target->output_dir().value(), + target->settings()->build_settings()->build_dir()), + &result); + return result; + } + break; + case SUBSTITUTION_OUTPUT_EXTENSION: // Use the extension provided on the target if specified, otherwise // fall back on the default. Note that the target's output extension diff --git a/chromium/tools/gn/substitution_writer_unittest.cc b/chromium/tools/gn/substitution_writer_unittest.cc index 77374f1a313..d252c79f54c 100644 --- a/chromium/tools/gn/substitution_writer_unittest.cc +++ b/chromium/tools/gn/substitution_writer_unittest.cc @@ -278,4 +278,46 @@ TEST(SubstitutionWriter, LinkerSubstitutions) { EXPECT_EQ("", SubstitutionWriter::GetLinkerSubstitution( &target, tool, SUBSTITUTION_OUTPUT_EXTENSION)); + + // Output directory is tested in a separate test below. +} + +TEST(SubstitutionWriter, OutputDir) { + TestWithScope setup; + Err err; + + // This tool has an output directory pattern and uses that for the + // output name. + Tool tool; + SubstitutionPattern out_dir_pattern; + ASSERT_TRUE(out_dir_pattern.Parse("{{root_out_dir}}/{{target_output_name}}", + nullptr, &err)); + tool.set_default_output_dir(out_dir_pattern); + tool.SetComplete(); + + // Default target with no output dir overrides. + Target target(setup.settings(), Label(SourceDir("//foo/"), "baz")); + target.set_output_type(Target::EXECUTABLE); + target.SetToolchain(setup.toolchain()); + ASSERT_TRUE(target.OnResolved(&err)); + + // The output should expand the default from the patterns in the tool. + SubstitutionPattern output_name; + ASSERT_TRUE(output_name.Parse("{{output_dir}}/{{target_output_name}}.exe", + nullptr, &err)); + EXPECT_EQ("./baz/baz.exe", + SubstitutionWriter::ApplyPatternToLinkerAsOutputFile( + &target, &tool, output_name).value()); + + // Override the output name to the root build dir. + target.set_output_dir(SourceDir("//out/Debug/")); + EXPECT_EQ("./baz.exe", + SubstitutionWriter::ApplyPatternToLinkerAsOutputFile( + &target, &tool, output_name).value()); + + // Override the output name to a new subdirectory. + target.set_output_dir(SourceDir("//out/Debug/foo/bar")); + EXPECT_EQ("foo/bar/baz.exe", + SubstitutionWriter::ApplyPatternToLinkerAsOutputFile( + &target, &tool, output_name).value()); } diff --git a/chromium/tools/gn/switches.cc b/chromium/tools/gn/switches.cc index df167b30aa5..8884634f906 100644 --- a/chromium/tools/gn/switches.cc +++ b/chromium/tools/gn/switches.cc @@ -69,17 +69,51 @@ const char kDotfile_Help[] = " Note that this interacts with \"--root\" in a possibly incorrect way.\n" " It would be nice to test the edge cases and document or fix.\n"; +const char kFailOnUnusedArgs[] = "fail-on-unused-args"; +const char kFailOnUnusedArgs_HelpShort[] = + "--fail-on-unused-args: Treat unused build args as fatal errors."; +const char kFailOnUnusedArgs_Help[] = + "--fail-on-unused-args: Treat unused build args as fatal errors.\n" + "\n" + " If you set a value in a build's \"gn args\" and never use it in the\n" + " build (in a declare_args() block), GN will normally print an error\n" + " but not fail the build.\n" + "\n" + " In many cases engineers would use build args to enable or disable\n" + " features that would sometimes get removed. It would by annoying to\n" + " block work for typically benign problems. In Chrome in particular,\n" + " flags might be configured for build bots in a separate infrastructure\n" + " repository, or a declare_args block might be changed in a third party\n" + " repository. Treating these errors as blocking forced complex multi-\n" + " way patches to land what would otherwise be simple changes.\n" + "\n" + " In some cases, such concerns are not as important, and a mismatch\n" + " in build flags between the invoker of the build and the build files\n" + " represents a critical mismatch that should be immediately fixed. Such\n" + " users can set this flag to force GN to fail in that case.\n"; + const char kMarkdown[] = "markdown"; const char kMarkdown_HelpShort[] = - "--markdown: write the output in the Markdown format."; + "--markdown: Write help output in the Markdown format."; const char kMarkdown_Help[] = - "--markdown: write the output in the Markdown format.\n"; + "--markdown: Write help output in the Markdown format.\n"; const char kNoColor[] = "nocolor"; const char kNoColor_HelpShort[] = "--nocolor: Force non-colored output."; const char kNoColor_Help[] = COLOR_HELP_LONG; +const char kScriptExecutable[] = "script-executable"; +const char kScriptExecutable_HelpShort[] = + "--script-executable: Set the executable used to execute scripts."; +const char kScriptExecutable_Help[] = + "--script-executable: Set the executable used to execute scripts.\n" + "\n" + " By default GN searches the PATH for Python to execute scripts in\n" + " action targets and exec_script calls. This flag allows the\n" + " specification of a specific Python executable or potentially\n" + " a different language interpreter.\n"; + const char kQuiet[] = "q"; const char kQuiet_HelpShort[] = "-q: Quiet mode. Don't print output on success."; @@ -202,6 +236,8 @@ const char kVersion_HelpShort[] = // immediately if this switch is used. const char kVersion_Help[] = ""; +const char kAllToolchains[] = "all-toolchains"; + // ----------------------------------------------------------------------------- SwitchInfo::SwitchInfo() @@ -223,11 +259,13 @@ const SwitchInfoMap& GetSwitches() { INSERT_VARIABLE(Args) INSERT_VARIABLE(Color) INSERT_VARIABLE(Dotfile) + INSERT_VARIABLE(FailOnUnusedArgs) INSERT_VARIABLE(Markdown) INSERT_VARIABLE(NoColor) INSERT_VARIABLE(Root) INSERT_VARIABLE(Quiet) INSERT_VARIABLE(RuntimeDepsListFile) + INSERT_VARIABLE(ScriptExecutable) INSERT_VARIABLE(Threads) INSERT_VARIABLE(Time) INSERT_VARIABLE(Tracelog) diff --git a/chromium/tools/gn/switches.h b/chromium/tools/gn/switches.h index 3dc5b9f0f25..effaa25ed3c 100644 --- a/chromium/tools/gn/switches.h +++ b/chromium/tools/gn/switches.h @@ -40,6 +40,10 @@ extern const char kDotfile[]; extern const char kDotfile_HelpShort[]; extern const char kDotfile_Help[]; +extern const char kFailOnUnusedArgs[]; +extern const char kFailOnUnusedArgs_HelpShort[]; +extern const char kFailOnUnusedArgs_Help[]; + extern const char kMarkdown[]; extern const char kMarkdown_HelpShort[]; extern const char kMarkdown_Help[]; @@ -48,6 +52,10 @@ extern const char kNoColor[]; extern const char kNoColor_HelpShort[]; extern const char kNoColor_Help[]; +extern const char kScriptExecutable[]; +extern const char kScriptExecutable_HelpShort[]; +extern const char kScriptExecutable_Help[]; + extern const char kQuiet[]; extern const char kQuiet_HelpShort[]; extern const char kQuiet_Help[]; @@ -80,6 +88,20 @@ extern const char kVersion[]; extern const char kVersion_HelpShort[]; extern const char kVersion_Help[]; +// This switch is used by several commands. It is here so it can be shared, +// but it's documented in the individual commands it applies to rather than +// globally. +extern const char kAllToolchains[]; +#define ALL_TOOLCHAINS_SWITCH_HELP \ + " --all-toolchains\n" \ + " Normally only inputs in the default toolchain will be included.\n" \ + " This switch will turn on matching all toolchains.\n" \ + "\n" \ + " For example, a file is in a target might be compiled twice:\n" \ + " once in the default toolchain and once in a secondary one. Without\n" \ + " this flag, only the default toolchain one will be matched by\n" \ + " wildcards. With this flag, both will be matched.\n" + } // namespace switches #endif // TOOLS_GN_SWITCHES_H_ diff --git a/chromium/tools/gn/target.cc b/chromium/tools/gn/target.cc index 18c353eac05..ddc8ad5074d 100644 --- a/chromium/tools/gn/target.cc +++ b/chromium/tools/gn/target.cc @@ -55,19 +55,6 @@ Err MakeTestOnlyError(const Target* from, const Target* to) { "Either mark it test-only or don't do this dependency."); } -Err MakeStaticLibDepsError(const Target* from, const Target* to) { - return Err(from->defined_from(), - "Complete static libraries can't depend on static libraries.", - from->label().GetUserVisibleName(false) + - "\n" - "which is a complete static library can't depend on\n" + - to->label().GetUserVisibleName(false) + - "\n" - "which is a static library.\n" - "\n" - "Use source sets for intermediate targets instead."); -} - // Set check_private_deps to true for the first invocation since a target // can see all of its dependencies. For recursive invocations this will be set // to false to follow only public dependency paths. @@ -317,13 +304,14 @@ bool Target::OnResolved(Err* err) { return false; if (!CheckTestonly(err)) return false; - if (!CheckNoNestedStaticLibs(err)) - return false; if (!CheckAssertNoDeps(err)) return false; CheckSourcesGenerated(); } + if (!write_runtime_deps_output_.value().empty()) + g_scheduler->AddWriteRuntimeDepsTarget(this); + return true; } @@ -479,8 +467,24 @@ void Target::PullDependentTargetLibsFrom(const Target* dep, bool is_public) { // The current target isn't linked, so propogate linked deps and // libraries up the dependency tree. inherited_libraries_.AppendInherited(dep->inherited_libraries(), is_public); + } else if (dep->complete_static_lib()) { + // Inherit only final targets through _complete_ static libraries. + // + // Inherited final libraries aren't linked into complete static libraries. + // They are forwarded here so that targets that depend on complete + // static libraries can link them in. Conversely, since complete static + // libraries link in non-final targets they shouldn't be inherited. + for (const auto& inherited : + dep->inherited_libraries().GetOrderedAndPublicFlag()) { + if (inherited.first->IsFinal()) { + inherited_libraries_.Append(inherited.first, + is_public && inherited.second); + } + } + } - // Inherited library settings. + // Library settings are always inherited across static library boundaries. + if (!dep->IsFinal() || dep->output_type() == STATIC_LIBRARY) { all_lib_dirs_.append(dep->all_lib_dirs()); all_libs_.append(dep->all_libs()); } @@ -699,30 +703,6 @@ bool Target::CheckTestonly(Err* err) const { return true; } -bool Target::CheckNoNestedStaticLibs(Err* err) const { - // If the current target is not a complete static library, it can depend on - // static library targets with no problem. - if (!(output_type() == Target::STATIC_LIBRARY && complete_static_lib())) - return true; - - // Verify no deps are static libraries. - for (const auto& pair : GetDeps(DEPS_ALL)) { - if (pair.ptr->output_type() == Target::STATIC_LIBRARY) { - *err = MakeStaticLibDepsError(this, pair.ptr); - return false; - } - } - - // Verify no inherited libraries are static libraries. - for (const auto& lib : inherited_libraries().GetOrdered()) { - if (lib->output_type() == Target::STATIC_LIBRARY) { - *err = MakeStaticLibDepsError(this, lib); - return false; - } - } - return true; -} - bool Target::CheckAssertNoDeps(Err* err) const { if (assert_no_deps_.empty()) return true; diff --git a/chromium/tools/gn/target.h b/chromium/tools/gn/target.h index fdd6f1a6821..495a9c15ec9 100644 --- a/chromium/tools/gn/target.h +++ b/chromium/tools/gn/target.h @@ -100,6 +100,12 @@ class Target : public Item { output_prefix_override_ = prefix_override; } + // Desired output directory for the final output. This will be used for + // the {{output_dir}} substitution in the tool if it is specified. If + // is_null, the tool default will be used. + const SourceDir& output_dir() const { return output_dir_; } + void set_output_dir(const SourceDir& dir) { output_dir_ = dir; } + // The output extension is really a tri-state: unset (output_extension_set // is false and the string is empty, meaning the default extension should be // used), the output extension is set but empty (output should have no @@ -324,7 +330,6 @@ class Target : public Item { // Validates the given thing when a target is resolved. bool CheckVisibility(Err* err) const; bool CheckTestonly(Err* err) const; - bool CheckNoNestedStaticLibs(Err* err) const; bool CheckAssertNoDeps(Err* err) const; void CheckSourcesGenerated() const; void CheckSourceGenerated(const SourceFile& source) const; @@ -332,6 +337,7 @@ class Target : public Item { OutputType output_type_; std::string output_name_; bool output_prefix_override_; + SourceDir output_dir_; std::string output_extension_; bool output_extension_set_; diff --git a/chromium/tools/gn/target_generator.cc b/chromium/tools/gn/target_generator.cc index 2132a5b06bd..90642d47d20 100644 --- a/chromium/tools/gn/target_generator.cc +++ b/chromium/tools/gn/target_generator.cc @@ -403,6 +403,5 @@ bool TargetGenerator::FillWriteRuntimeDeps() { OutputFile output_file(GetBuildSettings(), source_file); target_->set_write_runtime_deps_output(output_file); - g_scheduler->AddWriteRuntimeDepsTarget(target_); return true; } diff --git a/chromium/tools/gn/target_unittest.cc b/chromium/tools/gn/target_unittest.cc index e2e41a8708c..622dd54aef7 100644 --- a/chromium/tools/gn/target_unittest.cc +++ b/chromium/tools/gn/target_unittest.cc @@ -183,7 +183,13 @@ TEST(Target, InheritCompleteStaticLib) { TestTarget a(setup, "//foo:a", Target::EXECUTABLE); TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY); b.set_complete_static_lib(true); + + const LibFile lib("foo"); + const SourceDir lib_dir("/foo_dir/"); TestTarget c(setup, "//foo:c", Target::SOURCE_SET); + c.config_values().libs().push_back(lib); + c.config_values().lib_dirs().push_back(lib_dir); + a.public_deps().push_back(LabelTargetPair(&b)); b.public_deps().push_back(LabelTargetPair(&c)); @@ -199,42 +205,74 @@ TEST(Target, InheritCompleteStaticLib) { // A should have B in its inherited libs, but not any others (the complete // static library will include the source set). std::vector<const Target*> a_inherited = a.inherited_libraries().GetOrdered(); - EXPECT_EQ(1u, a_inherited.size()); + ASSERT_EQ(1u, a_inherited.size()); EXPECT_EQ(&b, a_inherited[0]); + + // A should inherit the libs and lib_dirs from the C. + ASSERT_EQ(1u, a.all_libs().size()); + EXPECT_EQ(lib, a.all_libs()[0]); + ASSERT_EQ(1u, a.all_lib_dirs().size()); + EXPECT_EQ(lib_dir, a.all_lib_dirs()[0]); } -TEST(Target, InheritCompleteStaticLibNoDirectStaticLibDeps) { +TEST(Target, InheritCompleteStaticLibStaticLibDeps) { TestWithScope setup; Err err; // Create a dependency chain: - // A (complete static lib) -> B (static lib) - TestTarget a(setup, "//foo:a", Target::STATIC_LIBRARY); - a.set_complete_static_lib(true); + // A (executable) -> B (complete static lib) -> C (static lib) + TestTarget a(setup, "//foo:a", Target::EXECUTABLE); TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY); - + b.set_complete_static_lib(true); + TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY); a.public_deps().push_back(LabelTargetPair(&b)); + b.public_deps().push_back(LabelTargetPair(&c)); + + ASSERT_TRUE(c.OnResolved(&err)); ASSERT_TRUE(b.OnResolved(&err)); - ASSERT_FALSE(a.OnResolved(&err)); + ASSERT_TRUE(a.OnResolved(&err)); + + // B should have C in its inherited libs. + std::vector<const Target*> b_inherited = b.inherited_libraries().GetOrdered(); + ASSERT_EQ(1u, b_inherited.size()); + EXPECT_EQ(&c, b_inherited[0]); + + // A should have B in its inherited libs, but not any others (the complete + // static library will include the static library). + std::vector<const Target*> a_inherited = a.inherited_libraries().GetOrdered(); + ASSERT_EQ(1u, a_inherited.size()); + EXPECT_EQ(&b, a_inherited[0]); } -TEST(Target, InheritCompleteStaticLibNoIheritedStaticLibDeps) { +TEST(Target, InheritCompleteStaticLibInheritedCompleteStaticLibDeps) { TestWithScope setup; Err err; // Create a dependency chain: - // A (complete static lib) -> B (source set) -> C (static lib) - TestTarget a(setup, "//foo:a", Target::STATIC_LIBRARY); - a.set_complete_static_lib(true); - TestTarget b(setup, "//foo:b", Target::SOURCE_SET); + // A (executable) -> B (complete static lib) -> C (complete static lib) + TestTarget a(setup, "//foo:a", Target::EXECUTABLE); + TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY); + b.set_complete_static_lib(true); TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY); + c.set_complete_static_lib(true); - a.public_deps().push_back(LabelTargetPair(&b)); - b.public_deps().push_back(LabelTargetPair(&c)); + a.private_deps().push_back(LabelTargetPair(&b)); + b.private_deps().push_back(LabelTargetPair(&c)); ASSERT_TRUE(c.OnResolved(&err)); ASSERT_TRUE(b.OnResolved(&err)); - ASSERT_FALSE(a.OnResolved(&err)); + ASSERT_TRUE(a.OnResolved(&err)); + + // B should have C in its inherited libs. + std::vector<const Target*> b_inherited = b.inherited_libraries().GetOrdered(); + ASSERT_EQ(1u, b_inherited.size()); + EXPECT_EQ(&c, b_inherited[0]); + + // A should have B and C in its inherited libs. + std::vector<const Target*> a_inherited = a.inherited_libraries().GetOrdered(); + ASSERT_EQ(2u, a_inherited.size()); + EXPECT_EQ(&b, a_inherited[0]); + EXPECT_EQ(&c, a_inherited[1]); } TEST(Target, NoActionDepPropgation) { diff --git a/chromium/tools/gn/test_with_scope.cc b/chromium/tools/gn/test_with_scope.cc index 32d5dd67585..0ddd4636be4 100644 --- a/chromium/tools/gn/test_with_scope.cc +++ b/chromium/tools/gn/test_with_scope.cc @@ -24,6 +24,7 @@ TestWithScope::TestWithScope() settings_.set_default_toolchain_label(toolchain_.label()); SetupToolchain(&toolchain_); + scope_.set_item_collector(&items_); } TestWithScope::~TestWithScope() { @@ -37,6 +38,28 @@ Label TestWithScope::ParseLabel(const std::string& str) const { return result; } +bool TestWithScope::ExecuteSnippet(const std::string& str, Err* err) { + TestParseInput input(str); + if (input.has_error()) { + *err = input.parse_err(); + return false; + } + + size_t first_item = items_.size(); + input.parsed()->Execute(&scope_, err); + if (err->has_error()) + return false; + + for (size_t i = first_item; i < items_.size(); ++i) { + CHECK(items_[i]->AsTarget() != nullptr) + << "Only targets are supported in ExecuteSnippet()"; + items_[i]->AsTarget()->SetToolchain(&toolchain_); + if (!items_[i]->OnResolved(err)) + return false; + } + return true; +} + // static void TestWithScope::SetupToolchain(Toolchain* toolchain) { Err err; diff --git a/chromium/tools/gn/test_with_scope.h b/chromium/tools/gn/test_with_scope.h index fa6fb4b324b..88532438213 100644 --- a/chromium/tools/gn/test_with_scope.h +++ b/chromium/tools/gn/test_with_scope.h @@ -34,6 +34,7 @@ class TestWithScope { Toolchain* toolchain() { return &toolchain_; } const Toolchain* toolchain() const { return &toolchain_; } Scope* scope() { return &scope_; } + const Scope::ItemVector& items() { return items_; } // This buffer accumulates output from any print() commands executed in the // context of this test. Note that the implementation of this is not @@ -44,6 +45,11 @@ class TestWithScope { // assert if the label isn't valid (this is intended for hardcoded labels). Label ParseLabel(const std::string& str) const; + // Parses, evaluates, and resolves targets from the given snippet of code. + // All targets must be defined in dependency order (does not use a Builder, + // just blindly resolves all targets in order). + bool ExecuteSnippet(const std::string& str, Err* err); + // Fills in the tools for the given toolchain with reasonable default values. // The toolchain in this object will be automatically set up with this // function, it is exposed to allow tests to get the same functionality for @@ -62,6 +68,7 @@ class TestWithScope { Settings settings_; Toolchain toolchain_; Scope scope_; + Scope::ItemVector items_; // Supplies the scope with built-in variables like root_out_dir. ScopePerFileProvider scope_progammatic_provider_; diff --git a/chromium/tools/gn/tool.h b/chromium/tools/gn/tool.h index 9360ce66ef6..f6727ed6d16 100644 --- a/chromium/tools/gn/tool.h +++ b/chromium/tools/gn/tool.h @@ -52,6 +52,14 @@ class Tool { default_output_extension_ = ext; } + const SubstitutionPattern& default_output_dir() const { + return default_output_dir_; + } + void set_default_output_dir(const SubstitutionPattern& dir) { + DCHECK(!complete_); + default_output_dir_ = dir; + } + // Dependency file (if supported). const SubstitutionPattern& depfile() const { return depfile_; @@ -186,6 +194,7 @@ class Tool { private: SubstitutionPattern command_; std::string default_output_extension_; + SubstitutionPattern default_output_dir_; SubstitutionPattern depfile_; DepsFormat depsformat_; PrecompiledHeaderType precompiled_header_type_; diff --git a/chromium/tools/gn/variables.cc b/chromium/tools/gn/variables.cc index 4c5fae1adf6..a65d9403e31 100644 --- a/chromium/tools/gn/variables.cc +++ b/chromium/tools/gn/variables.cc @@ -418,6 +418,25 @@ const char kAllowCircularIncludesFrom_Help[] = " public_deps = [ \":c\" ]\n" " }\n"; +const char kArflags[] = "arflags"; +const char kArflags_HelpShort[] = + "arflags: [string list] Arguments passed to static_library archiver."; +const char kArflags_Help[] = + "arflags: Arguments passed to static_library archiver.\n" + "\n" + " A list of flags passed to the archive/lib command that creates static\n" + " libraries.\n" + "\n" + " arflags are NOT pushed to dependents, so applying arflags to source\n" + " sets or any other target type will be a no-op. As with ldflags,\n" + " you could put the arflags in a config and set that as a public or\n" + " \"all dependent\" config, but that will likely not be what you want.\n" + " If you have a chain of static libraries dependent on each other,\n" + " this can cause the flags to propagate up to other static libraries.\n" + " Due to the nature of how arflags are typically used, you will normally\n" + " want to apply them directly on static_library targets themselves.\n" + COMMON_ORDERING_HELP; + const char kArgs[] = "args"; const char kArgs_HelpShort[] = "args: [string list] Arguments passed to an action."; @@ -645,9 +664,16 @@ const char kCompleteStaticLib_Help[] = " In some cases the static library might be the final desired output.\n" " For example, you may be producing a static library for distribution to\n" " third parties. In this case, the static library should include code\n" - " for all dependencies in one complete package. Since GN does not unpack\n" - " static libraries to forward their contents up the dependency chain,\n" - " it is an error for complete static libraries to depend on other static\n" + " for all dependencies in one complete package. However, complete static\n" + " libraries themselves are never linked into other complete static\n" + " libraries. All complete static libraries are for distribution and\n" + " linking them in would cause code duplication in this case. If the\n" + " static library is not for distribution, it should not be complete.\n" + "\n" + " GN treats non-complete static libraries as source sets when they are\n" + " linked into complete static libraries. This is done because some tools\n" + " like AR do not handle dependent static libraries properly. This makes\n" + " it easier to write \"alink\" rules.\n" "\n" " In rare cases it makes sense to list a header in more than one\n" " target if it could be considered conceptually a member of both.\n" @@ -737,7 +763,7 @@ const char kConfigs_Help[] = const char kConsole[] = "console"; const char kConsole_HelpShort[] = - "console [boolean]: Run this action in the console pool."; + "console: [boolean] Run this action in the console pool."; const char kConsole_Help[] = "console: Run this action in the console pool.\n" "\n" @@ -781,7 +807,7 @@ const char kData_Help[] = " generated files both in the \"outputs\" list as well as the \"data\"\n" " list.\n" "\n" - " By convention, directories are be listed with a trailing slash:\n" + " By convention, directories are listed with a trailing slash:\n" " data = [ \"test/data/\" ]\n" " However, no verification is done on these so GN doesn't enforce this.\n" " The paths are just rebased and passed along when requested.\n" @@ -1119,6 +1145,34 @@ const char kOutputExtension_Help[] = " }\n" " }\n"; +const char kOutputDir[] = "output_dir"; +const char kOutputDir_HelpShort[] = + "output_dir: [directory] Directory to put output file in."; +const char kOutputDir_Help[] = + "output_dir: [directory] Directory to put output file in.\n" + "\n" + " For library and executable targets, overrides the directory for the\n" + " final output. This must be in the root_build_dir or a child thereof.\n" + "\n" + " This should generally be in the root_out_dir or a subdirectory thereof\n" + " (the root_out_dir will be the same as the root_build_dir for the\n" + " default toolchain, and will be a subdirectory for other toolchains).\n" + " Not putting the output in a subdirectory of root_out_dir can result\n" + " in collisions between different toolchains, so you will need to take\n" + " steps to ensure that your target is only present in one toolchain.\n" + "\n" + " Normally the toolchain specifies the output directory for libraries\n" + " and executables (see \"gn help tool\"). You will have to consult that\n" + " for the default location. The default location will be used if\n" + " output_dir is undefined or empty.\n" + "\n" + "Example\n" + "\n" + " shared_library(\"doom_melon\") {\n" + " output_dir = \"$root_out_dir/plugin_libs\"\n" + " ...\n" + " }\n"; + const char kOutputName[] = "output_name"; const char kOutputName_HelpShort[] = "output_name: [string] Name for the output file other than the default."; @@ -1272,6 +1326,19 @@ const char kPrecompiledSource_Help[] = " using \"msvc\"-style precompiled headers. It will be implicitly added\n" " to the sources of the target. See \"gn help precompiled_header\".\n"; +const char kProductType[] = "product_type"; +const char kProductType_HelpShort[] = + "product_type: [string] Product type for Xcode projects."; +const char kProductType_Help[] = + "product_type: Product type for Xcode projects.\n" + "\n" + " Correspond to the type of the product of a create_bundle target. Only\n" + " meaningful to Xcode (used as part of the Xcode project generation).\n" + "\n" + " When generating Xcode project files, only create_bundle target with\n" + " a non-empty product_type will have a corresponding target in Xcode\n" + " project.\n"; + const char kPublic[] = "public"; const char kPublic_HelpShort[] = "public: [file list] Declare public header files for a target."; @@ -1610,6 +1677,7 @@ const VariableInfoMap& GetTargetVariables() { if (info_map.empty()) { INSERT_VARIABLE(AllDependentConfigs) INSERT_VARIABLE(AllowCircularIncludesFrom) + INSERT_VARIABLE(Arflags) INSERT_VARIABLE(Args) INSERT_VARIABLE(Asmflags) INSERT_VARIABLE(AssertNoDeps) @@ -1636,12 +1704,14 @@ const VariableInfoMap& GetTargetVariables() { INSERT_VARIABLE(Ldflags) INSERT_VARIABLE(Libs) INSERT_VARIABLE(LibDirs) + INSERT_VARIABLE(OutputDir) INSERT_VARIABLE(OutputExtension) INSERT_VARIABLE(OutputName) INSERT_VARIABLE(OutputPrefixOverride) INSERT_VARIABLE(Outputs) INSERT_VARIABLE(PrecompiledHeader) INSERT_VARIABLE(PrecompiledSource) + INSERT_VARIABLE(ProductType) INSERT_VARIABLE(Public) INSERT_VARIABLE(PublicConfigs) INSERT_VARIABLE(PublicDeps) diff --git a/chromium/tools/gn/variables.h b/chromium/tools/gn/variables.h index 08fea1ab82b..0aaa8e09a8d 100644 --- a/chromium/tools/gn/variables.h +++ b/chromium/tools/gn/variables.h @@ -79,6 +79,10 @@ extern const char kAllowCircularIncludesFrom[]; extern const char kAllowCircularIncludesFrom_HelpShort[]; extern const char kAllowCircularIncludesFrom_Help[]; +extern const char kArflags[]; +extern const char kArflags_HelpShort[]; +extern const char kArflags_Help[]; + extern const char kArgs[]; extern const char kArgs_HelpShort[]; extern const char kArgs_Help[]; @@ -183,6 +187,10 @@ extern const char kLibs[]; extern const char kLibs_HelpShort[]; extern const char kLibs_Help[]; +extern const char kOutputDir[]; +extern const char kOutputDir_HelpShort[]; +extern const char kOutputDir_Help[]; + extern const char kOutputExtension[]; extern const char kOutputExtension_HelpShort[]; extern const char kOutputExtension_Help[]; @@ -207,6 +215,10 @@ extern const char kPrecompiledSource[]; extern const char kPrecompiledSource_HelpShort[]; extern const char kPrecompiledSource_Help[]; +extern const char kProductType[]; +extern const char kProductType_HelpShort[]; +extern const char kProductType_Help[]; + extern const char kPublic[]; extern const char kPublic_HelpShort[]; extern const char kPublic_Help[]; diff --git a/chromium/tools/gn/visual_studio_writer.cc b/chromium/tools/gn/visual_studio_writer.cc index e0483465f2f..50d6878a5f1 100644 --- a/chromium/tools/gn/visual_studio_writer.cc +++ b/chromium/tools/gn/visual_studio_writer.cc @@ -5,13 +5,13 @@ #include "tools/gn/visual_studio_writer.h" #include <algorithm> +#include <iterator> #include <map> #include <memory> #include <set> #include <string> #include "base/logging.h" -#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "tools/gn/builder.h" @@ -180,10 +180,22 @@ VisualStudioWriter::SolutionProject::SolutionProject( const std::string& _config_platform) : SolutionEntry(_name, _path, _guid), label_dir_path(_label_dir_path), - config_platform(_config_platform) {} + config_platform(_config_platform) { + // Make sure all paths use the same drive letter case. This is especially + // important when searching for the common path prefix. + label_dir_path[0] = base::ToUpperASCII(label_dir_path[0]); +} VisualStudioWriter::SolutionProject::~SolutionProject() = default; +VisualStudioWriter::SourceFileCompileTypePair::SourceFileCompileTypePair( + const SourceFile* _file, + const char* _compile_type) + : file(_file), compile_type(_compile_type) {} + +VisualStudioWriter::SourceFileCompileTypePair::~SourceFileCompileTypePair() = + default; + VisualStudioWriter::VisualStudioWriter(const BuildSettings* build_settings, const char* config_platform, Version version) @@ -211,8 +223,6 @@ VisualStudioWriter::VisualStudioWriter(const BuildSettings* build_settings, } VisualStudioWriter::~VisualStudioWriter() { - STLDeleteContainerPointers(projects_.begin(), projects_.end()); - STLDeleteContainerPointers(folders_.begin(), folders_.end()); } // static @@ -226,18 +236,10 @@ bool VisualStudioWriter::RunAndWriteFiles(const BuildSettings* build_settings, if (dir_filters.empty()) { targets = builder->GetAllResolvedTargets(); } else { - std::vector<std::string> tokens = base::SplitString( - dir_filters, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - SourceDir root_dir = - SourceDirForCurrentDirectory(build_settings->root_path()); - std::vector<LabelPattern> filters; - for (const std::string& token : tokens) { - LabelPattern pattern = - LabelPattern::GetPattern(root_dir, Value(nullptr, token), err); - if (err->has_error()) - return false; - filters.push_back(pattern); + if (!commands::FilterPatternsFromString(build_settings, dir_filters, + &filters, err)) { + return false; } commands::FilterTargetsByPatterns(builder->GetAllResolvedTargets(), filters, @@ -281,7 +283,8 @@ bool VisualStudioWriter::RunAndWriteFiles(const BuildSettings* build_settings, // Sort projects so they appear always in the same order in solution file. // Otherwise solution file is rewritten and reloaded by Visual Studio. std::sort(writer.projects_.begin(), writer.projects_.end(), - [](const SolutionEntry* a, const SolutionEntry* b) { + [](const std::unique_ptr<SolutionProject>& a, + const std::unique_ptr<SolutionProject>& b) { return a->path < b->path; }); @@ -310,15 +313,16 @@ bool VisualStudioWriter::WriteProjectFiles(const Target* target, Err* err) { base::FilePath vcxproj_path = build_settings_->GetFullPath(target_file); std::string vcxproj_path_str = FilePathToUTF8(vcxproj_path); - projects_.push_back(new SolutionProject( + projects_.emplace_back(new SolutionProject( project_name, vcxproj_path_str, MakeGuid(vcxproj_path_str, kGuidSeedProject), FilePathToUTF8(build_settings_->GetFullPath(target->label().dir())), project_config_platform)); std::stringstream vcxproj_string_out; + SourceFileCompileTypePairs source_types; if (!WriteProjectFileContents(vcxproj_string_out, *projects_.back(), target, - err)) { + &source_types, err)) { projects_.pop_back(); return false; } @@ -331,7 +335,7 @@ bool VisualStudioWriter::WriteProjectFiles(const Target* target, Err* err) { base::FilePath filters_path = UTF8ToFilePath(vcxproj_path_str + ".filters"); std::stringstream filters_string_out; - WriteFiltersFileContents(filters_string_out, target); + WriteFiltersFileContents(filters_string_out, target, source_types); return WriteFileIfChanged(filters_path, filters_string_out.str(), err); } @@ -339,6 +343,7 @@ bool VisualStudioWriter::WriteProjectFileContents( std::ostream& out, const SolutionProject& solution_project, const Target* target, + SourceFileCompileTypePairs* source_types, Err* err) { PathOutput path_output(GetTargetOutputDir(target), build_settings_->root_path_utf8(), @@ -477,13 +482,7 @@ bool VisualStudioWriter::WriteProjectFileContents( cl_compile->SubElement("MinimalRebuild")->Text("false"); if (!options.optimization.empty()) cl_compile->SubElement("Optimization")->Text(options.optimization); - if (target->config_values().has_precompiled_headers()) { - cl_compile->SubElement("PrecompiledHeader")->Text("Use"); - cl_compile->SubElement("PrecompiledHeaderFile") - ->Text(target->config_values().precompiled_header()); - } else { - cl_compile->SubElement("PrecompiledHeader")->Text("NotUsing"); - } + cl_compile->SubElement("PrecompiledHeader")->Text("NotUsing"); { std::unique_ptr<XmlElementWriter> preprocessor_definitions = cl_compile->SubElement("PreprocessorDefinitions"); @@ -508,22 +507,25 @@ bool VisualStudioWriter::WriteProjectFileContents( { std::unique_ptr<XmlElementWriter> group = project.SubElement("ItemGroup"); - if (!target->config_values().precompiled_source().is_null()) { - group - ->SubElement( - "ClCompile", "Include", - SourceFileWriter(path_output, - target->config_values().precompiled_source())) - ->SubElement("PrecompiledHeader") - ->Text("Create"); - } + std::vector<OutputFile> tool_outputs; // Prevent reallocation in loop. for (const SourceFile& file : target->sources()) { - SourceFileType type = GetSourceFileType(file); - if (type == SOURCE_H || type == SOURCE_CPP || type == SOURCE_C) { - group->SubElement(type == SOURCE_H ? "ClInclude" : "ClCompile", - "Include", SourceFileWriter(path_output, file)); + const char* compile_type; + Toolchain::ToolType tool_type = Toolchain::TYPE_NONE; + if (target->GetOutputFilesForSource(file, &tool_type, &tool_outputs)) { + compile_type = "CustomBuild"; + std::unique_ptr<XmlElementWriter> build = group->SubElement( + compile_type, "Include", SourceFileWriter(path_output, file)); + build->SubElement("Command")->Text("call ninja.exe -C $(OutDir) " + + tool_outputs[0].value()); + build->SubElement("Outputs")->Text("$(OutDir)" + + tool_outputs[0].value()); + } else { + compile_type = "None"; + group->SubElement(compile_type, "Include", + SourceFileWriter(path_output, file)); } + source_types->push_back(SourceFileCompileTypePair(&file, compile_type)); } } @@ -558,8 +560,10 @@ bool VisualStudioWriter::WriteProjectFileContents( return true; } -void VisualStudioWriter::WriteFiltersFileContents(std::ostream& out, - const Target* target) { +void VisualStudioWriter::WriteFiltersFileContents( + std::ostream& out, + const Target* target, + const SourceFileCompileTypePairs& source_types) { out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl; XmlElementWriter project( out, "Project", @@ -585,35 +589,31 @@ void VisualStudioWriter::WriteFiltersFileContents(std::ostream& out, std::set<std::string> processed_filters; - for (const SourceFile& file : target->sources()) { - SourceFileType type = GetSourceFileType(file); - if (type == SOURCE_H || type == SOURCE_CPP || type == SOURCE_C) { - std::unique_ptr<XmlElementWriter> cl_item = files_group.SubElement( - type == SOURCE_H ? "ClInclude" : "ClCompile", "Include", - SourceFileWriter(file_path_output, file)); - - std::ostringstream target_relative_out; - filter_path_output.WriteFile(target_relative_out, file); - std::string target_relative_path = target_relative_out.str(); - ConvertPathToSystem(&target_relative_path); - base::StringPiece filter_path = FindParentDir(&target_relative_path); - - if (!filter_path.empty()) { - std::string filter_path_str = filter_path.as_string(); - while (processed_filters.find(filter_path_str) == - processed_filters.end()) { - auto it = processed_filters.insert(filter_path_str).first; - filters_group - ->SubElement("Filter", - XmlAttributes("Include", filter_path_str)) - ->SubElement("UniqueIdentifier") - ->Text(MakeGuid(filter_path_str, kGuidSeedFilter)); - filter_path_str = FindParentDir(&(*it)).as_string(); - if (filter_path_str.empty()) - break; - } - cl_item->SubElement("Filter")->Text(filter_path); + for (const auto& file_and_type : source_types) { + std::unique_ptr<XmlElementWriter> cl_item = files_group.SubElement( + file_and_type.compile_type, "Include", + SourceFileWriter(file_path_output, *file_and_type.file)); + + std::ostringstream target_relative_out; + filter_path_output.WriteFile(target_relative_out, *file_and_type.file); + std::string target_relative_path = target_relative_out.str(); + ConvertPathToSystem(&target_relative_path); + base::StringPiece filter_path = FindParentDir(&target_relative_path); + + if (!filter_path.empty()) { + std::string filter_path_str = filter_path.as_string(); + while (processed_filters.find(filter_path_str) == + processed_filters.end()) { + auto it = processed_filters.insert(filter_path_str).first; + filters_group + ->SubElement("Filter", XmlAttributes("Include", filter_path_str)) + ->SubElement("UniqueIdentifier") + ->Text(MakeGuid(filter_path_str, kGuidSeedFilter)); + filter_path_str = FindParentDir(&(*it)).as_string(); + if (filter_path_str.empty()) + break; } + cl_item->SubElement("Filter")->Text(filter_path); } } } @@ -648,14 +648,14 @@ void VisualStudioWriter::WriteSolutionFileContents( out << "# " << version_string_ << std::endl; SourceDir solution_dir(FilePathToUTF8(solution_dir_path)); - for (const SolutionEntry* folder : folders_) { + for (const std::unique_ptr<SolutionEntry>& folder : folders_) { out << "Project(\"" << kGuidTypeFolder << "\") = \"(" << folder->name << ")\", \"" << RebasePath(folder->path, solution_dir) << "\", \"" << folder->guid << "\"" << std::endl; out << "EndProject" << std::endl; } - for (const SolutionEntry* project : projects_) { + for (const std::unique_ptr<SolutionProject>& project : projects_) { out << "Project(\"" << kGuidTypeProject << "\") = \"" << project->name << "\", \"" << RebasePath(project->path, solution_dir) << "\", \"" << project->guid << "\"" << std::endl; @@ -673,7 +673,7 @@ void VisualStudioWriter::WriteSolutionFileContents( out << "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution" << std::endl; - for (const SolutionProject* project : projects_) { + for (const std::unique_ptr<SolutionProject>& project : projects_) { const std::string project_config_mode = config_mode_prefix + project->config_platform; out << "\t\t" << project->guid << '.' << config_mode @@ -688,13 +688,13 @@ void VisualStudioWriter::WriteSolutionFileContents( out << "\tEndGlobalSection" << std::endl; out << "\tGlobalSection(NestedProjects) = preSolution" << std::endl; - for (const SolutionEntry* folder : folders_) { + for (const std::unique_ptr<SolutionEntry>& folder : folders_) { if (folder->parent_folder) { out << "\t\t" << folder->guid << " = " << folder->parent_folder->guid << std::endl; } } - for (const SolutionEntry* project : projects_) { + for (const std::unique_ptr<SolutionProject>& project : projects_) { out << "\t\t" << project->guid << " = " << project->parent_folder->guid << std::endl; } @@ -708,7 +708,7 @@ void VisualStudioWriter::ResolveSolutionFolders() { // Get all project directories. Create solution folder for each directory. std::map<base::StringPiece, SolutionEntry*> processed_paths; - for (SolutionProject* project : projects_) { + for (const std::unique_ptr<SolutionProject>& project : projects_) { base::StringPiece folder_path = project->label_dir_path; if (IsSlash(folder_path[folder_path.size() - 1])) folder_path = folder_path.substr(0, folder_path.size() - 1); @@ -717,12 +717,12 @@ void VisualStudioWriter::ResolveSolutionFolders() { project->parent_folder = it->second; } else { std::string folder_path_str = folder_path.as_string(); - SolutionEntry* folder = new SolutionEntry( + std::unique_ptr<SolutionEntry> folder(new SolutionEntry( FindLastDirComponent(SourceDir(folder_path)).as_string(), - folder_path_str, MakeGuid(folder_path_str, kGuidSeedFolder)); - folders_.push_back(folder); - project->parent_folder = folder; - processed_paths[folder_path] = folder; + folder_path_str, MakeGuid(folder_path_str, kGuidSeedFolder))); + project->parent_folder = folder.get(); + processed_paths[folder_path] = folder.get(); + folders_.push_back(std::move(folder)); if (root_folder_path_.empty()) { root_folder_path_ = folder_path_str; @@ -751,38 +751,42 @@ void VisualStudioWriter::ResolveSolutionFolders() { // Create also all parent folders up to |root_folder_path_|. SolutionFolders additional_folders; - for (SolutionEntry* folder : folders_) { - if (folder->path == root_folder_path_) + for (const std::unique_ptr<SolutionEntry>& solution_folder : folders_) { + if (solution_folder->path == root_folder_path_) continue; + SolutionEntry* folder = solution_folder.get(); base::StringPiece parent_path; while ((parent_path = FindParentDir(&folder->path)) != root_folder_path_) { auto it = processed_paths.find(parent_path); if (it != processed_paths.end()) { folder = it->second; } else { - folder = new SolutionEntry( + std::unique_ptr<SolutionEntry> new_folder(new SolutionEntry( FindLastDirComponent(SourceDir(parent_path)).as_string(), parent_path.as_string(), - MakeGuid(parent_path.as_string(), kGuidSeedFolder)); - additional_folders.push_back(folder); - processed_paths[parent_path] = folder; + MakeGuid(parent_path.as_string(), kGuidSeedFolder))); + processed_paths[parent_path] = new_folder.get(); + folder = new_folder.get(); + additional_folders.push_back(std::move(new_folder)); } } } - folders_.insert(folders_.end(), additional_folders.begin(), - additional_folders.end()); + folders_.insert(folders_.end(), + std::make_move_iterator(additional_folders.begin()), + std::make_move_iterator(additional_folders.end())); // Sort folders by path. std::sort(folders_.begin(), folders_.end(), - [](const SolutionEntry* a, const SolutionEntry* b) { + [](const std::unique_ptr<SolutionEntry>& a, + const std::unique_ptr<SolutionEntry>& b) { return a->path < b->path; }); // Match subfolders with their parents. Since |folders_| are sorted by path we // know that parent folder always precedes its children in vector. - SolutionFolders parents; - for (SolutionEntry* folder : folders_) { + std::vector<SolutionEntry*> parents; + for (const std::unique_ptr<SolutionEntry>& folder : folders_) { while (!parents.empty()) { if (base::StartsWith(folder->path, parents.back()->path, base::CompareCase::SENSITIVE)) { @@ -792,7 +796,7 @@ void VisualStudioWriter::ResolveSolutionFolders() { parents.pop_back(); } } - parents.push_back(folder); + parents.push_back(folder.get()); } } diff --git a/chromium/tools/gn/visual_studio_writer.h b/chromium/tools/gn/visual_studio_writer.h index 5b578ed3cba..99c537075ff 100644 --- a/chromium/tools/gn/visual_studio_writer.h +++ b/chromium/tools/gn/visual_studio_writer.h @@ -6,6 +6,7 @@ #define TOOLS_GN_VISUAL_STUDIO_WRITER_H_ #include <iosfwd> +#include <memory> #include <string> #include <vector> @@ -20,6 +21,7 @@ class FilePath; class Builder; class BuildSettings; class Err; +class SourceFile; class Target; class VisualStudioWriter { @@ -77,8 +79,19 @@ class VisualStudioWriter { std::string config_platform; }; - using SolutionProjects = std::vector<SolutionProject*>; - using SolutionFolders = std::vector<SolutionEntry*>; + struct SourceFileCompileTypePair { + SourceFileCompileTypePair(const SourceFile* file, const char* compile_type); + ~SourceFileCompileTypePair(); + + // Source file. + const SourceFile* file; + // Compile type string. + const char* compile_type; + }; + + using SolutionProjects = std::vector<std::unique_ptr<SolutionProject>>; + using SolutionFolders = std::vector<std::unique_ptr<SolutionEntry>>; + using SourceFileCompileTypePairs = std::vector<SourceFileCompileTypePair>; VisualStudioWriter(const BuildSettings* build_settings, const char* config_platform, @@ -89,8 +102,11 @@ class VisualStudioWriter { bool WriteProjectFileContents(std::ostream& out, const SolutionProject& solution_project, const Target* target, + SourceFileCompileTypePairs* source_types, Err* err); - void WriteFiltersFileContents(std::ostream& out, const Target* target); + void WriteFiltersFileContents(std::ostream& out, + const Target* target, + const SourceFileCompileTypePairs& source_types); bool WriteSolutionFile(const std::string& sln_name, Err* err); void WriteSolutionFileContents(std::ostream& out, const base::FilePath& solution_dir_path); diff --git a/chromium/tools/gn/visual_studio_writer_unittest.cc b/chromium/tools/gn/visual_studio_writer_unittest.cc index d70117fd0c2..f89c1c193f3 100644 --- a/chromium/tools/gn/visual_studio_writer_unittest.cc +++ b/chromium/tools/gn/visual_studio_writer_unittest.cc @@ -4,6 +4,7 @@ #include "tools/gn/visual_studio_writer.h" +#include "base/strings/string_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "tools/gn/test_with_scope.h" #include "tools/gn/visual_studio_utils.h" @@ -31,22 +32,22 @@ TEST_F(VisualStudioWriterTest, ResolveSolutionFolders) { std::string path = MakeTestPath("/foo/chromium/src/out/Debug/obj/base/base.vcxproj"); - writer.projects_.push_back(new VisualStudioWriter::SolutionProject( + writer.projects_.emplace_back(new VisualStudioWriter::SolutionProject( "base", path, MakeGuid(path, "project"), MakeTestPath("/foo/chromium/src/base"), "Win32")); path = MakeTestPath("/foo/chromium/src/out/Debug/obj/tools/gn/gn.vcxproj"); - writer.projects_.push_back(new VisualStudioWriter::SolutionProject( + writer.projects_.emplace_back(new VisualStudioWriter::SolutionProject( "gn", path, MakeGuid(path, "project"), MakeTestPath("/foo/chromium/src/tools/gn"), "Win32")); path = MakeTestPath("/foo/chromium/src/out/Debug/obj/chrome/chrome.vcxproj"); - writer.projects_.push_back(new VisualStudioWriter::SolutionProject( + writer.projects_.emplace_back(new VisualStudioWriter::SolutionProject( "chrome", path, MakeGuid(path, "project"), MakeTestPath("/foo/chromium/src/chrome"), "Win32")); path = MakeTestPath("/foo/chromium/src/out/Debug/obj/base/bar.vcxproj"); - writer.projects_.push_back(new VisualStudioWriter::SolutionProject( + writer.projects_.emplace_back(new VisualStudioWriter::SolutionProject( "bar", path, MakeGuid(path, "project"), MakeTestPath("/foo/chromium/src/base"), "Win32")); @@ -71,12 +72,12 @@ TEST_F(VisualStudioWriterTest, ResolveSolutionFolders) { ASSERT_EQ("gn", writer.folders_[3]->name); ASSERT_EQ(MakeTestPath("/foo/chromium/src/tools/gn"), writer.folders_[3]->path); - ASSERT_EQ(writer.folders_[2], writer.folders_[3]->parent_folder); + ASSERT_EQ(writer.folders_[2].get(), writer.folders_[3]->parent_folder); - ASSERT_EQ(writer.folders_[0], writer.projects_[0]->parent_folder); - ASSERT_EQ(writer.folders_[3], writer.projects_[1]->parent_folder); - ASSERT_EQ(writer.folders_[1], writer.projects_[2]->parent_folder); - ASSERT_EQ(writer.folders_[0], writer.projects_[3]->parent_folder); + ASSERT_EQ(writer.folders_[0].get(), writer.projects_[0]->parent_folder); + ASSERT_EQ(writer.folders_[3].get(), writer.projects_[1]->parent_folder); + ASSERT_EQ(writer.folders_[1].get(), writer.projects_[2]->parent_folder); + ASSERT_EQ(writer.folders_[0].get(), writer.projects_[3]->parent_folder); } TEST_F(VisualStudioWriterTest, ResolveSolutionFolders_AbsPath) { @@ -85,26 +86,30 @@ TEST_F(VisualStudioWriterTest, ResolveSolutionFolders_AbsPath) { std::string path = MakeTestPath("/foo/chromium/src/out/Debug/obj/base/base.vcxproj"); - writer.projects_.push_back(new VisualStudioWriter::SolutionProject( + writer.projects_.emplace_back(new VisualStudioWriter::SolutionProject( "base", path, MakeGuid(path, "project"), MakeTestPath("/foo/chromium/src/base"), "Win32")); path = MakeTestPath("/foo/chromium/src/out/Debug/obj/tools/gn/gn.vcxproj"); - writer.projects_.push_back(new VisualStudioWriter::SolutionProject( + writer.projects_.emplace_back(new VisualStudioWriter::SolutionProject( "gn", path, MakeGuid(path, "project"), MakeTestPath("/foo/chromium/src/tools/gn"), "Win32")); path = MakeTestPath( "/foo/chromium/src/out/Debug/obj/ABS_PATH/C/foo/bar/bar.vcxproj"); - writer.projects_.push_back(new VisualStudioWriter::SolutionProject( + writer.projects_.emplace_back(new VisualStudioWriter::SolutionProject( "bar", path, MakeGuid(path, "project"), MakeTestPath("/foo/bar"), "Win32")); + std::string baz_label_dir_path = MakeTestPath("/foo/bar/baz"); +#if defined(OS_WIN) + // Make sure mixed lower and upper-case drive letters are handled properly. + baz_label_dir_path[0] = base::ToLowerASCII(baz_label_dir_path[0]); +#endif path = MakeTestPath( "/foo/chromium/src/out/Debug/obj/ABS_PATH/C/foo/bar/baz/baz.vcxproj"); - writer.projects_.push_back(new VisualStudioWriter::SolutionProject( - "baz", path, MakeGuid(path, "project"), MakeTestPath("/foo/bar/baz"), - "Win32")); + writer.projects_.emplace_back(new VisualStudioWriter::SolutionProject( + "baz", path, MakeGuid(path, "project"), baz_label_dir_path, "Win32")); writer.ResolveSolutionFolders(); @@ -118,7 +123,7 @@ TEST_F(VisualStudioWriterTest, ResolveSolutionFolders_AbsPath) { ASSERT_EQ("baz", writer.folders_[1]->name); ASSERT_EQ(MakeTestPath("/foo/bar/baz"), writer.folders_[1]->path); - ASSERT_EQ(writer.folders_[0], writer.folders_[1]->parent_folder); + ASSERT_EQ(writer.folders_[0].get(), writer.folders_[1]->parent_folder); ASSERT_EQ("chromium", writer.folders_[2]->name); ASSERT_EQ(MakeTestPath("/foo/chromium"), writer.folders_[2]->path); @@ -126,23 +131,23 @@ TEST_F(VisualStudioWriterTest, ResolveSolutionFolders_AbsPath) { ASSERT_EQ("src", writer.folders_[3]->name); ASSERT_EQ(MakeTestPath("/foo/chromium/src"), writer.folders_[3]->path); - ASSERT_EQ(writer.folders_[2], writer.folders_[3]->parent_folder); + ASSERT_EQ(writer.folders_[2].get(), writer.folders_[3]->parent_folder); ASSERT_EQ("base", writer.folders_[4]->name); ASSERT_EQ(MakeTestPath("/foo/chromium/src/base"), writer.folders_[4]->path); - ASSERT_EQ(writer.folders_[3], writer.folders_[4]->parent_folder); + ASSERT_EQ(writer.folders_[3].get(), writer.folders_[4]->parent_folder); ASSERT_EQ("tools", writer.folders_[5]->name); ASSERT_EQ(MakeTestPath("/foo/chromium/src/tools"), writer.folders_[5]->path); - ASSERT_EQ(writer.folders_[3], writer.folders_[5]->parent_folder); + ASSERT_EQ(writer.folders_[3].get(), writer.folders_[5]->parent_folder); ASSERT_EQ("gn", writer.folders_[6]->name); ASSERT_EQ(MakeTestPath("/foo/chromium/src/tools/gn"), writer.folders_[6]->path); - ASSERT_EQ(writer.folders_[5], writer.folders_[6]->parent_folder); + ASSERT_EQ(writer.folders_[5].get(), writer.folders_[6]->parent_folder); - ASSERT_EQ(writer.folders_[4], writer.projects_[0]->parent_folder); - ASSERT_EQ(writer.folders_[6], writer.projects_[1]->parent_folder); - ASSERT_EQ(writer.folders_[0], writer.projects_[2]->parent_folder); - ASSERT_EQ(writer.folders_[1], writer.projects_[3]->parent_folder); + ASSERT_EQ(writer.folders_[4].get(), writer.projects_[0]->parent_folder); + ASSERT_EQ(writer.folders_[6].get(), writer.projects_[1]->parent_folder); + ASSERT_EQ(writer.folders_[0].get(), writer.projects_[2]->parent_folder); + ASSERT_EQ(writer.folders_[1].get(), writer.projects_[3]->parent_folder); } diff --git a/chromium/tools/gn/xcode_object.cc b/chromium/tools/gn/xcode_object.cc new file mode 100644 index 00000000000..bc8994409fe --- /dev/null +++ b/chromium/tools/gn/xcode_object.cc @@ -0,0 +1,858 @@ +// Copyright 2016 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. + +#include "tools/gn/xcode_object.h" + +#include <iomanip> +#include <sstream> +#include <utility> + +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/strings/string_util.h" + +// Helper methods ------------------------------------------------------------- + +namespace { +struct IndentRules { + bool one_line; + unsigned level; +}; + +std::vector<std::unique_ptr<PBXObject>> EmptyPBXObjectVector() { + return std::vector<std::unique_ptr<PBXObject>>(); +} + +bool CharNeedEscaping(char c) { + if (base::IsAsciiAlpha(c) || base::IsAsciiDigit(c)) + return false; + if (c == '$' || c == '.' || c == '/' || c == '_') + return false; + return true; +} + +bool StringNeedEscaping(const std::string& string) { + if (string.empty()) + return true; + if (string.find("___") != std::string::npos) + return true; + + for (char c : string) { + if (CharNeedEscaping(c)) + return true; + } + return false; +} + +std::string EncodeString(const std::string& string) { + if (!StringNeedEscaping(string)) + return string; + + std::stringstream buffer; + buffer << '"'; + for (char c : string) { + if (c <= 31) { + switch (c) { + case '\a': + buffer << "\\a"; + break; + case '\b': + buffer << "\\b"; + break; + case '\t': + buffer << "\\t"; + break; + case '\n': + case '\r': + buffer << "\\n"; + break; + case '\v': + buffer << "\\v"; + break; + case '\f': + buffer << "\\f"; + break; + default: + buffer << std::hex << std::setw(4) << std::left << "\\U" + << static_cast<unsigned>(c); + break; + } + } else { + if (c == '"' || c == '\\') + buffer << '\\'; + buffer << c; + } + } + buffer << '"'; + return buffer.str(); +} + +const char* GetSourceType(const base::FilePath::StringType& ext) { + std::map<base::FilePath::StringType, const char*> extension_map = { + {FILE_PATH_LITERAL(".a"), "archive.ar"}, + {FILE_PATH_LITERAL(".app"), "wrapper.application"}, + {FILE_PATH_LITERAL(".bdic"), "file"}, + {FILE_PATH_LITERAL(".bundle"), "wrapper.cfbundle"}, + {FILE_PATH_LITERAL(".c"), "sourcecode.c.c"}, + {FILE_PATH_LITERAL(".cc"), "sourcecode.cpp.cpp"}, + {FILE_PATH_LITERAL(".cpp"), "sourcecode.cpp.cpp"}, + {FILE_PATH_LITERAL(".css"), "text.css"}, + {FILE_PATH_LITERAL(".cxx"), "sourcecode.cpp.cpp"}, + {FILE_PATH_LITERAL(".dart"), "sourcecode"}, + {FILE_PATH_LITERAL(".dylib"), "compiled.mach-o.dylib"}, + {FILE_PATH_LITERAL(".framework"), "wrapper.framework"}, + {FILE_PATH_LITERAL(".h"), "sourcecode.c.h"}, + {FILE_PATH_LITERAL(".hxx"), "sourcecode.cpp.h"}, + {FILE_PATH_LITERAL(".icns"), "image.icns"}, + {FILE_PATH_LITERAL(".java"), "sourcecode.java"}, + {FILE_PATH_LITERAL(".js"), "sourcecode.javascript"}, + {FILE_PATH_LITERAL(".kext"), "wrapper.kext"}, + {FILE_PATH_LITERAL(".m"), "sourcecode.c.objc"}, + {FILE_PATH_LITERAL(".mm"), "sourcecode.cpp.objcpp"}, + {FILE_PATH_LITERAL(".nib"), "wrapper.nib"}, + {FILE_PATH_LITERAL(".o"), "compiled.mach-o.objfile"}, + {FILE_PATH_LITERAL(".pdf"), "image.pdf"}, + {FILE_PATH_LITERAL(".pl"), "text.script.perl"}, + {FILE_PATH_LITERAL(".plist"), "text.plist.xml"}, + {FILE_PATH_LITERAL(".pm"), "text.script.perl"}, + {FILE_PATH_LITERAL(".png"), "image.png"}, + {FILE_PATH_LITERAL(".py"), "text.script.python"}, + {FILE_PATH_LITERAL(".r"), "sourcecode.rez"}, + {FILE_PATH_LITERAL(".rez"), "sourcecode.rez"}, + {FILE_PATH_LITERAL(".s"), "sourcecode.asm"}, + {FILE_PATH_LITERAL(".storyboard"), "file.storyboard"}, + {FILE_PATH_LITERAL(".strings"), "text.plist.strings"}, + {FILE_PATH_LITERAL(".swift"), "sourcecode.swift"}, + {FILE_PATH_LITERAL(".ttf"), "file"}, + {FILE_PATH_LITERAL(".xcassets"), "folder.assetcatalog"}, + {FILE_PATH_LITERAL(".xcconfig"), "text.xcconfig"}, + {FILE_PATH_LITERAL(".xcdatamodel"), "wrapper.xcdatamodel"}, + {FILE_PATH_LITERAL(".xcdatamodeld"), "wrapper.xcdatamodeld"}, + {FILE_PATH_LITERAL(".xib"), "file.xib"}, + {FILE_PATH_LITERAL(".y"), "sourcecode.yacc"}, + }; + + const auto& iter = extension_map.find(ext); + if (iter != extension_map.end()) { + return iter->second; + } + + return "text"; +} + +bool HasExplicitFileType(const base::FilePath::StringType& ext) { + return ext == FILE_PATH_LITERAL(".dart"); +} + +bool IsSourceFileForIndexing(const base::FilePath::StringType& ext) { + return ext == FILE_PATH_LITERAL(".c") || ext == FILE_PATH_LITERAL(".cc") || + ext == FILE_PATH_LITERAL(".cpp") || ext == FILE_PATH_LITERAL(".cxx") || + ext == FILE_PATH_LITERAL(".m") || ext == FILE_PATH_LITERAL(".mm"); +} + +void PrintValue(std::ostream& out, IndentRules rules, unsigned value) { + out << value; +} + +void PrintValue(std::ostream& out, IndentRules rules, const char* value) { + out << EncodeString(value); +} + +void PrintValue(std::ostream& out, + IndentRules rules, + const std::string& value) { + out << EncodeString(value); +} + +void PrintValue(std::ostream& out, IndentRules rules, const PBXObject* value) { + out << value->Reference(); +} + +template <typename ObjectClass> +void PrintValue(std::ostream& out, + IndentRules rules, + const std::unique_ptr<ObjectClass>& value) { + PrintValue(out, rules, value.get()); +} + +template <typename ValueType> +void PrintValue(std::ostream& out, + IndentRules rules, + const std::vector<ValueType>& values) { + IndentRules sub_rule{rules.one_line, rules.level + 1}; + out << "(" << (rules.one_line ? " " : "\n"); + for (const auto& value : values) { + if (!sub_rule.one_line) + out << std::string(sub_rule.level, '\t'); + + PrintValue(out, sub_rule, value); + out << "," << (rules.one_line ? " " : "\n"); + } + + if (!rules.one_line && rules.level) + out << std::string(rules.level, '\t'); + out << ")"; +} + +template <typename ValueType> +void PrintValue(std::ostream& out, + IndentRules rules, + const std::map<std::string, ValueType>& values) { + IndentRules sub_rule{rules.one_line, rules.level + 1}; + out << "{" << (rules.one_line ? " " : "\n"); + for (const auto& pair : values) { + if (!sub_rule.one_line) + out << std::string(sub_rule.level, '\t'); + + out << pair.first << " = "; + PrintValue(out, sub_rule, pair.second); + out << ";" << (rules.one_line ? " " : "\n"); + } + + if (!rules.one_line && rules.level) + out << std::string(rules.level, '\t'); + out << "}"; +} + +template <typename ValueType> +void PrintProperty(std::ostream& out, + IndentRules rules, + const char* name, + ValueType&& value) { + if (!rules.one_line && rules.level) + out << std::string(rules.level, '\t'); + + out << name << " = "; + PrintValue(out, rules, std::forward<ValueType>(value)); + out << ";" << (rules.one_line ? " " : "\n"); +} +} // namespace + +// PBXObjectClass ------------------------------------------------------------- + +const char* ToString(PBXObjectClass cls) { + switch (cls) { + case PBXAggregateTargetClass: + return "PBXAggregateTarget"; + case PBXBuildFileClass: + return "PBXBuildFile"; + case PBXFileReferenceClass: + return "PBXFileReference"; + case PBXFrameworksBuildPhaseClass: + return "PBXFrameworksBuildPhase"; + case PBXGroupClass: + return "PBXGroup"; + case PBXNativeTargetClass: + return "PBXNativeTarget"; + case PBXProjectClass: + return "PBXProject"; + case PBXShellScriptBuildPhaseClass: + return "PBXShellScriptBuildPhase"; + case PBXSourcesBuildPhaseClass: + return "PBXSourcesBuildPhase"; + case XCBuildConfigurationClass: + return "XCBuildConfiguration"; + case XCConfigurationListClass: + return "XCConfigurationList"; + } + NOTREACHED(); + return nullptr; +} + +// PBXObjectVisitor ----------------------------------------------------------- + +PBXObjectVisitor::PBXObjectVisitor() {} + +PBXObjectVisitor::~PBXObjectVisitor() {} + +// PBXObject ------------------------------------------------------------------ + +PBXObject::PBXObject() {} + +PBXObject::~PBXObject() {} + +void PBXObject::SetId(const std::string& id) { + DCHECK(id_.empty()); + DCHECK(!id.empty()); + id_.assign(id); +} + +std::string PBXObject::Reference() const { + std::string comment = Comment(); + if (comment.empty()) + return id_; + + return id_ + " /* " + comment + " */"; +} + +std::string PBXObject::Comment() const { + return Name(); +} + +void PBXObject::Visit(PBXObjectVisitor& visitor) { + visitor.Visit(this); +} + +// PBXBuildPhase -------------------------------------------------------------- + +PBXBuildPhase::PBXBuildPhase() {} + +PBXBuildPhase::~PBXBuildPhase() {} + +// PBXTarget ------------------------------------------------------------------ + +PBXTarget::PBXTarget(const std::string& name, + const std::string& shell_script, + const std::string& config_name, + const PBXAttributes& attributes) + : configurations_(new XCConfigurationList(config_name, attributes, this)), + name_(name) { + if (!shell_script.empty()) { + build_phases_.push_back( + base::WrapUnique(new PBXShellScriptBuildPhase(name, shell_script))); + } +} + +PBXTarget::~PBXTarget() {} + +std::string PBXTarget::Name() const { + return name_; +} + +void PBXTarget::Visit(PBXObjectVisitor& visitor) { + PBXObject::Visit(visitor); + configurations_->Visit(visitor); + for (const auto& build_phase : build_phases_) { + build_phase->Visit(visitor); + } +} + +// PBXAggregateTarget --------------------------------------------------------- + +PBXAggregateTarget::PBXAggregateTarget(const std::string& name, + const std::string& shell_script, + const std::string& config_name, + const PBXAttributes& attributes) + : PBXTarget(name, shell_script, config_name, attributes) {} + +PBXAggregateTarget::~PBXAggregateTarget() {} + +PBXObjectClass PBXAggregateTarget::Class() const { + return PBXAggregateTargetClass; +} + +void PBXAggregateTarget::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {false, indent + 1}; + out << indent_str << Reference() << " = {\n"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "buildConfigurationList", configurations_); + PrintProperty(out, rules, "buildPhases", build_phases_); + PrintProperty(out, rules, "dependencies", EmptyPBXObjectVector()); + PrintProperty(out, rules, "name", name_); + PrintProperty(out, rules, "productName", name_); + out << indent_str << "};\n"; +} + +// PBXBuildFile --------------------------------------------------------------- + +PBXBuildFile::PBXBuildFile(const PBXFileReference* file_reference, + const PBXSourcesBuildPhase* build_phase) + : file_reference_(file_reference), build_phase_(build_phase) { + DCHECK(file_reference_); + DCHECK(build_phase_); +} + +PBXBuildFile::~PBXBuildFile() {} + +PBXObjectClass PBXBuildFile::Class() const { + return PBXBuildFileClass; +} + +std::string PBXBuildFile::Name() const { + return file_reference_->Name() + " in " + build_phase_->Name(); +} + +void PBXBuildFile::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {true, 0}; + out << indent_str << Reference() << " = {"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "fileRef", file_reference_); + out << "};\n"; +} + +// PBXFileReference ----------------------------------------------------------- + +PBXFileReference::PBXFileReference(const std::string& name, + const std::string& path, + const std::string& type) + : name_(name), path_(path), type_(type) {} + +PBXFileReference::~PBXFileReference() {} + +PBXObjectClass PBXFileReference::Class() const { + return PBXFileReferenceClass; +} + +std::string PBXFileReference::Name() const { + return path_; +} + +void PBXFileReference::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {true, 0}; + out << indent_str << Reference() << " = {"; + PrintProperty(out, rules, "isa", ToString(Class())); + + if (!type_.empty()) { + PrintProperty(out, rules, "explicitFileType", type_); + PrintProperty(out, rules, "includeInIndex", 0u); + } else { + const base::FilePath::StringType ext = + base::FilePath::FromUTF8Unsafe(path_).Extension(); + + if (HasExplicitFileType(ext)) + PrintProperty(out, rules, "explicitFileType", GetSourceType(ext)); + else + PrintProperty(out, rules, "lastKnownFileType", GetSourceType(ext)); + } + + if (name_ != path_ && !name_.empty()) + PrintProperty(out, rules, "name", name_); + + PrintProperty(out, rules, "path", path_); + PrintProperty(out, rules, "sourceTree", + type_.empty() ? "<group>" : "BUILT_PRODUCTS_DIR"); + out << "};\n"; +} + +// PBXFrameworksBuildPhase ---------------------------------------------------- + +PBXFrameworksBuildPhase::PBXFrameworksBuildPhase() {} + +PBXFrameworksBuildPhase::~PBXFrameworksBuildPhase() {} + +PBXObjectClass PBXFrameworksBuildPhase::Class() const { + return PBXFrameworksBuildPhaseClass; +} + +std::string PBXFrameworksBuildPhase::Name() const { + return "Frameworks"; +} + +void PBXFrameworksBuildPhase::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {false, indent + 1}; + out << indent_str << Reference() << " = {\n"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "buildActionMask", 0x7fffffffu); + PrintProperty(out, rules, "files", EmptyPBXObjectVector()); + PrintProperty(out, rules, "runOnlyForDeploymentPostprocessing", 0u); + out << indent_str << "};\n"; +} + +// PBXGroup ------------------------------------------------------------------- + +PBXGroup::PBXGroup(const std::string& path, const std::string& name) + : name_(name), path_(path) {} + +PBXGroup::~PBXGroup() {} + +PBXObject* PBXGroup::AddChild(std::unique_ptr<PBXObject> child) { + DCHECK(child); + children_.push_back(std::move(child)); + return children_.back().get(); +} + +PBXFileReference* PBXGroup::AddSourceFile(const std::string& source_path) { + DCHECK(!source_path.empty()); + std::string::size_type sep = source_path.find("/"); + if (sep == std::string::npos) { + children_.push_back(base::WrapUnique( + new PBXFileReference(std::string(), source_path, std::string()))); + return static_cast<PBXFileReference*>(children_.back().get()); + } + + PBXGroup* group = nullptr; + base::StringPiece component(source_path.data(), sep); + for (const auto& child : children_) { + if (child->Class() != PBXGroupClass) + continue; + + PBXGroup* child_as_group = static_cast<PBXGroup*>(child.get()); + if (child_as_group->path_ == component) { + group = child_as_group; + break; + } + } + + if (!group) { + children_.push_back(base::WrapUnique(new PBXGroup(component.as_string()))); + group = static_cast<PBXGroup*>(children_.back().get()); + } + + DCHECK(group); + DCHECK(group->path_ == component); + return group->AddSourceFile(source_path.substr(sep + 1)); +} + +PBXObjectClass PBXGroup::Class() const { + return PBXGroupClass; +} + +std::string PBXGroup::Name() const { + if (!name_.empty()) + return name_; + if (!path_.empty()) + return path_; + return std::string(); +} + +void PBXGroup::Visit(PBXObjectVisitor& visitor) { + PBXObject::Visit(visitor); + for (const auto& child : children_) { + child->Visit(visitor); + } +} + +void PBXGroup::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {false, indent + 1}; + out << indent_str << Reference() << " = {\n"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "children", children_); + if (!name_.empty()) + PrintProperty(out, rules, "name", name_); + if (!path_.empty()) + PrintProperty(out, rules, "path", path_); + PrintProperty(out, rules, "sourceTree", "<group>"); + out << indent_str << "};\n"; +} + +// PBXNativeTarget ------------------------------------------------------------ + +PBXNativeTarget::PBXNativeTarget(const std::string& name, + const std::string& shell_script, + const std::string& config_name, + const PBXAttributes& attributes, + const std::string& product_type, + const PBXFileReference* product_reference) + : PBXTarget(name, shell_script, config_name, attributes), + product_reference_(product_reference), + product_type_(product_type) { + DCHECK(product_reference_); + build_phases_.push_back(base::WrapUnique(new PBXSourcesBuildPhase)); + source_build_phase_ = + static_cast<PBXSourcesBuildPhase*>(build_phases_.back().get()); + + build_phases_.push_back(base::WrapUnique(new PBXFrameworksBuildPhase)); +} + +PBXNativeTarget::~PBXNativeTarget() {} + +void PBXNativeTarget::AddFileForIndexing( + const PBXFileReference* file_reference) { + DCHECK(file_reference); + source_build_phase_->AddBuildFile( + base::WrapUnique(new PBXBuildFile(file_reference, source_build_phase_))); +} + +PBXObjectClass PBXNativeTarget::Class() const { + return PBXNativeTargetClass; +} + +void PBXNativeTarget::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {false, indent + 1}; + out << indent_str << Reference() << " = {\n"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "buildConfigurationList", configurations_); + PrintProperty(out, rules, "buildPhases", build_phases_); + PrintProperty(out, rules, "buildRules", EmptyPBXObjectVector()); + PrintProperty(out, rules, "dependencies", EmptyPBXObjectVector()); + PrintProperty(out, rules, "name", name_); + PrintProperty(out, rules, "productName", name_); + PrintProperty(out, rules, "productReference", product_reference_); + PrintProperty(out, rules, "productType", product_type_); + out << indent_str << "};\n"; +} + +// PBXProject ----------------------------------------------------------------- + +PBXProject::PBXProject(const std::string& name, + const std::string& config_name, + const std::string& source_path, + const PBXAttributes& attributes) + : name_(name), config_name_(config_name), target_for_indexing_(nullptr) { + attributes_["BuildIndependentTargetsInParallel"] = "YES"; + + main_group_.reset(new PBXGroup); + sources_ = static_cast<PBXGroup*>(main_group_->AddChild( + base::WrapUnique(new PBXGroup(source_path, "Source")))); + products_ = static_cast<PBXGroup*>(main_group_->AddChild( + base::WrapUnique(new PBXGroup(std::string(), "Product")))); + main_group_->AddChild(base::WrapUnique(new PBXGroup(std::string(), "Build"))); + + configurations_.reset(new XCConfigurationList(config_name, attributes, this)); +} + +PBXProject::~PBXProject() {} + +void PBXProject::AddSourceFile(const std::string& source_path) { + PBXFileReference* file_reference = sources_->AddSourceFile(source_path); + const base::FilePath::StringType ext = + base::FilePath::FromUTF8Unsafe(source_path).Extension(); + if (!IsSourceFileForIndexing(ext)) + return; + + if (!target_for_indexing_) { + PBXAttributes attributes; + attributes["EXECUTABLE_PREFIX"] = ""; + attributes["HEADER_SEARCH_PATHS"] = sources_->path(); + attributes["PRODUCT_NAME"] = name_; + + PBXFileReference* product_reference = static_cast<PBXFileReference*>( + products_->AddChild(base::WrapUnique(new PBXFileReference( + std::string(), name_, "compiled.mach-o.executable")))); + + const char product_type[] = "com.apple.product-type.tool"; + targets_.push_back(base::WrapUnique( + new PBXNativeTarget(name_, std::string(), config_name_, attributes, + product_type, product_reference))); + target_for_indexing_ = static_cast<PBXNativeTarget*>(targets_.back().get()); + } + + DCHECK(target_for_indexing_); + target_for_indexing_->AddFileForIndexing(file_reference); +} + +void PBXProject::AddAggregateTarget(const std::string& name, + const std::string& shell_script) { + PBXAttributes attributes; + attributes["CODE_SIGNING_REQUIRED"] = "NO"; + attributes["CONFIGURATION_BUILD_DIR"] = "."; + attributes["PRODUCT_NAME"] = name; + + targets_.push_back(base::WrapUnique( + new PBXAggregateTarget(name, shell_script, config_name_, attributes))); +} + +void PBXProject::AddNativeTarget(const std::string& name, + const std::string& type, + const std::string& output_name, + const std::string& output_type, + const std::string& shell_script) { + const base::FilePath::StringType ext = + base::FilePath::FromUTF8Unsafe(output_name).Extension(); + + PBXFileReference* product = static_cast<PBXFileReference*>( + products_->AddChild(base::WrapUnique(new PBXFileReference( + name, output_name, type.empty() ? GetSourceType(ext) : type)))); + + PBXAttributes attributes; + attributes["CODE_SIGNING_REQUIRED"] = "NO"; + attributes["CONFIGURATION_BUILD_DIR"] = "."; + attributes["PRODUCT_NAME"] = name; + + targets_.push_back(base::WrapUnique(new PBXNativeTarget( + name, shell_script, config_name_, attributes, output_type, product))); +} + +void PBXProject::SetProjectDirPath(const std::string& project_dir_path) { + DCHECK(!project_dir_path.empty()); + project_dir_path_.assign(project_dir_path); +} + +void PBXProject::SetProjectRoot(const std::string& project_root) { + DCHECK(!project_root.empty()); + project_root_.assign(project_root); +} + +void PBXProject::AddTarget(std::unique_ptr<PBXTarget> target) { + DCHECK(target); + targets_.push_back(std::move(target)); +} + +PBXObjectClass PBXProject::Class() const { + return PBXProjectClass; +} + +std::string PBXProject::Name() const { + return name_; +} + +std::string PBXProject::Comment() const { + return "Project object"; +} + +void PBXProject::Visit(PBXObjectVisitor& visitor) { + PBXObject::Visit(visitor); + configurations_->Visit(visitor); + main_group_->Visit(visitor); + for (const auto& target : targets_) { + target->Visit(visitor); + } +} + +void PBXProject::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {false, indent + 1}; + out << indent_str << Reference() << " = {\n"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "attributes", attributes_); + PrintProperty(out, rules, "buildConfigurationList", configurations_); + PrintProperty(out, rules, "compatibilityVersion", "Xcode 3.2"); + PrintProperty(out, rules, "developmentRegion", "English"); + PrintProperty(out, rules, "hasScannedForEncodings", 1u); + PrintProperty(out, rules, "knownRegions", std::vector<std::string>({"en"})); + PrintProperty(out, rules, "mainGroup", main_group_); + PrintProperty(out, rules, "projectDirPath", project_dir_path_); + PrintProperty(out, rules, "projectRoot", project_root_); + PrintProperty(out, rules, "targets", targets_); + out << indent_str << "};\n"; +} + +// PBXShellScriptBuildPhase --------------------------------------------------- + +PBXShellScriptBuildPhase::PBXShellScriptBuildPhase( + const std::string& name, + const std::string& shell_script) + : name_("Action \"Compile and copy " + name + " via ninja\""), + shell_script_(shell_script) {} + +PBXShellScriptBuildPhase::~PBXShellScriptBuildPhase() {} + +PBXObjectClass PBXShellScriptBuildPhase::Class() const { + return PBXShellScriptBuildPhaseClass; +} + +std::string PBXShellScriptBuildPhase::Name() const { + return name_; +} + +void PBXShellScriptBuildPhase::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {false, indent + 1}; + out << indent_str << Reference() << " = {\n"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "buildActionMask", 0x7fffffffu); + PrintProperty(out, rules, "files", EmptyPBXObjectVector()); + PrintProperty(out, rules, "inputPaths", EmptyPBXObjectVector()); + PrintProperty(out, rules, "name", name_); + PrintProperty(out, rules, "outputPaths", EmptyPBXObjectVector()); + PrintProperty(out, rules, "runOnlyForDeploymentPostprocessing", 0u); + PrintProperty(out, rules, "shellPath", "/bin/sh"); + PrintProperty(out, rules, "shellScript", shell_script_); + PrintProperty(out, rules, "showEnvVarsInLog", 0u); + out << indent_str << "};\n"; +} + +// PBXSourcesBuildPhase ------------------------------------------------------- + +PBXSourcesBuildPhase::PBXSourcesBuildPhase() {} + +PBXSourcesBuildPhase::~PBXSourcesBuildPhase() {} + +void PBXSourcesBuildPhase::AddBuildFile( + std::unique_ptr<PBXBuildFile> build_file) { + files_.push_back(std::move(build_file)); +} + +PBXObjectClass PBXSourcesBuildPhase::Class() const { + return PBXSourcesBuildPhaseClass; +} + +std::string PBXSourcesBuildPhase::Name() const { + return "Sources"; +} + +void PBXSourcesBuildPhase::Visit(PBXObjectVisitor& visitor) { + PBXBuildPhase::Visit(visitor); + for (const auto& file : files_) { + file->Visit(visitor); + } +} + +void PBXSourcesBuildPhase::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {false, indent + 1}; + out << indent_str << Reference() << " = {\n"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "buildActionMask", 0x7fffffffu); + PrintProperty(out, rules, "files", files_); + PrintProperty(out, rules, "runOnlyForDeploymentPostprocessing", 0u); + out << indent_str << "};\n"; +} + +// XCBuildConfiguration ------------------------------------------------------- + +XCBuildConfiguration::XCBuildConfiguration(const std::string& name, + const PBXAttributes& attributes) + : attributes_(attributes), name_(name) {} + +XCBuildConfiguration::~XCBuildConfiguration() {} + +PBXObjectClass XCBuildConfiguration::Class() const { + return XCBuildConfigurationClass; +} + +std::string XCBuildConfiguration::Name() const { + return name_; +} + +void XCBuildConfiguration::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {false, indent + 1}; + out << indent_str << Reference() << " = {\n"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "buildSettings", attributes_); + PrintProperty(out, rules, "name", name_); + out << indent_str << "};\n"; +} + +// XCConfigurationList -------------------------------------------------------- + +XCConfigurationList::XCConfigurationList(const std::string& name, + const PBXAttributes& attributes, + const PBXObject* owner_reference) + : owner_reference_(owner_reference) { + DCHECK(owner_reference_); + configurations_.push_back( + base::WrapUnique(new XCBuildConfiguration(name, attributes))); +} + +XCConfigurationList::~XCConfigurationList() {} + +PBXObjectClass XCConfigurationList::Class() const { + return XCConfigurationListClass; +} + +std::string XCConfigurationList::Name() const { + std::stringstream buffer; + buffer << "Build configuration list for " + << ToString(owner_reference_->Class()) << " \"" + << owner_reference_->Name() << "\""; + return buffer.str(); +} + +void XCConfigurationList::Visit(PBXObjectVisitor& visitor) { + PBXObject::Visit(visitor); + for (const auto& configuration : configurations_) { + configuration->Visit(visitor); + } +} + +void XCConfigurationList::Print(std::ostream& out, unsigned indent) const { + const std::string indent_str(indent, '\t'); + const IndentRules rules = {false, indent + 1}; + out << indent_str << Reference() << " = {\n"; + PrintProperty(out, rules, "isa", ToString(Class())); + PrintProperty(out, rules, "buildConfigurations", configurations_); + PrintProperty(out, rules, "defaultConfigurationIsVisible", 1u); + PrintProperty(out, rules, "defaultConfigurationName", + configurations_[0]->Name()); + out << indent_str << "};\n"; +} diff --git a/chromium/tools/gn/xcode_object.h b/chromium/tools/gn/xcode_object.h new file mode 100644 index 00000000000..25f2415f516 --- /dev/null +++ b/chromium/tools/gn/xcode_object.h @@ -0,0 +1,392 @@ +// Copyright 2016 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. + +#ifndef TOOLS_GN_XCODE_OBJECT_H_ +#define TOOLS_GN_XCODE_OBJECT_H_ + +#include <iosfwd> +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/macros.h" + +// Helper classes to generate Xcode project files. +// +// This code is based on gyp xcodeproj_file.py generator. It does not support +// all features of Xcode project but instead just enough to implement a hybrid +// mode where Xcode uses external scripts to perform the compilation steps. +// +// See https://chromium.googlesource.com/external/gyp/+/master/pylib/gyp/xcodeproj_file.py +// for more information on Xcode project file format. + +// PBXObjectClass ------------------------------------------------------------- + +enum PBXObjectClass { + // Those values needs to stay sorted in alphabetic order. + PBXAggregateTargetClass, + PBXBuildFileClass, + PBXFileReferenceClass, + PBXFrameworksBuildPhaseClass, + PBXGroupClass, + PBXNativeTargetClass, + PBXProjectClass, + PBXShellScriptBuildPhaseClass, + PBXSourcesBuildPhaseClass, + XCBuildConfigurationClass, + XCConfigurationListClass, +}; + +const char* ToString(PBXObjectClass cls); + +// Forward-declarations ------------------------------------------------------- + +class PBXAggregateTarget; +class PBXBuildFile; +class PBXFileReference; +class PBXBuildPhase; +class PBXFrameworksBuildPhase; +class PBXGroup; +class PBXNativeTarget; +class PBXObject; +class PBXProject; +class PBXShellScriptBuildPhase; +class PBXSourcesBuildPhase; +class PBXTarget; +class XCBuildConfiguration; +class XCConfigurationList; + +using PBXAttributes = std::map<std::string, std::string>; + +// PBXObjectVisitor ----------------------------------------------------------- + +class PBXObjectVisitor { + public: + PBXObjectVisitor(); + virtual ~PBXObjectVisitor(); + virtual void Visit(PBXObject* object) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(PBXObjectVisitor); +}; + +// PBXObject ------------------------------------------------------------------ + +class PBXObject { + public: + PBXObject(); + virtual ~PBXObject(); + + const std::string id() const { return id_; } + void SetId(const std::string& id); + + std::string Reference() const; + + virtual PBXObjectClass Class() const = 0; + virtual std::string Name() const = 0; + virtual std::string Comment() const; + virtual void Visit(PBXObjectVisitor& visitor); + virtual void Print(std::ostream& out, unsigned indent) const = 0; + + private: + std::string id_; + + DISALLOW_COPY_AND_ASSIGN(PBXObject); +}; + +// PBXBuildPhase -------------------------------------------------------------- + +class PBXBuildPhase : public PBXObject { + public: + PBXBuildPhase(); + ~PBXBuildPhase() override; + + private: + DISALLOW_COPY_AND_ASSIGN(PBXBuildPhase); +}; + +// PBXTarget ------------------------------------------------------------------ + +class PBXTarget : public PBXObject { + public: + PBXTarget(const std::string& name, + const std::string& shell_script, + const std::string& config_name, + const PBXAttributes& attributes); + ~PBXTarget() override; + + // PXBObject implementation. + std::string Name() const override; + void Visit(PBXObjectVisitor& visitor) override; + + protected: + std::unique_ptr<XCConfigurationList> configurations_; + std::vector<std::unique_ptr<PBXBuildPhase>> build_phases_; + PBXSourcesBuildPhase* source_build_phase_; + std::string name_; + + private: + DISALLOW_COPY_AND_ASSIGN(PBXTarget); +}; + +// PBXAggregateTarget --------------------------------------------------------- + +class PBXAggregateTarget : public PBXTarget { + public: + PBXAggregateTarget(const std::string& name, + const std::string& shell_script, + const std::string& config_name, + const PBXAttributes& attributes); + ~PBXAggregateTarget() override; + + // PXBObject implementation. + PBXObjectClass Class() const override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(PBXAggregateTarget); +}; + +// PBXBuildFile --------------------------------------------------------------- + +class PBXBuildFile : public PBXObject { + public: + PBXBuildFile(const PBXFileReference* file_reference, + const PBXSourcesBuildPhase* build_phase); + ~PBXBuildFile() override; + + // PXBObject implementation. + PBXObjectClass Class() const override; + std::string Name() const override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + const PBXFileReference* file_reference_; + const PBXSourcesBuildPhase* build_phase_; + + DISALLOW_COPY_AND_ASSIGN(PBXBuildFile); +}; + +// PBXFileReference ----------------------------------------------------------- + +class PBXFileReference : public PBXObject { + public: + PBXFileReference(const std::string& name, + const std::string& path, + const std::string& type); + ~PBXFileReference() override; + + // PBXObject implementation. + PBXObjectClass Class() const override; + std::string Name() const override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + std::string name_; + std::string path_; + std::string type_; + + DISALLOW_COPY_AND_ASSIGN(PBXFileReference); +}; + +// PBXFrameworksBuildPhase ---------------------------------------------------- + +class PBXFrameworksBuildPhase : public PBXBuildPhase { + public: + PBXFrameworksBuildPhase(); + ~PBXFrameworksBuildPhase() override; + + // PBXObject implementation. + PBXObjectClass Class() const override; + std::string Name() const override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(PBXFrameworksBuildPhase); +}; + +// PBXGroup ------------------------------------------------------------------- + +class PBXGroup : public PBXObject { + public: + explicit PBXGroup(const std::string& path = std::string(), + const std::string& name = std::string()); + ~PBXGroup() override; + + const std::string& path() const { return path_; } + + PBXObject* AddChild(std::unique_ptr<PBXObject> child); + PBXFileReference* AddSourceFile(const std::string& source_path); + + // PBXObject implementation. + PBXObjectClass Class() const override; + std::string Name() const override; + void Visit(PBXObjectVisitor& visitor) override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + std::vector<std::unique_ptr<PBXObject>> children_; + std::string name_; + std::string path_; + + DISALLOW_COPY_AND_ASSIGN(PBXGroup); +}; + +// PBXNativeTarget ------------------------------------------------------------ + +class PBXNativeTarget : public PBXTarget { + public: + PBXNativeTarget(const std::string& name, + const std::string& shell_script, + const std::string& config_name, + const PBXAttributes& attributes, + const std::string& product_type, + const PBXFileReference* product_reference); + ~PBXNativeTarget() override; + + void AddFileForIndexing(const PBXFileReference* file_reference); + + // PBXObject implementation. + PBXObjectClass Class() const override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + const PBXFileReference* product_reference_; + std::string product_type_; + + DISALLOW_COPY_AND_ASSIGN(PBXNativeTarget); +}; + +// PBXProject ----------------------------------------------------------------- + +class PBXProject : public PBXObject { + public: + PBXProject(const std::string& name, + const std::string& config_name, + const std::string& source_path, + const PBXAttributes& attributes); + ~PBXProject() override; + + void AddSourceFile(const std::string& source_path); + void AddAggregateTarget(const std::string& name, + const std::string& shell_script); + void AddNativeTarget(const std::string& name, + const std::string& type, + const std::string& output_name, + const std::string& output_type, + const std::string& shell_script); + + void SetProjectDirPath(const std::string& project_dir_path); + void SetProjectRoot(const std::string& project_root); + void AddTarget(std::unique_ptr<PBXTarget> target); + + // PBXObject implementation. + PBXObjectClass Class() const override; + std::string Name() const override; + std::string Comment() const override; + void Visit(PBXObjectVisitor& visitor) override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + PBXAttributes attributes_; + std::unique_ptr<XCConfigurationList> configurations_; + std::unique_ptr<PBXGroup> main_group_; + std::string project_dir_path_; + std::string project_root_; + std::vector<std::unique_ptr<PBXTarget>> targets_; + std::string name_; + std::string config_name_; + + PBXGroup* sources_; + PBXGroup* products_; + PBXNativeTarget* target_for_indexing_; + + DISALLOW_COPY_AND_ASSIGN(PBXProject); +}; + +// PBXShellScriptBuildPhase --------------------------------------------------- + +class PBXShellScriptBuildPhase : public PBXBuildPhase { + public: + PBXShellScriptBuildPhase(const std::string& name, + const std::string& shell_script); + ~PBXShellScriptBuildPhase() override; + + // PBXObject implementation. + PBXObjectClass Class() const override; + std::string Name() const override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + std::string name_; + std::string shell_script_; + + DISALLOW_COPY_AND_ASSIGN(PBXShellScriptBuildPhase); +}; + +// PBXSourcesBuildPhase ------------------------------------------------------- + +class PBXSourcesBuildPhase : public PBXBuildPhase { + public: + PBXSourcesBuildPhase(); + ~PBXSourcesBuildPhase() override; + + void AddBuildFile(std::unique_ptr<PBXBuildFile> build_file); + + // PBXObject implementation. + PBXObjectClass Class() const override; + std::string Name() const override; + void Visit(PBXObjectVisitor& visitor) override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + std::vector<std::unique_ptr<PBXBuildFile>> files_; + + DISALLOW_COPY_AND_ASSIGN(PBXSourcesBuildPhase); +}; + +// XCBuildConfiguration ------------------------------------------------------- + +class XCBuildConfiguration : public PBXObject { + public: + XCBuildConfiguration(const std::string& name, + const PBXAttributes& attributes); + ~XCBuildConfiguration() override; + + // PBXObject implementation. + PBXObjectClass Class() const override; + std::string Name() const override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + PBXAttributes attributes_; + std::string name_; + + DISALLOW_COPY_AND_ASSIGN(XCBuildConfiguration); +}; + +// XCConfigurationList -------------------------------------------------------- + +class XCConfigurationList : public PBXObject { + public: + XCConfigurationList(const std::string& name, + const PBXAttributes& attributes, + const PBXObject* owner_reference); + ~XCConfigurationList() override; + + // PBXObject implementation. + PBXObjectClass Class() const override; + std::string Name() const override; + void Visit(PBXObjectVisitor& visitor) override; + void Print(std::ostream& out, unsigned indent) const override; + + private: + std::vector<std::unique_ptr<XCBuildConfiguration>> configurations_; + const PBXObject* owner_reference_; + + DISALLOW_COPY_AND_ASSIGN(XCConfigurationList); +}; + +#endif // TOOLS_GN_XCODE_OBJECT_H_ diff --git a/chromium/tools/gn/xcode_writer.cc b/chromium/tools/gn/xcode_writer.cc new file mode 100644 index 00000000000..4168f7f068d --- /dev/null +++ b/chromium/tools/gn/xcode_writer.cc @@ -0,0 +1,432 @@ +// Copyright 2016 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. + +#include "tools/gn/xcode_writer.h" + +#include <iomanip> +#include <map> +#include <memory> +#include <sstream> +#include <string> +#include <utility> + +#include "base/environment.h" +#include "base/logging.h" +#include "base/sha1.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "tools/gn/args.h" +#include "tools/gn/build_settings.h" +#include "tools/gn/builder.h" +#include "tools/gn/commands.h" +#include "tools/gn/deps_iterator.h" +#include "tools/gn/filesystem_utils.h" +#include "tools/gn/settings.h" +#include "tools/gn/source_file.h" +#include "tools/gn/target.h" +#include "tools/gn/value.h" +#include "tools/gn/variables.h" +#include "tools/gn/xcode_object.h" + +namespace { + +XcodeWriter::TargetOsType GetTargetOs(const Args& args) { + const Value* target_os_value = args.GetArgOverride(variables::kTargetOs); + if (target_os_value) { + if (target_os_value->type() == Value::STRING) { + if (target_os_value->string_value() == "ios") + return XcodeWriter::WRITER_TARGET_OS_IOS; + } + } + return XcodeWriter::WRITER_TARGET_OS_MACOS; +} + +std::string GetArchs(const Args& args) { + const Value* target_cpu_value = args.GetArgOverride(variables::kTargetCpu); + if (target_cpu_value) { + if (target_cpu_value->type() == Value::STRING) { + if (target_cpu_value->string_value() == "x86") + return "i386"; + if (target_cpu_value->string_value() == "x64") + return "x86_64"; + if (target_cpu_value->string_value() == "arm") + return "armv7"; + if (target_cpu_value->string_value() == "armv7") + return "armv7"; + if (target_cpu_value->string_value() == "arm64") + return "armv64"; + } + } + return "x86_64"; +} + +std::string GetBuildScript(const std::string& target_name, + const std::string& build_path, + const std::string& ninja_extra_args) { + std::stringstream script; + script << "echo note: \"Compile and copy " << target_name << " via ninja\"\n" + << "exec "; + if (!build_path.empty()) + script << "env PATH=\"" << build_path << "\" "; + script << "ninja -C ."; + if (!ninja_extra_args.empty()) + script << " " << ninja_extra_args; + if (!target_name.empty()) + script << " " << target_name; + script << "\nexit 1\n"; + return script.str(); +} + +class CollectPBXObjectsPerClassHelper : public PBXObjectVisitor { + public: + CollectPBXObjectsPerClassHelper() {} + + void Visit(PBXObject* object) override { + DCHECK(object); + objects_per_class_[object->Class()].push_back(object); + } + + const std::map<PBXObjectClass, std::vector<const PBXObject*>>& + objects_per_class() const { + return objects_per_class_; + } + + private: + std::map<PBXObjectClass, std::vector<const PBXObject*>> objects_per_class_; + + DISALLOW_COPY_AND_ASSIGN(CollectPBXObjectsPerClassHelper); +}; + +std::map<PBXObjectClass, std::vector<const PBXObject*>> +CollectPBXObjectsPerClass(PBXProject* project) { + CollectPBXObjectsPerClassHelper visitor; + project->Visit(visitor); + return visitor.objects_per_class(); +} + +class RecursivelyAssignIdsHelper : public PBXObjectVisitor { + public: + RecursivelyAssignIdsHelper(const std::string& seed) + : seed_(seed), counter_(0) {} + + void Visit(PBXObject* object) override { + std::stringstream buffer; + buffer << seed_ << " " << object->Name() << " " << counter_; + std::string hash = base::SHA1HashString(buffer.str()); + DCHECK_EQ(hash.size() % 4, 0u); + + uint32_t id[3] = {0, 0, 0}; + const uint32_t* ptr = reinterpret_cast<const uint32_t*>(hash.data()); + for (size_t i = 0; i < hash.size() / 4; i++) + id[i % 3] ^= ptr[i]; + + object->SetId(base::HexEncode(id, sizeof(id))); + ++counter_; + } + + private: + std::string seed_; + int64_t counter_; + + DISALLOW_COPY_AND_ASSIGN(RecursivelyAssignIdsHelper); +}; + +void RecursivelyAssignIds(PBXProject* project) { + RecursivelyAssignIdsHelper visitor(project->Name()); + project->Visit(visitor); +} + +} // namespace + +// static +bool XcodeWriter::RunAndWriteFiles(const std::string& workspace_name, + const std::string& root_target_name, + const std::string& ninja_extra_args, + const std::string& dir_filters_string, + const BuildSettings* build_settings, + Builder* builder, + Err* err) { + const XcodeWriter::TargetOsType target_os = + GetTargetOs(build_settings->build_args()); + + PBXAttributes attributes; + switch (target_os) { + case XcodeWriter::WRITER_TARGET_OS_IOS: + attributes["SDKROOT"] = "iphoneos"; + attributes["TARGETED_DEVICE_FAMILY"] = "1,2"; + break; + case XcodeWriter::WRITER_TARGET_OS_MACOS: + attributes["ARCHS"] = GetArchs(build_settings->build_args()); + attributes["SDKROOT"] = "macosx10.11"; + break; + } + + const std::string source_path = + base::FilePath::FromUTF8Unsafe( + RebasePath("//", build_settings->build_dir())) + .StripTrailingSeparators() + .AsUTF8Unsafe(); + + std::string config_name = build_settings->build_dir() + .Resolve(base::FilePath()) + .StripTrailingSeparators() + .BaseName() + .AsUTF8Unsafe(); + DCHECK(!config_name.empty()); + + std::string::size_type separator = config_name.find('-'); + if (separator != std::string::npos) + config_name = config_name.substr(0, separator); + + std::vector<const Target*> targets; + std::vector<const Target*> all_targets = builder->GetAllResolvedTargets(); + if (!XcodeWriter::FilterTargets(build_settings, all_targets, + dir_filters_string, &targets, err)) { + return false; + } + + XcodeWriter workspace(workspace_name); + workspace.CreateProductsProject(targets, attributes, source_path, config_name, + root_target_name, ninja_extra_args, + target_os); + + workspace.CreateSourcesProject(all_targets, build_settings->build_dir(), + attributes, source_path, config_name, + target_os); + + return workspace.WriteFiles(build_settings, err); +} + +XcodeWriter::XcodeWriter(const std::string& name) : name_(name) { + if (name_.empty()) + name_.assign("all"); +} + +XcodeWriter::~XcodeWriter() {} + +// static +bool XcodeWriter::FilterTargets(const BuildSettings* build_settings, + const std::vector<const Target*>& all_targets, + const std::string& dir_filters_string, + std::vector<const Target*>* targets, + Err* err) { + // Filter targets according to the semicolon-delimited list of label patterns, + // if defined, first. + targets->reserve(all_targets.size()); + if (dir_filters_string.empty()) { + *targets = all_targets; + } else { + std::vector<LabelPattern> filters; + if (!commands::FilterPatternsFromString(build_settings, dir_filters_string, + &filters, err)) { + return false; + } + + commands::FilterTargetsByPatterns(all_targets, filters, targets); + } + + // Filter out all target of type EXECUTABLE that are direct dependency of + // a BUNDLE_DATA target (under the assumption that they will be part of a + // CREATE_BUNDLE target generating an application bundle). Sort the list + // of targets per pointer to use binary search for the removal. + std::sort(targets->begin(), targets->end()); + + for (const Target* target : all_targets) { + if (!target->settings()->is_default()) + continue; + + if (target->output_type() != Target::BUNDLE_DATA) + continue; + + for (const auto& pair : target->GetDeps(Target::DEPS_LINKED)) { + if (pair.ptr->output_type() != Target::EXECUTABLE) + continue; + + auto iter = std::lower_bound(targets->begin(), targets->end(), pair.ptr); + if (iter != targets->end() && *iter == pair.ptr) + targets->erase(iter); + } + } + + // Sort the list of targets per-label to get a consistent ordering of them + // in the generated Xcode project (and thus stability of the file generated). + std::sort(targets->begin(), targets->end(), + [](const Target* a, const Target* b) { + return a->label().name() < b->label().name(); + }); + + return true; +} + +void XcodeWriter::CreateProductsProject( + const std::vector<const Target*>& targets, + const PBXAttributes& attributes, + const std::string& source_path, + const std::string& config_name, + const std::string& root_target, + const std::string& ninja_extra_args, + TargetOsType target_os) { + std::unique_ptr<PBXProject> main_project( + new PBXProject("products", config_name, source_path, attributes)); + + std::string build_path; + std::unique_ptr<base::Environment> env(base::Environment::Create()); + env->GetVar("PATH", &build_path); + + main_project->AddAggregateTarget( + "All", GetBuildScript(root_target, build_path, ninja_extra_args)); + + for (const Target* target : targets) { + switch (target->output_type()) { + case Target::EXECUTABLE: + if (target_os == XcodeWriter::WRITER_TARGET_OS_IOS) + continue; + + main_project->AddNativeTarget( + target->label().name(), "compiled.mach-o.executable", + target->output_name().empty() ? target->label().name() + : target->output_name(), + "com.apple.product-type.tool", + GetBuildScript(target->label().name(), build_path, + ninja_extra_args)); + break; + + case Target::CREATE_BUNDLE: + if (target->bundle_data().product_type().empty()) + continue; + + main_project->AddNativeTarget( + target->label().name(), std::string(), + target->bundle_data() + .GetBundleRootDirOutput(target->settings()) + .Resolve(base::FilePath()) + .AsUTF8Unsafe(), + target->bundle_data().product_type(), + GetBuildScript(target->label().name(), build_path, + ninja_extra_args)); + break; + + default: + break; + } + } + + projects_.push_back(std::move(main_project)); +} + +void XcodeWriter::CreateSourcesProject( + const std::vector<const Target*>& targets, + const SourceDir& root_build_dir, + const PBXAttributes& attributes, + const std::string& source_path, + const std::string& config_name, + TargetOsType target_os) { + std::vector<SourceFile> sources; + for (const Target* target : targets) { + if (!target->settings()->is_default()) + continue; + + for (const SourceFile& source : target->sources()) { + if (source.is_system_absolute()) + continue; + + if (IsStringInOutputDir(root_build_dir, source.value())) + continue; + + sources.push_back(source); + } + } + + std::unique_ptr<PBXProject> sources_for_indexing( + new PBXProject("sources", config_name, source_path, attributes)); + + // Sort sources to ensure determinisn of the project file generation and + // remove duplicate reference to the source files (can happen due to the + // bundle_data targets). + std::sort(sources.begin(), sources.end()); + sources.erase(std::unique(sources.begin(), sources.end()), sources.end()); + + for (const SourceFile& source : sources) { + base::FilePath source_path = source.Resolve(base::FilePath()); + sources_for_indexing->AddSourceFile(source_path.AsUTF8Unsafe()); + } + + projects_.push_back(std::move(sources_for_indexing)); +} + +bool XcodeWriter::WriteFiles(const BuildSettings* build_settings, Err* err) { + for (const auto& project : projects_) { + if (!WriteProjectFile(build_settings, project.get(), err)) + return false; + } + + SourceFile xcworkspacedata_file = + build_settings->build_dir().ResolveRelativeFile( + Value(nullptr, name_ + ".xcworkspace/contents.xcworkspacedata"), err); + if (xcworkspacedata_file.is_null()) + return false; + + std::stringstream xcworkspacedata_string_out; + WriteWorkspaceContent(xcworkspacedata_string_out); + + return WriteFileIfChanged(build_settings->GetFullPath(xcworkspacedata_file), + xcworkspacedata_string_out.str(), err); +} + +bool XcodeWriter::WriteProjectFile(const BuildSettings* build_settings, + PBXProject* project, + Err* err) { + SourceFile pbxproj_file = build_settings->build_dir().ResolveRelativeFile( + Value(nullptr, project->Name() + ".xcodeproj/project.pbxproj"), err); + if (pbxproj_file.is_null()) + return false; + + std::stringstream pbxproj_string_out; + WriteProjectContent(pbxproj_string_out, project); + + if (!WriteFileIfChanged(build_settings->GetFullPath(pbxproj_file), + pbxproj_string_out.str(), err)) + return false; + + return true; +} + +void XcodeWriter::WriteWorkspaceContent(std::ostream& out) { + out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + << "<Workspace version = \"1.0\">\n"; + for (const auto& project : projects_) { + out << " <FileRef location = \"group:" << project->Name() + << ".xcodeproj\"></FileRef>\n"; + } + out << "</Workspace>\n"; +} + +void XcodeWriter::WriteProjectContent(std::ostream& out, PBXProject* project) { + RecursivelyAssignIds(project); + + out << "// !$*UTF8*$!\n" + << "{\n" + << "\tarchiveVersion = 1;\n" + << "\tclasses = {\n" + << "\t};\n" + << "\tobjectVersion = 46;\n" + << "\tobjects = {\n"; + + for (auto& pair : CollectPBXObjectsPerClass(project)) { + out << "\n" + << "/* Begin " << ToString(pair.first) << " section */\n"; + std::sort(pair.second.begin(), pair.second.end(), + [](const PBXObject* a, const PBXObject* b) { + return a->id() < b->id(); + }); + for (const auto& object : pair.second) { + object->Print(out, 2); + } + out << "/* End " << ToString(pair.first) << " section */\n"; + } + + out << "\t};\n" + << "\trootObject = " << project->Reference() << ";\n" + << "}\n"; +} diff --git a/chromium/tools/gn/xcode_writer.h b/chromium/tools/gn/xcode_writer.h new file mode 100644 index 00000000000..dd162c65f89 --- /dev/null +++ b/chromium/tools/gn/xcode_writer.h @@ -0,0 +1,97 @@ +// Copyright 2016 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. + +#ifndef TOOLS_GN_XCODE_WRITER_H_ +#define TOOLS_GN_XCODE_WRITER_H_ + +#include <iosfwd> +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/macros.h" + +class Builder; +class BuildSettings; +class Err; +class SourceDir; +class Target; + +using PBXAttributes = std::map<std::string, std::string>; +class PBXProject; + +class XcodeWriter { + public: + enum TargetOsType { + WRITER_TARGET_OS_IOS, + WRITER_TARGET_OS_MACOS, + }; + + // Writes Xcode workspace and project files. + // + // |workspace_name| is the optional name of the workspace file name ("all" + // is used if not specified). |root_target_name| is the name of the main + // target corresponding to building "All" (for example "gn_all" in Chromium). + // |ninja_extra_args| are additional arguments to pass to ninja invocation + // (can be used to increase limit of concurrent processes when using goma). + // |dir_filters_string| is optional semicolon-separated list of label patterns + // used to limit the set of generated projects. Only matching targets will be + // included to the workspace. On failure will populate |err| and return false. + static bool RunAndWriteFiles(const std::string& workspace_name, + const std::string& root_target_name, + const std::string& ninja_extra_args, + const std::string& dir_filters_string, + const BuildSettings* build_settings, + Builder* builder, + Err* err); + + private: + XcodeWriter(const std::string& name); + ~XcodeWriter(); + + // Filters the list of targets to only return the targets with artifacts + // usable from Xcode (mostly application bundles). On failure populate |err| + // and return false. + static bool FilterTargets(const BuildSettings* build_settings, + const std::vector<const Target*>& all_targets, + const std::string& dir_filters_string, + std::vector<const Target*>* targets, + Err* err); + + // Generate the "products.xcodeproj" project that reference all products + // (i.e. targets that have a build artefact usable from Xcode, mostly + // application bundles). + void CreateProductsProject(const std::vector<const Target*>& targets, + const PBXAttributes& attributes, + const std::string& source_path, + const std::string& config_name, + const std::string& root_target, + const std::string& ninja_extra_args, + TargetOsType target_os); + + // Generates the "sources.xcodeproj" project that reference all source + // files to allow Xcode to index them. + void CreateSourcesProject(const std::vector<const Target*>& targets, + const SourceDir& root_build_dir, + const PBXAttributes& attributes, + const std::string& source_path, + const std::string& config_name, + TargetOsType target_os); + + bool WriteFiles(const BuildSettings* build_settings, Err* err); + bool WriteProjectFile(const BuildSettings* build_settings, + PBXProject* project, + Err* err); + + void WriteWorkspaceContent(std::ostream& out); + void WriteProjectContent(std::ostream& out, PBXProject* project); + + std::string name_; + std::vector<std::unique_ptr<PBXProject>> projects_; + + DISALLOW_COPY_AND_ASSIGN(XcodeWriter); +}; + +#endif // TOOLS_GN_XCODE_WRITER_H_ diff --git a/chromium/tools/grit/OWNERS b/chromium/tools/grit/OWNERS index 5a9431a7735..40b5c310ad5 100644 --- a/chromium/tools/grit/OWNERS +++ b/chromium/tools/grit/OWNERS @@ -1,4 +1,3 @@ flackr@chromium.org -newt@chromium.org thakis@chromium.org thestig@chromium.org diff --git a/chromium/tools/grit/grit_rule.gni b/chromium/tools/grit/grit_rule.gni index 90c0b00abbf..07d8f3aebf9 100644 --- a/chromium/tools/grit/grit_rule.gni +++ b/chromium/tools/grit/grit_rule.gni @@ -159,13 +159,6 @@ if (use_nss_certs) { ] } -if (use_nss_verifier) { - grit_defines += [ - "-D", - "use_nss_verifier", - ] -} - if (use_ozone) { grit_defines += [ "-D", diff --git a/chromium/tools/gritsettings/resource_ids b/chromium/tools/gritsettings/resource_ids index b790c724ce5..5c46a2647f8 100644 --- a/chromium/tools/gritsettings/resource_ids +++ b/chromium/tools/gritsettings/resource_ids @@ -64,6 +64,9 @@ "includes": [6100], "structures": [6150], }, + "ash/wm/common/resources/ash_wm_common_resources.grd": { + "structures": [6700], + }, "ui/keyboard/keyboard_resources.grd": { "includes": [6850], }, @@ -175,6 +178,11 @@ "content/content_resources.grd": { "includes": [23950], }, + # ios_web strings and content strings must start at the same id. + # App only use one file depending on whether it is iOS or other platform. + "ios/web/ios_web_resources.grd": { + "includes": [23950], + }, "content/shell/shell_resources.grd": { "includes": [24450], }, diff --git a/chromium/tools/gyp/pylib/gyp/MSVSSettings.py b/chromium/tools/gyp/pylib/gyp/MSVSSettings.py index 4985756bdde..8ae19180ea2 100644 --- a/chromium/tools/gyp/pylib/gyp/MSVSSettings.py +++ b/chromium/tools/gyp/pylib/gyp/MSVSSettings.py @@ -592,6 +592,7 @@ _Same(_compile, 'UndefinePreprocessorDefinitions', _string_list) # /U _Same(_compile, 'UseFullPaths', _boolean) # /FC _Same(_compile, 'WholeProgramOptimization', _boolean) # /GL _Same(_compile, 'XMLDocumentationFileName', _file_name) +_Same(_compile, 'CompileAsWinRT', _boolean) # /ZW _Same(_compile, 'AssemblerOutput', _Enumeration(['NoListing', diff --git a/chromium/tools/gyp/pylib/gyp/generator/msvs.py b/chromium/tools/gyp/pylib/gyp/generator/msvs.py index bc4dfc31247..e60c0256312 100644 --- a/chromium/tools/gyp/pylib/gyp/generator/msvs.py +++ b/chromium/tools/gyp/pylib/gyp/generator/msvs.py @@ -257,6 +257,8 @@ def _ToolSetOrAppend(tools, tool_name, setting, value, only_if_unset=False): if not tools.get(tool_name): tools[tool_name] = dict() tool = tools[tool_name] + if 'CompileAsWinRT' == setting: + return if tool.get(setting): if only_if_unset: return if type(tool[setting]) == list and type(value) == list: @@ -286,6 +288,21 @@ def _ConfigFullName(config_name, config_data): return '%s|%s' % (_ConfigBaseName(config_name, platform_name), platform_name) +def _ConfigWindowsTargetPlatformVersion(config_data): + ver = config_data.get('msvs_windows_sdk_version') + + for key in [r'HKLM\Software\Microsoft\Microsoft SDKs\Windows\%s', + r'HKLM\Software\Wow6432Node\Microsoft\Microsoft SDKs\Windows\%s']: + sdk_dir = MSVSVersion._RegistryGetValue(key % ver, 'InstallationFolder') + if not sdk_dir: + continue + version = MSVSVersion._RegistryGetValue(key % ver, 'ProductVersion') or '' + # Find a matching entry in sdk_dir\include. + names = sorted([x for x in os.listdir(r'%s\include' % sdk_dir) + if x.startswith(version)], reverse=True) + return names[0] + + def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path, quote_cmd, do_setup_env): @@ -2676,6 +2693,21 @@ def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): else: properties[0].append(['ApplicationType', 'Windows Store']) + platform_name = None + msvs_windows_sdk_version = None + for configuration in spec['configurations'].itervalues(): + platform_name = platform_name or _ConfigPlatform(configuration) + msvs_windows_sdk_version = (msvs_windows_sdk_version or + _ConfigWindowsTargetPlatformVersion(configuration)) + if platform_name and msvs_windows_sdk_version: + break + + if platform_name == 'ARM': + properties[0].append(['WindowsSDKDesktopARMSupport', 'true']) + if msvs_windows_sdk_version: + properties[0].append(['WindowsTargetPlatformVersion', + str(msvs_windows_sdk_version)]) + return properties def _GetMSBuildConfigurationDetails(spec, build_file): diff --git a/chromium/tools/gyp/pylib/gyp/generator/ninja.py b/chromium/tools/gyp/pylib/gyp/generator/ninja.py index edac48dfca4..9cfc7060b5c 100644 --- a/chromium/tools/gyp/pylib/gyp/generator/ninja.py +++ b/chromium/tools/gyp/pylib/gyp/generator/ninja.py @@ -1369,7 +1369,8 @@ class NinjaWriter(object): is_command_start=not package_framework) if package_framework and not is_empty: if spec['type'] == 'shared_library' and self.xcode_settings.isIOS: - self.ninja.build(output, 'package_ios_framework', mac_bundle_depends) + self.ninja.build(output, 'package_ios_framework', mac_bundle_depends, + variables=variables) else: variables.append(('version', self.xcode_settings.GetFrameworkVersion())) self.ninja.build(output, 'package_framework', mac_bundle_depends, diff --git a/chromium/tools/gyp/pylib/gyp/generator/xcode.py b/chromium/tools/gyp/pylib/gyp/generator/xcode.py index 0e3fb9301ec..db99d6ab81e 100644 --- a/chromium/tools/gyp/pylib/gyp/generator/xcode.py +++ b/chromium/tools/gyp/pylib/gyp/generator/xcode.py @@ -77,6 +77,7 @@ generator_additional_non_configuration_keys = [ 'mac_framework_headers', 'mac_framework_private_headers', 'mac_xctest_bundle', + 'mac_xcuitest_bundle', 'xcode_create_dependents_test_runner', ] @@ -691,6 +692,7 @@ def GenerateOutput(target_list, target_dicts, data, params): 'executable+bundle': 'com.apple.product-type.application', 'loadable_module+bundle': 'com.apple.product-type.bundle', 'loadable_module+xctest': 'com.apple.product-type.bundle.unit-test', + 'loadable_module+xcuitest': 'com.apple.product-type.bundle.ui-testing', 'shared_library+bundle': 'com.apple.product-type.framework', 'executable+extension+bundle': 'com.apple.product-type.app-extension', 'executable+watch+extension+bundle': @@ -707,13 +709,19 @@ def GenerateOutput(target_list, target_dicts, data, params): type = spec['type'] is_xctest = int(spec.get('mac_xctest_bundle', 0)) + is_xcuitest = int(spec.get('mac_xcuitest_bundle', 0)) is_bundle = int(spec.get('mac_bundle', 0)) or is_xctest is_app_extension = int(spec.get('ios_app_extension', 0)) is_watchkit_extension = int(spec.get('ios_watchkit_extension', 0)) is_watch_app = int(spec.get('ios_watch_app', 0)) if type != 'none': type_bundle_key = type - if is_xctest: + if is_xcuitest: + type_bundle_key += '+xcuitest' + assert type == 'loadable_module', ( + 'mac_xcuitest_bundle targets must have type loadable_module ' + '(target %s)' % target_name) + elif is_xctest: type_bundle_key += '+xctest' assert type == 'loadable_module', ( 'mac_xctest_bundle targets must have type loadable_module ' @@ -745,6 +753,9 @@ def GenerateOutput(target_list, target_dicts, data, params): assert not is_bundle, ( 'mac_bundle targets cannot have type none (target "%s")' % target_name) + assert not is_xcuitest, ( + 'mac_xcuitest_bundle targets cannot have type none (target "%s")' % + target_name) assert not is_xctest, ( 'mac_xctest_bundle targets cannot have type none (target "%s")' % target_name) diff --git a/chromium/tools/gyp/pylib/gyp/mac_tool.py b/chromium/tools/gyp/pylib/gyp/mac_tool.py index 32aba14fe76..e33c1d1273d 100755 --- a/chromium/tools/gyp/pylib/gyp/mac_tool.py +++ b/chromium/tools/gyp/pylib/gyp/mac_tool.py @@ -405,7 +405,7 @@ class MacTool(object): self._MergePlist(merged_plist, plist) plistlib.writePlist(merged_plist, output) - def ExecCodeSignBundle(self, key, entitlements, provisioning): + def ExecCodeSignBundle(self, key, entitlements, provisioning, path, preserve): """Code sign a bundle. This function tries to code sign an iOS bundle, following the same @@ -419,11 +419,14 @@ class MacTool(object): provisioning, self._GetCFBundleIdentifier()) entitlements_path = self._InstallEntitlements( entitlements, substitutions, overrides) - subprocess.check_call([ - 'codesign', '--force', '--sign', key, '--entitlements', - entitlements_path, '--timestamp=none', os.path.join( - os.environ['TARGET_BUILD_DIR'], - os.environ['FULL_PRODUCT_NAME'])]) + + args = ['codesign', '--force', '--sign', key] + if preserve == 'True': + args.extend(['--deep', '--preserve-metadata=identifier,entitlements']) + else: + args.extend(['--entitlements', entitlements_path]) + args.extend(['--timestamp=none', path]) + subprocess.check_call(args) def _InstallProvisioningProfile(self, profile, bundle_identifier): """Installs embedded.mobileprovision into the bundle. @@ -639,7 +642,7 @@ class MacTool(object): return data def NextGreaterPowerOf2(x): - return 2**(x-1).bit_length() + return 2**(x).bit_length() def WriteHmap(output_name, filelist): """Generates a header map based on |filelist|. diff --git a/chromium/tools/gyp/pylib/gyp/win_tool.py b/chromium/tools/gyp/pylib/gyp/win_tool.py index bb6f1ea436f..1c843a0b6cf 100755 --- a/chromium/tools/gyp/pylib/gyp/win_tool.py +++ b/chromium/tools/gyp/pylib/gyp/win_tool.py @@ -116,11 +116,19 @@ class WinTool(object): env = self._GetEnv(arch) if use_separate_mspdbsrv == 'True': self._UseSeparateMspdbsrv(env, args) - link = subprocess.Popen([args[0].replace('/', '\\')] + list(args[1:]), - shell=True, - env=env, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) + if sys.platform == 'win32': + args = list(args) # *args is a tuple by default, which is read-only. + args[0] = args[0].replace('/', '\\') + # https://docs.python.org/2/library/subprocess.html: + # "On Unix with shell=True [...] if args is a sequence, the first item + # specifies the command string, and any additional items will be treated as + # additional arguments to the shell itself. That is to say, Popen does the + # equivalent of: + # Popen(['/bin/sh', '-c', args[0], args[1], ...])" + # For that reason, since going through the shell doesn't seem necessary on + # non-Windows don't do that there. + link = subprocess.Popen(args, shell=sys.platform == 'win32', env=env, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, _ = link.communicate() for line in out.splitlines(): if (not line.startswith(' Creating library ') and diff --git a/chromium/tools/gyp/pylib/gyp/xcode_emulation.py b/chromium/tools/gyp/pylib/gyp/xcode_emulation.py index 2dec19e5d6f..048511a2690 100644 --- a/chromium/tools/gyp/pylib/gyp/xcode_emulation.py +++ b/chromium/tools/gyp/pylib/gyp/xcode_emulation.py @@ -229,11 +229,15 @@ class XcodeSettings(object): self.isIOS def _IsBundle(self): - return int(self.spec.get('mac_bundle', 0)) != 0 or self._IsXCTest() + return int(self.spec.get('mac_bundle', 0)) != 0 or self._IsXCTest() or \ + self._IsXCUiTest() def _IsXCTest(self): return int(self.spec.get('mac_xctest_bundle', 0)) != 0 + def _IsXCUiTest(self): + return int(self.spec.get('mac_xcuitest_bundle', 0)) != 0 + def _IsIosAppExtension(self): return int(self.spec.get('ios_app_extension', 0)) != 0 @@ -312,7 +316,8 @@ class XcodeSettings(object): """Returns the qualified path to the bundle's plist file. E.g. Chromium.app/Contents/Info.plist. Only valid for bundles.""" assert self._IsBundle() - if self.spec['type'] in ('executable', 'loadable_module'): + if self.spec['type'] in ('executable', 'loadable_module') or \ + self.IsIosFramework(): return os.path.join(self.GetBundleContentsFolderPath(), 'Info.plist') else: return os.path.join(self.GetBundleContentsFolderPath(), @@ -332,6 +337,10 @@ class XcodeSettings(object): assert self._IsBundle(), ('ios_watch_app flag requires mac_bundle ' '(target %s)' % self.spec['target_name']) return 'com.apple.product-type.application.watchapp' + if self._IsXCUiTest(): + assert self._IsBundle(), ('mac_xcuitest_bundle flag requires mac_bundle ' + '(target %s)' % self.spec['target_name']) + return 'com.apple.product-type.bundle.ui-testing' if self._IsBundle(): return { 'executable': 'com.apple.product-type.application', @@ -839,7 +848,8 @@ class XcodeSettings(object): ldflags.append('-arch ' + archs[0]) # Xcode adds the product directory by default. - ldflags.append('-L' + product_dir) + # Rewrite -L. to -L./ to work around http://www.openradar.me/25313838 + ldflags.append('-L' + (product_dir if product_dir != '.' else './')) install_name = self.GetInstallName() if install_name and self.spec['type'] != 'loadable_module': @@ -1008,10 +1018,20 @@ class XcodeSettings(object): self.IsIosFramework()): return [] + postbuilds = [] + product_name = self.GetFullProductName() settings = self.xcode_settings[configname] + + # Xcode expects XCTests to be copied into the TEST_HOST dir. + if self._IsXCTest(): + source = os.path.join("${BUILT_PRODUCTS_DIR}", product_name) + test_host = os.path.dirname(settings.get('TEST_HOST')); + xctest_destination = os.path.join(test_host, 'PlugIns', product_name) + postbuilds.extend(['ditto %s %s' % (source, xctest_destination)]) + key = self._GetIOSCodeSignIdentityKey(settings) if not key: - return [] + return postbuilds # Warn for any unimplemented signing xcode keys. unimpl = ['OTHER_CODE_SIGN_FLAGS'] @@ -1020,11 +1040,41 @@ class XcodeSettings(object): print 'Warning: Some codesign keys not implemented, ignoring: %s' % ( ', '.join(sorted(unimpl))) - return ['%s code-sign-bundle "%s" "%s" "%s"' % ( + if self._IsXCTest(): + # For device xctests, Xcode copies two extra frameworks into $TEST_HOST. + test_host = os.path.dirname(settings.get('TEST_HOST')); + frameworks_dir = os.path.join(test_host, 'Frameworks') + platform_root = self._XcodePlatformPath(configname) + frameworks = \ + ['Developer/Library/PrivateFrameworks/IDEBundleInjection.framework', + 'Developer/Library/Frameworks/XCTest.framework'] + for framework in frameworks: + source = os.path.join(platform_root, framework) + destination = os.path.join(frameworks_dir, os.path.basename(framework)) + postbuilds.extend(['ditto %s %s' % (source, destination)]) + + # Then re-sign everything with 'preserve=True' + postbuilds.extend(['%s code-sign-bundle "%s" "%s" "%s" "%s" %s' % ( + os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, + settings.get('CODE_SIGN_ENTITLEMENTS', ''), + settings.get('PROVISIONING_PROFILE', ''), destination, True) + ]) + plugin_dir = os.path.join(test_host, 'PlugIns') + targets = [os.path.join(plugin_dir, product_name), test_host] + for target in targets: + postbuilds.extend(['%s code-sign-bundle "%s" "%s" "%s" "%s" %s' % ( + os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, + settings.get('CODE_SIGN_ENTITLEMENTS', ''), + settings.get('PROVISIONING_PROFILE', ''), target, True) + ]) + + postbuilds.extend(['%s code-sign-bundle "%s" "%s" "%s" "%s" %s' % ( os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, settings.get('CODE_SIGN_ENTITLEMENTS', ''), - settings.get('PROVISIONING_PROFILE', '')) - ] + settings.get('PROVISIONING_PROFILE', ''), + os.path.join("${BUILT_PRODUCTS_DIR}", product_name), False) + ]) + return postbuilds def _GetIOSCodeSignIdentityKey(self, settings): identity = settings.get('CODE_SIGN_IDENTITY') @@ -1379,6 +1429,7 @@ def IsMacBundle(flavor, spec): just a single file. Bundle rules do not produce a binary but also package resources into that directory.""" is_mac_bundle = int(spec.get('mac_xctest_bundle', 0)) != 0 or \ + int(spec.get('mac_xcuitest_bundle', 0)) != 0 or \ (int(spec.get('mac_bundle', 0)) != 0 and flavor == 'mac') if is_mac_bundle: diff --git a/chromium/tools/gyp/pylib/gyp/xcodeproj_file.py b/chromium/tools/gyp/pylib/gyp/xcodeproj_file.py index d08b7f77700..1bc90c7d6d8 100644 --- a/chromium/tools/gyp/pylib/gyp/xcodeproj_file.py +++ b/chromium/tools/gyp/pylib/gyp/xcodeproj_file.py @@ -2261,6 +2261,8 @@ class PBXNativeTarget(XCTarget): '', ''], 'com.apple.product-type.bundle.unit-test': ['wrapper.cfbundle', '', '.xctest'], + 'com.apple.product-type.bundle.ui-testing': ['wrapper.cfbundle', + '', '.xctest'], 'com.googlecode.gyp.xcode.bundle': ['compiled.mach-o.dylib', '', '.so'], 'com.apple.product-type.kernel-extension': ['wrapper.kext', @@ -2317,7 +2319,9 @@ class PBXNativeTarget(XCTarget): force_extension = suffix[1:] if self._properties['productType'] == \ - 'com.apple.product-type-bundle.unit.test': + 'com.apple.product-type-bundle.unit.test' or \ + self._properties['productType'] == \ + 'com.apple.product-type-bundle.ui-testing': if force_extension is None: force_extension = suffix[1:] diff --git a/chromium/tools/gyp/test/ios/framework/framework.gyp b/chromium/tools/gyp/test/ios/framework/framework.gyp index a99079226d4..2c6fdd5b272 100644 --- a/chromium/tools/gyp/test/ios/framework/framework.gyp +++ b/chromium/tools/gyp/test/ios/framework/framework.gyp @@ -10,6 +10,8 @@ 'mac_bundle': 1, 'sources': [ 'iOSFramework/iOSFramework.h', + 'iOSFramework/Thing.h', + 'iOSFramework/Thing.m', ], 'link_settings': { 'libraries': [ @@ -18,7 +20,9 @@ ], }, 'mac_framework_headers': [ + # Using two headers here tests mac_tool.py NextGreaterPowerOf2. 'iOSFramework/iOSFramework.h', + 'iOSFramework/Thing.h', ], 'mac_framework_dirs': [ '$(SDKROOT)/../../Library/Frameworks', diff --git a/chromium/tools/gyp/test/mac/xcuitest/test.gyp b/chromium/tools/gyp/test/mac/xcuitest/test.gyp new file mode 100644 index 00000000000..80cdf9032d0 --- /dev/null +++ b/chromium/tools/gyp/test/mac/xcuitest/test.gyp @@ -0,0 +1,69 @@ +# Copyright (c) 2013 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'target_defaults': { + 'xcode_settings': { + 'SDKROOT': 'iphoneos', + 'FRAMEWORK_SEARCH_PATHS': [ + '$(inherited)', + '$(DEVELOPER_FRAMEWORKS_DIR)', + ], + 'OTHER_LDFLAGS': [ + '$(inherited)', + '-ObjC', + ], + 'GCC_PREFIX_HEADER': '', + 'CLANG_ENABLE_OBJC_ARC': 'YES', + 'INFOPLIST_FILE': 'Info.plist', + }, + }, + 'targets': [ + { + 'target_name': 'testApp', + 'type': 'executable', + 'mac_bundle': 1, + 'sources': [ + 'MyAppDelegate.h', + 'MyAppDelegate.m', + 'main.m', + ], + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/Foundation.framework', + '$(SDKROOT)/System/Library/Frameworks/UIKit.framework', + ], + }, + }, + { + 'target_name': 'tests', + 'type': 'loadable_module', + 'mac_bundle': 1, + 'mac_xcuitest_bundle': 1, + 'sources': [ + 'TestCase.m', + ], + 'dependencies': [ + 'testApp', + ], + 'mac_bundle_resources': [ + 'resource.txt', + ], + 'variables': { + # This must *not* be set for xctest ui tests. + 'xctest_host': '', + }, + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/XCTest.framework', + ] + }, + 'xcode_settings': { + 'WRAPPER_EXTENSION': 'xctest', + 'TEST_TARGET_NAME': 'testApp', + }, + }, + ], +} + diff --git a/chromium/tools/gyp/test/win/compiler-flags/compile-as-winrt.gyp b/chromium/tools/gyp/test/win/compiler-flags/compile-as-winrt.gyp new file mode 100644 index 00000000000..8978e5059de --- /dev/null +++ b/chromium/tools/gyp/test/win/compiler-flags/compile-as-winrt.gyp @@ -0,0 +1,20 @@ +# Copyright (c) 2016 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'targets': [ + { + 'target_name': 'test-compile-as-winrt', + 'type': 'executable', + 'msvs_windows_sdk_version': 'v10.0', + 'msvs_settings': { + 'VCCLCompilerTool': { + 'AdditionalUsingDirectories': ['$(VCInstallDir)vcpackages;$(WindowsSdkDir)UnionMetadata;%(AdditionalUsingDirectories)'], + 'CompileAsWinRT': 'true' + } + }, + 'sources': ['compile-as-winrt.cc'] + } + ] +} diff --git a/chromium/tools/idl_parser/OWNERS b/chromium/tools/idl_parser/OWNERS new file mode 100644 index 00000000000..c5e87c09a35 --- /dev/null +++ b/chromium/tools/idl_parser/OWNERS @@ -0,0 +1,3 @@ +bashi@chromium.org +haraken@chromium.org +yukishiino@chromium.org diff --git a/chromium/tools/idl_parser/idl_parser.py b/chromium/tools/idl_parser/idl_parser.py index 45f8d7c5827..ff787a46346 100755 --- a/chromium/tools/idl_parser/idl_parser.py +++ b/chromium/tools/idl_parser/idl_parser.py @@ -554,14 +554,12 @@ class IDLParser(object): # [36] def p_StringifierRest(self, p): - """StringifierRest : AttributeRest + """StringifierRest : ReadOnly AttributeRest | ReturnType OperationRest | ';'""" if len(p) == 3: p[2].AddChildren(p[1]) p[0] = p[2] - elif p[1] != ';': - p[0] = p[1] # [37] def p_StaticMember(self, p): diff --git a/chromium/tools/imagediff/BUILD.gn b/chromium/tools/imagediff/BUILD.gn index 7688cfea54b..9273106f288 100644 --- a/chromium/tools/imagediff/BUILD.gn +++ b/chromium/tools/imagediff/BUILD.gn @@ -2,20 +2,31 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -executable("imagediff") { - output_name = "image_diff" # Different than dir nam for historical reasons. - sources = [ - "image_diff.cc", - "image_diff_png.cc", - "image_diff_png.h", - ] +import("//build/symlink.gni") - configs += [ "//build/config/compiler:wexit_time_destructors" ] +if (current_toolchain == host_toolchain) { + executable("imagediff") { + output_name = "image_diff" # Different than dir nam for historical reasons. + sources = [ + "image_diff.cc", + "image_diff_png.cc", + "image_diff_png.h", + ] - deps = [ - "//base", - "//build/config/sanitizers:deps", - "//third_party/libpng", - "//third_party/zlib", - ] + configs += [ "//build/config/compiler:wexit_time_destructors" ] + + deps = [ + "//base", + "//build/config/sanitizers:deps", + "//build/win:default_exe_manifest", + "//third_party/libpng", + "//third_party/zlib", + ] + } +} else { + # Aliases for compatibility with GYP. + binary_symlink("imagediff") { + binary_label = ":$target_name($host_toolchain)" + binary_output_name = "image_diff" + } } diff --git a/chromium/tools/include_tracer.py b/chromium/tools/include_tracer.py index 567a79765f8..30061d79a6b 100755 --- a/chromium/tools/include_tracer.py +++ b/chromium/tools/include_tracer.py @@ -112,7 +112,6 @@ INCLUDE_PATHS = [ 'third_party/WebKit/Source/public', 'third_party/WebKit/Source/web', 'third_party/WebKit/Source/wtf', - 'third_party/cld', 'third_party/google_toolbox_for_mac/src', 'third_party/icu/public/common', 'third_party/icu/public/i18n', diff --git a/chromium/tools/ipc_fuzzer/BUILD.gn b/chromium/tools/ipc_fuzzer/BUILD.gn new file mode 100644 index 00000000000..ce31589d31e --- /dev/null +++ b/chromium/tools/ipc_fuzzer/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright 2016 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. + +import("//tools/ipc_fuzzer/ipc_fuzzer.gni") + +config("ipc_fuzzer_config") { + defines = [ "ENABLE_IPC_FUZZER" ] +} + +config("ipc_fuzzer_tool_config") { + if (is_win) { + cflags = [ "/wd4366" ] + } + defines = [ + "ENABLE_IPC_FUZZER", + "USE_CUPS", + ] + include_dirs = [ "." ] +} + +if (enable_ipc_fuzzer) { + assert(!is_component_build, "IPC fuzzer does not support component builds.") + + group("ipc_fuzzer_all") { + deps = [ + "//tools/ipc_fuzzer/fuzzer:ipc_fuzzer", + "//tools/ipc_fuzzer/message_dump:ipc_message_dump", + "//tools/ipc_fuzzer/message_replay:ipc_fuzzer_replay", + "//tools/ipc_fuzzer/message_tools:ipc_message_list", + "//tools/ipc_fuzzer/message_tools:ipc_message_util", + ] + } +} else { + group("ipc_fuzzer_all") { + } +} diff --git a/chromium/tools/ipc_fuzzer/fuzzer/BUILD.gn b/chromium/tools/ipc_fuzzer/fuzzer/BUILD.gn new file mode 100644 index 00000000000..6a1dc836fee --- /dev/null +++ b/chromium/tools/ipc_fuzzer/fuzzer/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright 2016 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. + +import("//build/config/sanitizers/sanitizers.gni") + +executable("ipc_fuzzer") { + configs += [ "//tools/ipc_fuzzer:ipc_fuzzer_tool_config" ] + sources = [ + "fuzzer.cc", + "fuzzer.h", + "fuzzer_main.cc", + "generator.cc", + "generator.h", + "mutator.cc", + "mutator.h", + "rand_util.cc", + "rand_util.h", + ] + deps = [ + "//tools/ipc_fuzzer/message_lib:ipc_message_lib", + ] + if (is_asan && is_chromeos) { + # Compiling fuzzer.cc with ASan takes too long, see + # http://crbug.com/360158. + config -= [ "//build/config/sanitizers:default_sanitizer_flags" ] + } +} diff --git a/chromium/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/chromium/tools/ipc_fuzzer/fuzzer/fuzzer.cc index c1fb9d2e446..8f970dfe5be 100644 --- a/chromium/tools/ipc_fuzzer/fuzzer/fuzzer.cc +++ b/chromium/tools/ipc_fuzzer/fuzzer/fuzzer.cc @@ -1253,17 +1253,6 @@ struct FuzzTraits<gpu::MailboxHolder> { }; template <> -struct FuzzTraits<gpu::ValueState> { - static bool Fuzz(gpu::ValueState* p, Fuzzer* fuzzer) { - if (!FuzzParamArray(&p->float_value[0], 4, fuzzer)) - return false; - if (!FuzzParamArray(&p->int_value[0], 4, fuzzer)) - return false; - return true; - } -}; - -template <> struct FuzzTraits<GURL> { static bool Fuzz(GURL* p, Fuzzer* fuzzer) { if (!fuzzer->ShouldGenerate()) { @@ -1481,15 +1470,27 @@ struct FuzzTraits<net::HostPortPair> { }; template <> +struct FuzzTraits<net::IPAddress> { + static bool Fuzz(net::IPAddress* p, Fuzzer* fuzzer) { + std::vector<uint8_t> bytes = p->bytes(); + if (!FuzzParam(&bytes, fuzzer)) + return false; + net::IPAddress ip_address(bytes); + *p = ip_address; + return true; + } +}; + +template <> struct FuzzTraits<net::IPEndPoint> { static bool Fuzz(net::IPEndPoint* p, Fuzzer* fuzzer) { - net::IPAddressNumber address_number = p->address().bytes(); + net::IPAddress ip_address = p->address(); int port = p->port(); - if (!FuzzParam(&address_number, fuzzer)) + if (!FuzzParam(&ip_address, fuzzer)) return false; if (!FuzzParam(&port, fuzzer)) return false; - net::IPEndPoint ip_endpoint(address_number, port); + net::IPEndPoint ip_endpoint(ip_address, port); *p = ip_endpoint; return true; } diff --git a/chromium/tools/ipc_fuzzer/ipc_fuzzer.gni b/chromium/tools/ipc_fuzzer/ipc_fuzzer.gni new file mode 100644 index 00000000000..f4f41ac523e --- /dev/null +++ b/chromium/tools/ipc_fuzzer/ipc_fuzzer.gni @@ -0,0 +1,16 @@ +# Copyright 2016 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. + +import("//build/config/chrome_build.gni") +import("//build/config/chromecast_build.gni") +import("//build/config/sanitizers/sanitizers.gni") + +declare_args() { + # Build IPC fuzzer by default if it's a supported configuration. For + # sanitizer builds, this needs to be enabled explicitly as they can be slow + # (especially MSan). + enable_ipc_fuzzer = + is_clang && !is_component_build && !is_official_build && !is_chromecast && + !using_sanitizer && (is_linux || is_mac || is_win) +} diff --git a/chromium/tools/ipc_fuzzer/message_dump/BUILD.gn b/chromium/tools/ipc_fuzzer/message_dump/BUILD.gn new file mode 100644 index 00000000000..756652cbf9b --- /dev/null +++ b/chromium/tools/ipc_fuzzer/message_dump/BUILD.gn @@ -0,0 +1,13 @@ +# Copyright 2016 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. + +loadable_module("ipc_message_dump") { + configs += [ "//tools/ipc_fuzzer:ipc_fuzzer_tool_config" ] + deps = [ + "//tools/ipc_fuzzer/message_lib:ipc_message_lib", + ] + sources = [ + "message_dump.cc", + ] +} diff --git a/chromium/tools/ipc_fuzzer/message_lib/BUILD.gn b/chromium/tools/ipc_fuzzer/message_lib/BUILD.gn new file mode 100644 index 00000000000..f6a20169cc2 --- /dev/null +++ b/chromium/tools/ipc_fuzzer/message_lib/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright 2016 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. + +import("//build/config/features.gni") + +static_library("ipc_message_lib") { + configs += [ "//tools/ipc_fuzzer:ipc_fuzzer_tool_config" ] + public_deps = [ + "//base", + "//chrome/common", + "//chrome/common/safe_browsing:proto", + "//components/content_settings/content/common", + "//components/network_hints/common", + "//components/page_load_metrics/common", + "//components/pdf/common", + "//components/tracing", + "//content/child", + "//content/public/child", + "//ipc", + "//media/cast:net", + "//ppapi/proxy:ipc", + "//skia", + "//third_party/WebKit/public:blink", + "//third_party/WebKit/public:blink_headers", + "//third_party/libjingle", + "//third_party/mt19937ar", + "//ui/accessibility:ax_gen", + ] + sources = [ + "all_messages.h", + "message_cracker.h", + "message_file.h", + "message_file_format.h", + "message_file_reader.cc", + "message_file_writer.cc", + "message_names.cc", + "message_names.h", + ] + + if (enable_nacl) { + public_deps += [ "//components/nacl/common" ] + } +} diff --git a/chromium/tools/ipc_fuzzer/message_lib/DEPS b/chromium/tools/ipc_fuzzer/message_lib/DEPS index b2aa99957dd..46cdff245d7 100644 --- a/chromium/tools/ipc_fuzzer/message_lib/DEPS +++ b/chromium/tools/ipc_fuzzer/message_lib/DEPS @@ -5,6 +5,7 @@ include_rules = [ "+components/dns_prefetch/common", "+components/nacl/common", "+components/network_hints/common", + "+components/page_load_metrics/common", "+components/password_manager/content/common", "+components/pdf/common", "+components/tracing", diff --git a/chromium/tools/ipc_fuzzer/message_lib/all_messages.h b/chromium/tools/ipc_fuzzer/message_lib/all_messages.h index cc601787f88..6cead53f176 100644 --- a/chromium/tools/ipc_fuzzer/message_lib/all_messages.h +++ b/chromium/tools/ipc_fuzzer/message_lib/all_messages.h @@ -19,7 +19,7 @@ #include "components/content_settings/content/common/content_settings_message_generator.h" #include "components/nacl/common/nacl_host_messages.h" #include "components/network_hints/common/network_hints_message_generator.h" -#include "components/password_manager/content/common/credential_manager_message_generator.h" +#include "components/page_load_metrics/common/page_load_metrics_messages.h" #include "components/pdf/common/pdf_message_generator.h" #include "components/tracing/tracing_messages.h" #include "components/translate/content/common/translate_messages.h" diff --git a/chromium/tools/ipc_fuzzer/message_lib/message_lib.gyp b/chromium/tools/ipc_fuzzer/message_lib/message_lib.gyp index 56ccce07f3b..cf9d18beb33 100644 --- a/chromium/tools/ipc_fuzzer/message_lib/message_lib.gyp +++ b/chromium/tools/ipc_fuzzer/message_lib/message_lib.gyp @@ -11,13 +11,13 @@ '../../../chrome/chrome.gyp:safe_browsing_proto', '../../../components/components.gyp:content_settings_content_common', '../../../components/components.gyp:network_hints_common', + '../../../components/components.gyp:page_load_metrics_common', '../../../components/components.gyp:pdf_common', '../../../components/nacl.gyp:nacl_common', '../../../content/content.gyp:content_child', '../../../ipc/ipc.gyp:ipc', '../../../media/cast/cast.gyp:cast_net', '../../../ppapi/ppapi_internal.gyp:ppapi_ipc', - '../../../remoting/remoting.gyp:remoting_host', '../../../skia/skia.gyp:skia', '../../../third_party/libjingle/libjingle.gyp:libjingle', '../../../third_party/mt19937ar/mt19937ar.gyp:mt19937ar', diff --git a/chromium/tools/ipc_fuzzer/message_replay/BUILD.gn b/chromium/tools/ipc_fuzzer/message_replay/BUILD.gn new file mode 100644 index 00000000000..b1ec352669a --- /dev/null +++ b/chromium/tools/ipc_fuzzer/message_replay/BUILD.gn @@ -0,0 +1,16 @@ +# Copyright 2016 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. + +executable("ipc_fuzzer_replay") { + configs += [ "//tools/ipc_fuzzer:ipc_fuzzer_tool_config" ] + deps = [ + "//ipc/mojo", + "//tools/ipc_fuzzer/message_lib:ipc_message_lib", + ] + sources = [ + "replay.cc", + "replay_process.cc", + "replay_process.h", + ] +} diff --git a/chromium/tools/ipc_fuzzer/message_replay/replay_process.cc b/chromium/tools/ipc_fuzzer/message_replay/replay_process.cc index 54b56de8f10..dcee5c77d59 100644 --- a/chromium/tools/ipc_fuzzer/message_replay/replay_process.cc +++ b/chromium/tools/ipc_fuzzer/message_replay/replay_process.cc @@ -105,8 +105,7 @@ void ReplayProcess::OpenChannel() { std::string process_type = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kProcessType); - bool should_use_mojo = process_type == switches::kRendererProcess && - content::ShouldUseMojoChannel(); + bool should_use_mojo = process_type == switches::kRendererProcess; if (should_use_mojo) { std::string token = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( diff --git a/chromium/tools/ipc_fuzzer/message_tools/BUILD.gn b/chromium/tools/ipc_fuzzer/message_tools/BUILD.gn new file mode 100644 index 00000000000..dad44ffd65a --- /dev/null +++ b/chromium/tools/ipc_fuzzer/message_tools/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright 2016 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. + +executable("ipc_message_util") { + configs += [ "//tools/ipc_fuzzer:ipc_fuzzer_tool_config" ] + deps = [ + "//third_party/re2", + "//tools/ipc_fuzzer/message_lib:ipc_message_lib", + ] + sources = [ + "message_util.cc", + ] +} + +executable("ipc_message_list") { + configs += [ "//tools/ipc_fuzzer:ipc_fuzzer_tool_config" ] + deps = [ + "//chrome/common/safe_browsing:proto", + "//tools/ipc_fuzzer/message_lib:ipc_message_lib", + ] + sources = [ + "message_list.cc", + ] +} diff --git a/chromium/tools/json_schema_compiler/cc_generator.py b/chromium/tools/json_schema_compiler/cc_generator.py index 0904e39b366..267d9fe8f10 100644 --- a/chromium/tools/json_schema_compiler/cc_generator.py +++ b/chromium/tools/json_schema_compiler/cc_generator.py @@ -43,6 +43,7 @@ class _Generator(object): .Append() .Append(self._util_cc_helper.GetIncludePath()) .Append('#include "base/logging.h"') + .Append('#include "base/memory/ptr_util.h"') .Append('#include "base/strings/string_number_conversions.h"') .Append('#include "base/strings/utf_string_conversions.h"') .Append('#include "%s/%s.h"' % @@ -317,7 +318,7 @@ class _Generator(object): c.Append('const base::DictionaryValue* dict = ' 'static_cast<const base::DictionaryValue*>(&value);') if self._generate_error_messages: - c.Append('std::set<std::string> keys;') + c.Append('std::set<std::string> keys;') for prop in type_.properties.itervalues(): c.Concat(self._InitializePropertyToDefault(prop, 'out')) for prop in type_.properties.itervalues(): @@ -508,20 +509,12 @@ class _Generator(object): # Enums cannot be wrapped with scoped_ptr, but the XXX_NONE enum value # is equal to 0. (c.Sblock('if (%s) {' % choice_var) - .Append('DCHECK(!result) << "Cannot set multiple choices for %s";' % - type_.unix_name) - .Cblock(self._CreateValueFromType('result.reset(%s);', - choice.name, - choice, - choice_var, - True)) - .Eblock('}') - ) + .Append('DCHECK(!result) << "Cannot set multiple choices for %s";' % + type_.unix_name).Cblock(self._CreateValueFromType( + 'result = %s;', choice.name, choice, choice_var, True)) + .Eblock('}')) (c.Append('DCHECK(result) << "Must set at least one choice for %s";' % - type_.unix_name) - .Append('return result;') - .Eblock('}') - ) + type_.unix_name).Append('return result;').Eblock('}')) return c def _GenerateFunction(self, function): @@ -570,7 +563,7 @@ class _Generator(object): def _CreateValueFromType(self, code, prop_name, type_, var, is_ptr=False): """Creates a base::Value given a type. Generated code passes ownership - to caller. + to caller via std::unique_ptr. var: variable or variable* @@ -624,21 +617,22 @@ class _Generator(object): if (underlying_type.property_type == PropertyType.CHOICES or underlying_type.property_type == PropertyType.OBJECT): if is_ptr: - return '(%s)->ToValue().release()' % var + return '(%s)->ToValue()' % var else: - return '(%s).ToValue().release()' % var + return '(%s).ToValue()' % var elif (underlying_type.property_type == PropertyType.ANY or underlying_type.property_type == PropertyType.FUNCTION): if is_ptr: vardot = '(%s)->' % var else: vardot = '(%s).' % var - return '%sDeepCopy()' % vardot + return '%sCreateDeepCopy()' % vardot elif underlying_type.property_type == PropertyType.ENUM: maybe_namespace = '' if type_.property_type == PropertyType.REF: maybe_namespace = '%s::' % underlying_type.namespace.unix_name - return 'new base::StringValue(%sToString(%s))' % (maybe_namespace, var) + return 'base::WrapUnique(new base::StringValue(%sToString(%s)))' % ( + maybe_namespace, var) elif underlying_type.property_type == PropertyType.BINARY: if is_ptr: vardot = var + '->' @@ -647,16 +641,16 @@ class _Generator(object): return ('base::BinaryValue::CreateWithCopiedBuffer(%sdata(),' ' %ssize())' % (vardot, vardot)) elif underlying_type.property_type == PropertyType.ARRAY: - return '%s.release()' % self._util_cc_helper.CreateValueFromArray( + return '%s' % self._util_cc_helper.CreateValueFromArray( var, is_ptr) elif underlying_type.property_type.is_fundamental: if is_ptr: var = '*%s' % var if underlying_type.property_type == PropertyType.STRING: - return 'new base::StringValue(%s)' % var + return 'base::WrapUnique(new base::StringValue(%s))' % var else: - return 'new base::FundamentalValue(%s)' % var + return 'base::WrapUnique(new base::FundamentalValue(%s))' % var else: raise NotImplementedError('Conversion of %s to base::Value not ' 'implemented' % repr(type_.type_)) @@ -840,7 +834,7 @@ class _Generator(object): if is_ptr: c.Append('%(dst_var)s.reset(new base::DictionaryValue());') elif underlying_type.property_type == PropertyType.ANY: - c.Append('%(dst_var)s.reset(%(src_var)s->DeepCopy());') + c.Append('%(dst_var)s = %(src_var)s->CreateDeepCopy();') elif underlying_type.property_type == PropertyType.ARRAY: # util_cc_helper deals with optional and required arrays (c.Append('const base::ListValue* list = NULL;') diff --git a/chromium/tools/json_schema_compiler/util.cc b/chromium/tools/json_schema_compiler/util.cc index dcb44ecb132..d1a16261d2a 100644 --- a/chromium/tools/json_schema_compiler/util.cc +++ b/chromium/tools/json_schema_compiler/util.cc @@ -160,12 +160,12 @@ void AddItemToList(const std::vector<char>& from, base::ListValue* out) { void AddItemToList(const std::unique_ptr<base::Value>& from, base::ListValue* out) { - out->Append(from->DeepCopy()); + out->Append(from->CreateDeepCopy()); } void AddItemToList(const std::unique_ptr<base::DictionaryValue>& from, base::ListValue* out) { - out->Append(static_cast<base::Value*>(from->DeepCopy())); + out->Append(from->CreateDeepCopy()); } std::string ValueTypeToString(base::Value::Type type) { diff --git a/chromium/tools/licenses.py b/chromium/tools/licenses.py index 9a6602b855a..7a77710c0c5 100755 --- a/chromium/tools/licenses.py +++ b/chromium/tools/licenses.py @@ -29,6 +29,9 @@ PRUNE_PATHS = set([ # Placeholder directory only, not third-party code. os.path.join('third_party','adobe'), + # Already covered by //third_party/android_tools. + os.path.join('third_party','android_tools_internal'), + # Apache 2.0 license. See crbug.com/140478 os.path.join('third_party','bidichecker'), @@ -42,11 +45,13 @@ PRUNE_PATHS = set([ os.path.join('build','secondary'), os.path.join('third_party','bison'), os.path.join('third_party','blanketjs'), + os.path.join('third_party','chromite'), os.path.join('third_party','cygwin'), os.path.join('third_party','gles2_conform'), os.path.join('third_party','gnu_binutils'), os.path.join('third_party','gold'), os.path.join('third_party','gperf'), + os.path.join('third_party','jarjar'), os.path.join('third_party','kasko'), os.path.join('third_party','lighttpd'), os.path.join('third_party','llvm'), @@ -56,6 +61,7 @@ PRUNE_PATHS = set([ os.path.join('third_party','pefile'), os.path.join('third_party','perl'), os.path.join('third_party','psyco_win32'), + os.path.join('third_party','pyelftools'), os.path.join('third_party','pylib'), os.path.join('third_party','pywebsocket'), os.path.join('third_party','qunit'), @@ -166,12 +172,6 @@ SPECIAL_CASES = { "URL": "http://code.google.com/p/pdfium/", "License": "BSD", }, - os.path.join('third_party', 'pdfsqueeze'): { - "Name": "pdfsqueeze", - "URL": "http://code.google.com/p/pdfsqueeze/", - "License": "Apache 2.0", - "License File": "COPYING", - }, os.path.join('third_party', 'ppapi'): { "Name": "ppapi", "URL": "http://code.google.com/p/ppapi/", @@ -298,7 +298,6 @@ KNOWN_NON_IOS_LIBRARIES = set([ os.path.join('third_party', 'mozilla'), os.path.join('third_party', 'npapi'), os.path.join('third_party', 'ots'), - os.path.join('third_party', 'pdfsqueeze'), os.path.join('third_party', 'ppapi'), os.path.join('third_party', 'qcms'), os.path.join('third_party', 're2'), diff --git a/chromium/tools/mb/mb.py b/chromium/tools/mb/mb.py index 39e810c1a67..2c16266c641 100755 --- a/chromium/tools/mb/mb.py +++ b/chromium/tools/mb/mb.py @@ -23,10 +23,18 @@ import shutil import sys import subprocess import tempfile +import traceback import urllib2 from collections import OrderedDict +CHROMIUM_SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname( + os.path.abspath(__file__)))) +sys.path = [os.path.join(CHROMIUM_SRC_DIR, 'build')] + sys.path + +import gn_helpers + + def main(args): mbw = MetaBuildWrapper() return mbw.Main(args) @@ -34,11 +42,9 @@ def main(args): class MetaBuildWrapper(object): def __init__(self): - p = os.path - d = os.path.dirname - self.chromium_src_dir = p.normpath(d(d(d(p.abspath(__file__))))) - self.default_config = p.join(self.chromium_src_dir, 'tools', 'mb', - 'mb_config.pyl') + self.chromium_src_dir = CHROMIUM_SRC_DIR + self.default_config = os.path.join(self.chromium_src_dir, 'tools', 'mb', + 'mb_config.pyl') self.executable = sys.executable self.platform = sys.platform self.sep = os.sep @@ -57,9 +63,11 @@ class MetaBuildWrapper(object): except KeyboardInterrupt: self.Print('interrupted, exiting', stream=sys.stderr) return 130 - except Exception as e: + except Exception: self.DumpInputFiles() - self.Print(str(e)) + s = traceback.format_exc() + for l in s.splitlines(): + self.Print(l) return 1 def ParseArgs(self, argv): @@ -74,8 +82,14 @@ class MetaBuildWrapper(object): default=self.default_config, help='path to config file ' '(default is //tools/mb/mb_config.pyl)') - subp.add_argument('-g', '--goma-dir', default=self.ExpandUser('~/goma'), - help='path to goma directory (default is %(default)s).') + subp.add_argument('-g', '--goma-dir', + help='path to goma directory') + subp.add_argument('--android-version-code', + help='Sets GN arg android_default_version_code and ' + 'GYP_DEFINE app_manifest_version_code') + subp.add_argument('--android-version-name', + help='Sets GN arg android_default_version_name and ' + 'GYP_DEFINE app_manifest_version_name') subp.add_argument('-n', '--dryrun', action='store_true', help='Do a dry run (i.e., do nothing, just print ' 'the commands that will run)') @@ -222,6 +236,7 @@ class MetaBuildWrapper(object): def CmdAnalyze(self): vals = self.Lookup() + self.ClobberIfNeeded(vals) if vals['type'] == 'gn': return self.RunGNAnalyze(vals) else: @@ -230,7 +245,6 @@ class MetaBuildWrapper(object): def CmdGen(self): vals = self.Lookup() self.ClobberIfNeeded(vals) - if vals['type'] == 'gn': return self.RunGNGen(vals) else: @@ -255,7 +269,9 @@ class MetaBuildWrapper(object): def CmdLookup(self): vals = self.Lookup() if vals['type'] == 'gn': - cmd = self.GNCmd('gen', '_path_', vals['gn_args']) + cmd = self.GNCmd('gen', '_path_') + gn_args = self.GNArgs(vals) + self.Print('\nWriting """\\\n%s""" to _path_/args.gn.\n' % gn_args) env = None else: cmd, env = self.GYPCmd('_path_', vals) @@ -310,9 +326,13 @@ class MetaBuildWrapper(object): for config in self.masters[master].values(): all_configs[config] = master - # Check that every referenced config actually exists. + # Check that every referenced args file or config actually exists. for config, loc in all_configs.items(): - if not config in self.configs: + if config.startswith('//'): + if not self.Exists(self.ToAbsPath(config)): + errs.append('Unknown args file "%s" referenced from "%s".' % + (config, loc)) + elif not config in self.configs: errs.append('Unknown config "%s" referenced from "%s".' % (config, loc)) @@ -451,6 +471,8 @@ class MetaBuildWrapper(object): config = self.masters[master][builder] if config == 'tbd': tbd.add(builder) + elif config.startswith('//'): + done.add(builder) else: # TODO(dpranke): Check if MB is actually running? vals = self.FlattenConfig(config) @@ -470,7 +492,7 @@ class MetaBuildWrapper(object): PrintBuilders(STAT_TBD, tbd, notes) PrintBuilders(STAT_GYP, gyp, notes) else: - self.Print(' ... done') + self.Print(' All GN!') stats[STAT_DONE] += len(done) @@ -543,11 +565,22 @@ class MetaBuildWrapper(object): if not vals: self.ReadConfigFile() config = self.ConfigFromArgs() - if not config in self.configs: - raise MBErr('Config "%s" not found in %s' % - (config, self.args.config_file)) - - vals = self.FlattenConfig(config) + if config.startswith('//'): + if not self.Exists(self.ToAbsPath(config)): + raise MBErr('args file "%s" not found' % config) + vals = { + 'args_file': config, + 'cros_passthrough': False, + 'gn_args': '', + 'gyp_crosscompile': False, + 'gyp_defines': '', + 'type': 'gn', + } + else: + if not config in self.configs: + raise MBErr('Config "%s" not found in %s' % + (config, self.args.config_file)) + vals = self.FlattenConfig(config) # Do some basic sanity checking on the config so that we # don't have to do this in every caller. @@ -574,10 +607,12 @@ class MetaBuildWrapper(object): gn_args = ' '.join(contents.get('gn_args', [])) return { - 'type': contents.get('mb_type', ''), + 'args_file': '', + 'cros_passthrough': False, 'gn_args': gn_args, - 'gyp_defines': gyp_defines, 'gyp_crosscompile': False, + 'gyp_defines': gyp_defines, + 'type': contents.get('mb_type', ''), } def ReadConfigFile(self): @@ -618,11 +653,15 @@ class MetaBuildWrapper(object): def FlattenConfig(self, config): mixins = self.configs[config] + # TODO(dpranke): We really should provide a constructor for the + # default set of values. vals = { - 'type': None, + 'args_file': '', + 'cros_passthrough': False, 'gn_args': [], 'gyp_defines': '', 'gyp_crosscompile': False, + 'type': None, } visited = [] @@ -639,8 +678,9 @@ class MetaBuildWrapper(object): visited.append(m) mixin_vals = self.mixins[m] - if 'type' in mixin_vals: - vals['type'] = mixin_vals['type'] + + if 'cros_passthrough' in mixin_vals: + vals['cros_passthrough'] = mixin_vals['cros_passthrough'] if 'gn_args' in mixin_vals: if vals['gn_args']: vals['gn_args'] += ' ' + mixin_vals['gn_args'] @@ -653,6 +693,9 @@ class MetaBuildWrapper(object): vals['gyp_defines'] += ' ' + mixin_vals['gyp_defines'] else: vals['gyp_defines'] = mixin_vals['gyp_defines'] + if 'type' in mixin_vals: + vals['type'] = mixin_vals['type'] + if 'mixins' in mixin_vals: self.FlattenMixins(mixin_vals['mixins'], vals, visited) return vals @@ -690,7 +733,14 @@ class MetaBuildWrapper(object): def RunGNGen(self, vals): build_dir = self.args.path[0] - cmd = self.GNCmd('gen', build_dir, vals['gn_args'], extra_args=['--check']) + cmd = self.GNCmd('gen', build_dir, '--check') + gn_args = self.GNArgs(vals) + + # Since GN hasn't run yet, the build directory may not even exist. + self.MaybeMakeDirectory(self.ToAbsPath(build_dir)) + + gn_args_path = self.ToAbsPath(build_dir, 'args.gn') + self.WriteFile(gn_args_path, gn_args, force_verbose=True) swarming_targets = [] if getattr(self.args, 'swarming_targets_file', None): @@ -722,10 +772,6 @@ class MetaBuildWrapper(object): ('//testing/buildbot/gn_isolate_map.pyl', err)) gn_runtime_deps_path = self.ToAbsPath(build_dir, 'runtime_deps') - - # Since GN hasn't run yet, the build directory may not even exist. - self.MaybeMakeDirectory(self.ToAbsPath(build_dir)) - self.WriteFile(gn_runtime_deps_path, '\n'.join(gn_labels) + '\n') cmd.append('--runtime-deps-list-file=%s' % gn_runtime_deps_path) @@ -736,9 +782,10 @@ class MetaBuildWrapper(object): self.Print('GN gen failed: %d' % ret) return ret + android = 'target_os="android"' in vals['gn_args'] for target in swarming_targets: - if target.endswith('_apk'): - # "_apk" targets may be either android_apk or executable. The former + if android: + # Android targets may be either android_apk or executable. The former # will result in runtime_deps associated with the stamp file, while the # latter will result in runtime_deps associated with the executable. target_name = self.GNTargetName(target) @@ -792,7 +839,7 @@ class MetaBuildWrapper(object): command, extra_files = self.GetIsolateCommand(target, vals, gn_isolate_map) label = gn_isolate_map[target_name]['label'] - cmd = self.GNCmd('desc', build_dir, extra_args=[label, 'runtime_deps']) + cmd = self.GNCmd('desc', build_dir, label, 'runtime_deps') ret, out, _ = self.Call(cmd) if ret: if out: @@ -841,22 +888,49 @@ class MetaBuildWrapper(object): isolate_path + 'd.gen.json', ) - def GNCmd(self, subcommand, path, gn_args='', extra_args=None): + def GNCmd(self, subcommand, path, *args): if self.platform == 'linux2': subdir, exe = 'linux64', 'gn' elif self.platform == 'darwin': subdir, exe = 'mac', 'gn' else: subdir, exe = 'win', 'gn.exe' + gn_path = self.PathJoin(self.chromium_src_dir, 'buildtools', subdir, exe) - cmd = [gn_path, subcommand, path] - gn_args = gn_args.replace("$(goma_dir)", self.args.goma_dir) - if gn_args: - cmd.append('--args=%s' % gn_args) - if extra_args: - cmd.extend(extra_args) - return cmd + return [gn_path, subcommand, path] + list(args) + + def GNArgs(self, vals): + if vals['cros_passthrough']: + if not 'GN_ARGS' in os.environ: + raise MBErr('MB is expecting GN_ARGS to be in the environment') + gn_args = os.environ['GN_ARGS'] + if not re.search('target_os.*=.*"chromeos"', gn_args): + raise MBErr('GN_ARGS is missing target_os = "chromeos": (GN_ARGS=%s)' % + gn_args) + else: + gn_args = vals['gn_args'] + + if self.args.goma_dir: + gn_args += ' goma_dir="%s"' % self.args.goma_dir + + android_version_code = self.args.android_version_code + if android_version_code: + gn_args += ' android_default_version_code="%s"' % android_version_code + + android_version_name = self.args.android_version_name + if android_version_name: + gn_args += ' android_default_version_name="%s"' % android_version_name + + # Canonicalize the arg string into a sorted, newline-separated list + # of key-value pairs, and de-dup the keys if need be so that only + # the last instance of each arg is listed. + gn_args = gn_helpers.ToGNString(gn_helpers.FromGNArgs(gn_args)) + + args_file = vals.get('args_file', None) + if args_file: + gn_args = ('import("%s")\n' % vals['args_file']) + gn_args + return gn_args def RunGYPGen(self, vals): path = self.args.path[0] @@ -913,10 +987,12 @@ class MetaBuildWrapper(object): cmdline = [] extra_files = [] - if android: - # TODO(jbudorick): This won't work with instrumentation test targets. - # Revisit this logic when those are added to gn_isolate_map.pyl. - cmdline = [self.PathJoin('bin', 'run_%s' % target_name)] + if android and test_type != "script": + cmdline = [ + self.PathJoin('bin', 'run_%s' % target_name), + '--logcat-output-dir', '${ISOLATED_OUTDIR}/logcats', + '-v', + ] elif use_x11 and test_type == 'windowed_test_launcher': extra_files = [ 'xdisplaycheck', @@ -998,15 +1074,34 @@ class MetaBuildWrapper(object): return output_dir def GYPCmd(self, output_dir, vals): - gyp_defines = vals['gyp_defines'] + if vals['cros_passthrough']: + if not 'GYP_DEFINES' in os.environ: + raise MBErr('MB is expecting GYP_DEFINES to be in the environment') + gyp_defines = os.environ['GYP_DEFINES'] + if not 'chromeos=1' in gyp_defines: + raise MBErr('GYP_DEFINES is missing chromeos=1: (GYP_DEFINES=%s)' % + gyp_defines) + else: + gyp_defines = vals['gyp_defines'] + goma_dir = self.args.goma_dir # GYP uses shlex.split() to split the gyp defines into separate arguments, # so we can support backslashes and and spaces in arguments by quoting # them, even on Windows, where this normally wouldn't work. - if '\\' in goma_dir or ' ' in goma_dir: + if goma_dir and ('\\' in goma_dir or ' ' in goma_dir): goma_dir = "'%s'" % goma_dir - gyp_defines = gyp_defines.replace("$(goma_dir)", goma_dir) + + if goma_dir: + gyp_defines += ' gomadir=%s' % goma_dir + + android_version_code = self.args.android_version_code + if android_version_code: + gyp_defines += ' app_manifest_version_code=%s' % android_version_code + + android_version_name = self.args.android_version_name + if android_version_name: + gyp_defines += ' app_manifest_version_name=%s' % android_version_name cmd = [ self.executable, @@ -1018,6 +1113,21 @@ class MetaBuildWrapper(object): # Ensure that we have an environment that only contains # the exact values of the GYP variables we need. env = os.environ.copy() + + # This is a terrible hack to work around the fact that + # //tools/clang/scripts/update.py is invoked by GYP and GN but + # currently relies on an environment variable to figure out + # what revision to embed in the command line #defines. + # For GN, we've made this work via a gn arg that will cause update.py + # to get an additional command line arg, but getting that to work + # via GYP_DEFINES has proven difficult, so we rewrite the GYP_DEFINES + # to get rid of the arg and add the old var in, instead. + # See crbug.com/582737 for more on this. This can hopefully all + # go away with GYP. + if 'llvm_force_head_revision=1' in gyp_defines: + env['LLVM_FORCE_HEAD_REVISION'] = '1' + gyp_defines = gyp_defines.replace('llvm_force_head_revision=1', '') + env['GYP_GENERATORS'] = 'ninja' if 'GYP_CHROMIUM_NO_ACTION' in env: del env['GYP_CHROMIUM_NO_ACTION'] @@ -1083,8 +1193,11 @@ class MetaBuildWrapper(object): matching_targets = set() try: - cmd = self.GNCmd('refs', self.args.path[0]) + [ - '@%s' % response_file.name, '--all', '--as=output'] + cmd = self.GNCmd('refs', + self.args.path[0], + '@%s' % response_file.name, + '--all', + '--as=output') ret, out, _ = self.Run(cmd, force_verbose=False) if ret and not 'The input matches no targets' in out: self.WriteFailureAndRaise('gn refs returned %d: %s' % (ret, out), @@ -1095,8 +1208,10 @@ class MetaBuildWrapper(object): if build_output in targets: matching_targets.add(build_output) - cmd = self.GNCmd('refs', self.args.path[0]) + [ - '@%s' % response_file.name, '--all'] + cmd = self.GNCmd('refs', + self.args.path[0], + '@%s' % response_file.name, + '--all') ret, out, _ = self.Run(cmd, force_verbose=False) if ret and not 'The input matches no targets' in out: self.WriteFailureAndRaise('gn refs returned %d: %s' % (ret, out), @@ -1214,7 +1329,7 @@ class MetaBuildWrapper(object): self.Print(json.dumps(obj, indent=2, sort_keys=True)) def GNTargetName(self, target): - return target[:-len('_apk')] if target.endswith('_apk') else target + return target def Build(self, target): build_dir = self.ToSrcRelPath(self.args.path[0]) diff --git a/chromium/tools/mb/mb_config.pyl b/chromium/tools/mb/mb_config.pyl index e2cfe335e1f..38fb6782222 100644 --- a/chromium/tools/mb/mb_config.pyl +++ b/chromium/tools/mb/mb_config.pyl @@ -12,10 +12,11 @@ # generated publicly advertised non-Official builds which are not allowed # to have proprietary codecs enabled. 'chromium': { - 'Android': 'android_without_codecs_gyp_release_bot_minimal_symbols', + 'Android': 'android_without_codecs_gn_release_bot_minimal_symbols', 'Linux x64': 'noswarming_gn_release_bot', 'Mac': 'noswarming_gyp_release_bot_mac_strip', 'Win': 'noswarming_gyp_release_bot_minimal_symbols_x86', + 'Win x64': 'noswarming_gn_release_bot_minimal_symbols_x64', }, 'chromium.android': { @@ -36,9 +37,11 @@ 'android_cronet_gn_release_bot_minimal_symbols_x86', 'Android Cronet x86 Builder (dbg)': 'android_cronet_gn_debug_static_bot_x86', - 'Android GN Builder (dbg)': 'android_gn_debug_bot_minimal_symbols', - 'Android MIPS Builder (dbg)': 'android_gn_debug_static_bot_mipsel', + 'Android MIPS Builder (dbg)': + 'android_gn_debug_static_minimal_symbols_mipsel', + 'Android N5X Swarm Builder': + 'swarming_android_gn_release_bot_minimal_symbols_arm64', 'Android Swarm Builder': 'swarming_android_gn_release_bot_minimal_symbols', 'Android WebView CTS L-MR1 (dbg)': 'none', @@ -66,200 +69,207 @@ }, 'chromium.chromiumos': { - 'ChromiumOS amd64-generic Compile': 'tbd', - 'ChromiumOS daisy Compile': 'tbd', - 'ChromiumOS x86-generic Compile': 'tbd', - 'Linux ChromiumOS Builder (dbg)': 'tbd', - 'Linux ChromiumOS Full': 'tbd', - 'Linux ChromiumOS Ozone Builder': 'tbd', - + 'ChromiumOS amd64-generic Compile': 'cros_chrome_sdk_gn', + 'ChromiumOS daisy Compile': 'cros_chrome_sdk_gn', + 'ChromiumOS x86-generic Compile': 'cros_chrome_sdk_gn', 'Linux ChromiumOS Builder': 'swarming_chromeos_gyp_release_bot', + 'Linux ChromiumOS Builder (dbg)': 'swarming_chromeos_gyp_debug_bot', + 'Linux ChromiumOS Full': 'swarming_chromeos_gyp_release_bot', 'Linux ChromiumOS GN (dbg)': 'chromeos_gn_debug_bot', 'Linux ChromiumOS GN': 'chromeos_ozone_gn_release_bot', + 'Linux ChromiumOS Ozone Builder': + 'swarming_chromeos_ozone_gyp_release_bot', 'Linux ChromiumOS Ozone Tests (1)': 'none', 'Linux ChromiumOS Tests (1)': 'none', 'Linux ChromiumOS Tests (dbg)(1)': 'none', }, 'chromium.fyi': { - 'Blink Linux LSan ASan': 'tbd', - 'Browser Side Navigation Linux': 'tbd', - 'Chromium Builder': 'tbd', - 'Chromium Builder (dbg)': 'tbd', - 'Chromium Linux Goma Canary': 'tbd', - 'Chromium Linux Goma Canary (clobber)': 'tbd', - 'Chromium Linux Precise Goma LinkTest': 'tbd', - 'Chromium Linux32 Goma Canary (clobber)': 'tbd', - 'Chromium Mac 10.10 MacViews': 'tbd', - 'Chromium Mac 10.11': 'tbd', - 'Chromium Mac 10.11 Force Mac Toolchain': 'tbd', - 'Chromium Mac 10.9 Goma Canary': 'tbd', - 'Chromium Mac 10.9 Goma Canary (clobber)': 'tbd', - 'Chromium Mac 10.9 Goma Canary (dbg)': 'tbd', - 'Chromium Mac 10.9 Goma Canary (dbg)(clobber)': 'tbd', - 'Chromium Win 10': 'tbd', - 'Chromium Win x64 Clobber': 'tbd', - 'ChromiumOS Linux Tests': 'tbd', - 'ClangToTAndroidASan': - 'android_clang_no_chrome_plugins_asan_gn_debug_bot_minimal_symbols', - 'ClangToTLinux': 'tbd', - 'ClangToTLinux (dbg)': 'tbd', - 'ClangToTLinuxASan': 'tbd', - 'ClangToTLinuxUBSanVptr': 'tbd', - 'ClangToTMac': 'tbd', - 'ClangToTMac (dbg)': 'tbd', - 'ClangToTMacASan': 'tbd', - 'ClangToTWin': 'tbd', - 'ClangToTWin(dbg)': 'tbd', - 'ClangToTWin(dll)': 'tbd', - 'ClangToTWin64': 'tbd', - 'ClangToTWin64(dbg)': 'tbd', - 'ClangToTWin64(dll)': 'tbd', - 'ClangToTiOS': 'tbd', - 'Closure Compilation Linux': 'tbd', - 'CrWin7Goma': 'tbd', - 'CrWin7Goma(clbr)': 'tbd', - 'CrWin7Goma(dbg)': 'tbd', - 'CrWin7Goma(dll)': 'tbd', - 'CrWinAsan': 'tbd', - 'CrWinAsan(dll)': 'tbd', - 'CrWinAsanCov': 'tbd', - 'CrWinClang(shared)': 'tbd', - 'CrWinClang64(dll)': 'tbd', - 'CrWinClangGoma': 'tbd', - 'CrWinClangLLD': 'tbd', - 'CrWinClangLLD64': 'tbd', - 'CrWinClngLLD64dbg': 'tbd', - 'CrWinClngLLDdbg': 'tbd', - 'CrWinGoma': 'tbd', - 'CrWinGoma(dll)': 'tbd', - 'Linux Trusty': 'tbd', - 'Linux Trusty (dbg)': 'tbd', - 'Linux V8 API Stability': 'tbd', - 'MD Top Chrome ChromeOS material-hybrid': 'tbd', - 'MD Top Chrome ChromeOS non-material': 'tbd', - 'MD Top Chrome Linux material': 'tbd', - 'MD Top Chrome Win material': 'tbd', - 'Ozone ECS Linux': 'tbd', - 'Windows 8 App Certification': 'tbd', - 'Windows Builder (DrMemory)': 'tbd', - 'Windows Tests (DrMemory)': 'tbd', - 'Android ChromeDriver Tests (dbg)': 'none', 'Android Cloud Tests': 'android_gn_debug_static_bot_x86', 'Android Remoting Tests': 'none', 'Android Tests (trial)(dbg)': 'none', 'Android Tests (x86 emulator)': 'android_gn_debug_static_bot_x86', 'Android Asan Builder Tests (dbg)': - 'android_asan_gn_debug_bot_minimal_symbols', + 'android_asan_gn_clang_shared_debug_minimal_symbols', 'Android Builder (dbg)': 'android_gn_debug_static_bot', - 'CFI Linux CF': 'gn_cfi_diag_release_bot', - 'CFI Linux ToT': 'gn_cfi_release_bot', - 'CFI Linux': 'gn_cfi_release_bot', - 'Chromium Win MiniInstaller Tests': 'none', + 'Blimp Linux (dbg)': + '//build/args/bots/chromium.fyi/blimp_linux_dbg.gn', + 'Browser Side Navigation Linux': 'gn_release_bot', + 'CFI Linux CF': 'gn_cfi_diag_release_static', + 'CFI Linux ToT': 'gn_cfi_release_static', + 'CFI Linux': 'gn_cfi_release_static', + 'Chromium Linux Goma Canary': 'gn_release_bot', + 'Chromium Linux Goma Canary (clobber)': 'gn_release_bot', + 'Chromium Linux Precise Goma LinkTest': 'gn_release_bot', + 'Chromium Linux32 Goma Canary (clobber)': 'gn_release_bot_x86', + 'Chromium Mac 10.10 MacViews': 'mac_views_browser_gyp_release_bot', + 'Chromium Mac 10.11': 'gyp_release_bot', + 'Chromium Mac 10.11 Force Mac Toolchain': 'gyp_release_bot', + 'Chromium Mac 10.9 Goma Canary': 'gyp_release_bot', + 'Chromium Mac 10.9 Goma Canary (clobber)': 'gyp_release_bot', + 'Chromium Mac 10.9 Goma Canary (dbg)': 'gyp_debug_bot', + 'Chromium Mac 10.9 Goma Canary (dbg)(clobber)': 'gyp_debug_bot', 'Chromium Win PGO Builder': 'gyp_official_winpgo', 'Chromium Win x64 PGO Builder': 'gyp_official_winpgo_x64', 'Chromium Windows Analyze': 'gn_windows_analyze', - 'Chromium_iOS_Device': 'ios_gyp', - 'Chromium_iOS_Device_(ninja)': 'ios_gyp', - 'Chromium_iOS_Simulator_(dbg)': 'ios_gyp', + 'CrWin7Goma': 'gyp_release_bot_minimal_symbols_x86', + 'CrWin7Goma(clbr)': 'gyp_shared_release_bot_minimal_symbols_x86', + 'CrWin7Goma(dbg)': 'gyp_debug_bot_minimal_symbols_x86', + 'CrWin7Goma(dll)': 'gyp_shared_release_bot_minimal_symbols_x86', 'CrWinClang': 'swarming_gyp_clang_official_release_bot_minimal_symbols_x86', 'CrWinClang(dbg)': 'swarming_gyp_clang_debug_bot_minimal_symbols_x86', + 'CrWinClang(dbg) tester': 'none', 'CrWinClang64': 'swarming_gyp_clang_official_release_bot_minimal_symbols_x64', + 'CrWinClang tester': 'none', + 'CrWinClang64(dll)': + 'swarming_gyp_clang_minimal_symbols_shared_release_bot_x64', + 'CrWinClangGoma': 'gyp_clang_minimal_symbols_shared_release_bot_x86', + 'CrWinGoma': 'gyp_release_bot_minimal_symbols_x86', + 'CrWinGoma(dll)': 'gyp_shared_release_bot_minimal_symbols_x86', + 'ClangToTAndroidASan': 'android_clang_tot_asan', 'ClangToTAndroidASan tester': 'none', + 'ClangToTLinux': + 'swarming_gyp_clang_tot_linux_dump_symbols_shared_release', 'ClangToTLinux tester': 'none', + 'ClangToTLinux (dbg)': 'swarming_clang_tot_shared_debug', + 'ClangToTLinuxASan': 'swarming_gyp_clang_tot_asan_lsan_static_release', 'ClangToTLinuxASan tester': 'none', + 'ClangToTLinuxLLD': 'swarming_clang_tot_lld_release_shared', + 'ClangToTLinuxLLD tester': 'none', + 'ClangToTLinuxUBSanVptr': + 'swarming_gyp_clang_tot_edge_ubsan_no_recover_hack_static_release', 'ClangToTLinuxUBSanVptr tester': 'none', + 'ClangToTMac': 'swarming_gyp_clang_tot_minimal_symbols_shared_release', 'ClangToTMac tester': 'none', + 'ClangToTMac (dbg)': + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug', + 'ClangToTMacASan': + 'swarming_gyp_asan_clang_tot_full_symbols_static_release', 'ClangToTMacASan tester': 'none', + 'ClangToTWin': + 'swarming_gyp_clang_tot_official_minimal_symbols_static_release_x86', 'ClangToTWin tester': 'none', + 'ClangToTWin(dbg)': + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug_x86', 'ClangToTWin(dbg) tester': 'none', + 'ClangToTWin(dll)': + 'swarming_gyp_clang_tot_minimal_symbols_shared_release_x86', 'ClangToTWin(dll) tester': 'none', + 'ClangToTWin64': + 'swarming_gyp_clang_tot_official_minimal_symbols_static_release_x64', 'ClangToTWin64 tester': 'none', + 'ClangToTWin64(dbg)': + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug_x64', 'ClangToTWin64(dbg) tester': 'none', + 'ClangToTWin64(dll)': + 'swarming_gyp_clang_tot_minimal_symbols_shared_release_x64', 'ClangToTWin64(dll) tester': 'none', + 'ClangToTiOS': 'ios_gyp', + 'Closure Compilation Linux': 'closure_compilation', + 'CrWinAsan': + 'swarming_gyp_asan_clang_fuzzer_static_v8_heap_x86_full_symbols_release', 'CrWinAsan tester': 'none', + 'CrWinAsan(dll)': + 'swarming_gyp_asan_clang_fuzzer_shared_v8_heap_x86_full_symbols_release', 'CrWinAsan(dll) tester': 'none', + 'CrWinAsanCov': + ('swarming_gyp_asan_clang_edge_fuzzer' + '_static_v8_heap_x86_full_symbols_release'), 'CrWinAsanCov tester': 'none', - 'CrWinClang tester': 'none', - 'CrWinClang(dbg) tester': 'none', + 'CrWinClang(shared)': + 'swarming_gyp_clang_shared_release_bot_minimal_symbols_x86', 'CrWinClang(shared) tester': 'none', 'CrWinClang64 tester': 'none', - 'CrWinClang64(dbg) tester': 'none', 'CrWinClang64(dbg)': 'win_clang_debug_bot', + 'CrWinClang64(dbg) tester': 'none', 'CrWinClang64(dll) tester': 'none', + 'CrWinClangLLD': + 'swarming_gyp_clang_tot_minimal_symbols_shared_release_use_lld_x86', 'CrWinClangLLD tester': 'none', + 'CrWinClangLLD64': + 'swarming_gyp_clang_tot_minimal_symbols_shared_release_use_lld_x64', 'CrWinClangLLD64 tester': 'none', + 'CrWinClngLLD64dbg': + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug_use_lld_x64', 'CrWinClngLLD64dbg tester': 'none', + 'CrWinClngLLDdbg': + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug_use_lld_x86', 'CrWinClngLLDdbg tester': 'none', + 'Headless Linux (dbg)': + '//build/args/bots/chromium.fyi/headless_linux_dbg.gn', + 'MD Top Chrome ChromeOS material-hybrid': + 'gyp_chromeos_with_codecs_debug_bot', + 'MD Top Chrome ChromeOS non-material': + 'gyp_chromeos_with_codecs_debug_bot', + 'MD Top Chrome Win material': + 'gyp_debug_bot_minimal_symbols_x64', + 'MD Top Chrome Linux material': 'gn_debug_bot', + 'LTO Linux': 'gn_official_goma_lto', 'LTO Linux Perf': 'gn_official_goma_lto', 'Libfuzzer Upload Linux ASan': 'gn_release_libfuzzer_asan', + 'Libfuzzer Upload Linux ASan Debug': 'gn_debug_libfuzzer_asan', 'Libfuzzer Upload Linux MSan': 'gn_release_libfuzzer_msan', 'Libfuzzer Upload Linux UBSan': 'gn_release_libfuzzer_ubsan', - 'Linux ARM': 'swarming_gyp_release_bot_arm', + 'Linux ARM': 'swarming_gn_release_bot_arm', + 'Linux Kitchen (kitchen_run)': 'swarming_gn_release_bot', + 'Linux Kitchen (annotated_run)': 'swarming_gn_release_bot', + 'Linux V8 API Stability': 'gn_release_bot', 'Site Isolation Linux': 'gn_release_trybot', 'Site Isolation Win': 'gyp_release_trybot_x64', - 'Vista Tests (dbg)(1)': 'none', - 'Vista Tests (dbg)(2)': 'none', + 'UBSanVptr Linux': 'gn_ubsan_vptr_release_bot', + 'WebKit Linux - TraceWrappables': 'swarming_gn_release_bot_x64', 'Win LKGR (DrM 64)': 'gn_release_drmemory_drfuzz', 'Win LKGR (DrM)': 'gn_release_drmemory_drfuzz_x86', - 'Win8 Tests (1)': 'none', - 'Win8 Tests (2)': 'none', - 'WinClang': 'win_clang_debug_bot', - 'Windows Browser (DrMemory light) (1)': 'none', - 'Windows Browser (DrMemory light) (2)': 'none', + 'Win 10 Fast Ring': 'gn_release_trybot_x64', }, 'chromium.gpu': { - 'Android Debug (Nexus 5)': 'android_gyp_debug_static_bot', - 'Android Debug (Nexus 6)': 'android_gyp_debug_static_bot', - 'Android Debug (Nexus 9)': 'android_gyp_debug_static_bot_arm64', - 'GPU Mac Builder': 'tbd', - 'GPU Mac Builder (dbg)': 'tbd', - - 'GPU Linux Builder (dbg)': 'swarming_gpu_tests_gn_debug_bot', - 'GPU Linux Builder': 'swarming_gpu_tests_gn_release_bot', - 'GPU Win Builder': - 'swarming_gpu_tests_gyp_release_bot_minimal_symbols_x86', - 'GPU Win Builder (dbg)': - 'swarming_gpu_tests_gyp_debug_bot_minimal_symbols_x86', + # These all use the 'trybot' mixins to ensure that dcheck is on. + 'GPU Mac Builder': 'swarming_gpu_tests_gyp_release_trybot', + 'GPU Mac Builder (dbg)': 'swarming_gpu_tests_gyp_debug_trybot', + 'GPU Linux Builder (dbg)': 'swarming_gpu_tests_gn_debug_trybot', + 'GPU Linux Builder': 'swarming_gpu_tests_gn_release_trybot', + 'GPU Win Builder': 'swarming_gpu_tests_gyp_release_trybot_x86', + 'GPU Win Builder (dbg)': 'swarming_gpu_tests_gyp_debug_trybot_x86', 'Linux Debug (NVIDIA)': 'none', 'Linux Release (NVIDIA)': 'none', 'Mac 10.10 Debug (Intel)': 'none', 'Mac 10.10 Release (Intel)': 'none', 'Mac 10.10 Retina Debug (AMD)': 'none', 'Mac 10.10 Retina Release (AMD)': 'none', - 'Mac Retina Debug': 'none', - 'Mac Retina Release': 'none', 'Win7 Debug (NVIDIA)': 'none', 'Win7 Release (ATI)': 'none', 'Win7 Release (NVIDIA)': 'none', }, 'chromium.gpu.fyi': { - 'GPU Mac Builder': 'tbd', - 'GPU Mac Builder (dbg)': 'tbd', - 'GPU Win Clang Builder (dbg)': 'tbd', - 'Linux Audio': 'tbd', - 'Win7 Audio': 'tbd', - - 'GPU Linux Builder (dbg)': 'swarming_gpu_fyi_tests_gn_debug_bot', - 'GPU Linux Builder': 'swarming_gpu_fyi_tests_gn_release_bot', - 'GPU Win Builder': - 'swarming_gpu_tests_deqp_gles_gyp_release_bot_minimal_symbols_x86', + # These all use the 'trybot' mixins to ensure that dcheck is on. + 'Android Debug (Nexus 5)': 'android_gn_debug_static_trybot', + 'Android Debug (Nexus 5X)': 'android_gn_debug_static_trybot_arm64', + 'Android Debug (Nexus 6)': 'android_gn_debug_static_trybot', + 'Android Debug (Nexus 9)': 'android_gn_debug_static_trybot_arm64', + 'GPU Linux Builder (dbg)': 'swarming_gpu_fyi_tests_gn_debug_trybot', + 'GPU Linux Builder': 'swarming_gpu_fyi_tests_gn_release_trybot', + 'GPU Mac Builder': 'swarming_gpu_fyi_tests_gyp_release_trybot', + 'GPU Mac Builder (dbg)': 'swarming_gpu_fyi_tests_gyp_debug_trybot', + 'GPU Win Builder': 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_x86', 'GPU Win Builder (dbg)': - 'swarming_gpu_tests_deqp_gles_gyp_debug_bot_minimal_symbols_x86', + 'swarming_gpu_tests_deqp_gles_gyp_debug_trybot_x86', + 'GPU Win Clang Builder (dbg)': + 'swarming_gpu_fyi_tests_gyp_clang_debug_trybot_x86', 'GPU Win x64 Builder': - 'swarming_gpu_tests_deqp_gles_gyp_release_bot_minimal_symbols_x64', + 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_x64', 'GPU Win x64 Builder (dbg)': - 'swarming_gpu_tests_deqp_gles_gyp_debug_bot_minimal_symbols_x64', + 'swarming_gpu_tests_deqp_gles_gyp_debug_trybot_x64', + 'Linux ChromiumOS Builder': + 'swarming_gpu_fyi_tests_chromeos_gyp_release_trybot', 'Linux Debug (NVIDIA)': 'none', 'Linux Debug (New Intel)': 'none', 'Linux Release (ATI)': 'none', - 'Linux Release (Intel Graphics Stack)': 'none', 'Linux Release (NVIDIA GeForce 730)': 'none', 'Linux Release (NVIDIA)': 'none', 'Linux Release (New Intel)': 'none', @@ -275,7 +285,6 @@ 'Win7 Debug (NVIDIA)': 'none', 'Win7 Debug (New Intel)': 'none', 'Win7 Release (ATI)': 'none', - 'Win7 Release (Intel)': 'none', 'Win7 Release (NVIDIA GeForce 730)': 'none', 'Win7 Release (NVIDIA)': 'none', 'Win7 Release (New Intel)': 'none', @@ -287,66 +296,89 @@ 'chromium.linux': { 'Android Arm64 Builder (dbg)': - 'swarming_android_gyp_debug_static_bot_arm64', - 'Android Builder (dbg)': 'swarming_android_gyp_debug_static_bot', - 'Android Builder': 'swarming_android_gyp_release_bot_minimal_symbols', + 'swarming_android_gn_debug_static_bot_arm64', + 'Android Builder (dbg)': 'swarming_android_gn_debug_static_bot', + 'Android Builder': 'swarming_android_gn_release_bot_minimal_symbols', 'Android Clang Builder (dbg)': - 'android_clang_asan_findbugs_gyp_debug_bot_minimal_symbols', + 'android_clang_asan_findbugs_gn_debug_bot_minimal_symbols', 'Android GN (dbg)': 'android_gn_debug_bot_minimal_symbols', 'Android GN': 'android_gn_release_bot_minimal_symbols', - 'Android Tests (dbg)': 'swarming_android_gyp_debug_static_bot', - 'Android Tests': 'swarming_android_gyp_release_bot_minimal_symbols', - 'Cast Android (dbg)': 'android_cast_gyp_debug_static_bot', + 'Android Tests (dbg)': 'swarming_android_gn_debug_static_bot', + 'Android Tests': 'swarming_android_gn_release_bot_minimal_symbols', + 'Cast Android (dbg)': 'android_cast_gn_debug_static_bot', 'Cast Linux': 'cast_gn_release_bot', 'Linux Builder (dbg)': 'swarming_gn_debug_bot', - 'Linux Builder (dbg)(32)': 'swarming_gyp_debug_bot_no_symbols_x86', + 'Linux Builder (dbg)(32)': 'swarming_gn_debug_bot_x86', 'Linux Builder': 'swarming_gn_release_bot', 'Linux Tests (dbg)(1)': 'none', 'Linux Tests (dbg)(1)(32)': 'none', 'Linux Tests': 'none', }, - 'chromium.mac': { - 'Mac Builder': 'tbd', - 'Mac Builder (dbg)': 'tbd', + 'chromium.lkgr': { + 'ASAN Debug': 'gyp_asan_lsan_edge_fuzzer_debug_bot', + 'ASAN Release (symbolized)': + 'gyp_asan_lsan_edge_fuzzer_v8_heap_symbolized_release_bot', + 'ASAN Release Media': + 'gyp_asan_lsan_edge_fuzzer_v8_heap_chromeos_codecs_release_bot', + 'ASAN Release': 'gyp_asan_lsan_edge_fuzzer_v8_heap_release_bot', + 'ASan Debug (32-bit x86 with V8-ARM)': + 'gyp_asan_edge_fuzzer_v8_heap_debug_bot_hybrid', + 'ASan Release (32-bit x86 with V8-ARM)': + 'gyp_asan_edge_fuzzer_v8_heap_release_bot_hybrid', + 'ASan Release (32-bit x86 with V8-ARM, symbolized)': + 'gyp_asan_edge_fuzzer_v8_heap_symbolized_release_bot_hybrid', + 'ASan Release Media (32-bit x86 with V8-ARM)': + 'gyp_asan_edge_fuzzer_v8_heap_chromeos_codecs_release_bot_hybrid', + 'ChromiumOS ASAN Release': + 'gyp_chromeos_asan_lsan_edge_fuzzer_v8_heap_release_bot', + 'MSAN Release (chained origins)': 'gyp_msan_edge_release_bot', + 'MSAN Release (no origins)': 'gyp_msan_no_origins_edge_release_bot', + 'Mac ASAN Debug': 'gyp_asan_fuzzer_v8_heap_debug_symbols_static_bot', + 'Mac ASAN Release Media': + 'gyp_asan_fuzzer_v8_heap_chrome_with_codecs_release_bot', + 'Mac ASAN Release': 'gyp_asan_fuzzer_v8_heap_release_bot', + 'TSAN Debug': 'gyp_tsan_disable_nacl_line_tables_debug_bot', + 'TSAN Release': 'gyp_tsan_disable_nacl_line_tables_release_bot', + 'Telemetry Harness Upload': 'none', + 'UBSan Release': 'gyp_ubsan_release_bot', + 'UBSan vptr Release': 'gyp_ubsan_vptr_edge_release_bot', + 'Win ASan Release Coverage': + 'gyp_asan_edge_fuzzer_v8_heap_release_static_x86', + 'Win ASan Release Media': + 'gyp_asan_fuzzer_v8_heap_chrome_with_codecs_release_static_x86', + 'Win ASan Release': 'gyp_asan_fuzzer_v8_heap_release_static_x86', + 'Win SyzyASAN LKGR': 'gyp_syzyasan_no_pch_win_z7_x86', + }, - 'Mac GN (dbg)': 'gn_debug_static_bot', + 'chromium.mac': { + 'Mac Builder': 'swarming_gpu_tests_gyp_release_bot', + 'Mac Builder (dbg)': 'swarming_gyp_debug_bot', + 'Mac GN (dbg)': 'gn_debug_bot', 'Mac GN': 'gn_release_bot', 'Mac10.10 Tests': 'none', 'Mac10.11 Tests': 'none', 'Mac10.9 Tests (dbg)': 'none', 'Mac10.9 Tests': 'none', - 'iOS_Device': 'ios_gyp', - 'iOS_Device_(ninja)': 'ios_gyp', - 'iOS_Device_GN': 'ios_gn', - 'iOS_Simulator_(dbg)': 'ios_gyp', - 'iOS_Simulator_GN_(dbg)': 'ios_gn', + 'ios-device': 'ios_gyp', + 'ios-device-gn': 'ios_gn', + 'ios-simulator': 'ios_gyp', + 'ios-simulator-gn': 'ios_gn', }, 'chromium.memory.fyi': { - 'Chromium Linux ChromeOS MSan Builder': 'tbd', - 'Chromium Linux MSan Builder': 'tbd', - 'Chromium Linux TSan Builder': 'tbd', - - 'Chromium Linux Builder (valgrind)': 'gyp_valgrind_release_bot', - 'Chromium OS (valgrind)(1)': 'none', - 'Chromium OS (valgrind)(2)': 'none', - 'Chromium OS (valgrind)(3)': 'none', - 'Chromium OS (valgrind)(4)': 'none', - 'Chromium OS (valgrind)(5)': 'none', - 'Chromium OS (valgrind)(6)': 'none', - 'Chromium OS Builder (valgrind)': 'gyp_valgrind_chromeos_release_bot', + 'Chromium Linux ChromeOS MSan Builder': + 'swarming_gyp_chromeos_msan_release_bot', + 'Chromium Linux MSan Builder': + 'swarming_gyp_msan_release_bot', + 'Chromium Linux TSan Builder': + 'swarming_gyp_tsan_disable_nacl_release_bot', 'Chromium Windows Builder (DrMemory x64)': 'gyp_drmemory_shared_release_x64', 'Chromium Windows Builder (DrMemory)': 'gyp_drmemory_shared_release_x86', 'Linux ChromeOS MSan Tests': 'none', 'Linux MSan Tests': 'none', 'Linux TSan Tests': 'none', - 'Linux Tests (valgrind)(1)': 'none', - 'Linux Tests (valgrind)(2)': 'none', - 'Linux Tests (valgrind)(3)': 'none', - 'Linux Tests (valgrind)(4)': 'none', - 'Linux Tests (valgrind)(5)': 'none', 'Windows Browser (DrMemory full) (1)': 'none', 'Windows Browser (DrMemory full) (10)': 'none', 'Windows Browser (DrMemory full) (11)': 'none', @@ -482,52 +514,65 @@ 'Linux Builder': 'swarming_gn_release_bot', 'Linux Builder-Trybot': 'swarming_gn_release_bot', 'Linux Tests': 'swarming_gn_release_bot', + 'Mac Builder': 'swarming_gpu_tests_gyp_release_bot', + 'Mac Builder-Trybot': 'swarming_gpu_tests_gyp_release_bot', 'Win Builder': 'swarming_gpu_tests_gyp_release_bot_minimal_symbols_x86', - 'Win Builder-Trybot': - 'swarming_gpu_tests_gyp_release_trybot_minimal_symbols_x86', + 'Win Builder-Trybot': 'swarming_gpu_tests_gyp_release_bot_x86', }, 'client.v8.fyi': { + 'Android Builder': 'gn_official_goma_minimal_symbols_android', 'Linux Debug Builder': 'gn_debug_bot', 'V8 Android GN (dbg)': 'android_gn_debug_bot', 'V8 Linux GN': 'gn_release_bot', + 'V8-Blink Linux 64': 'noswarming_gn_release_bot_x64', + 'V8-Blink Linux 64 - ignition': 'noswarming_gn_release_bot_x64', + 'V8-Blink Linux 64 (dbg)': 'noswarming_gn_debug_bot_x64', + 'V8-Blink Mac': 'noswarming_gyp_release_bot_x64', + 'V8-Blink Win': 'noswarming_gyp_release_bot_minimal_symbols_x86', }, 'chromium.webkit': { - 'Android Builder': 'gyp_release_bot_android', - 'WebKit Android (Nexus4)': 'gyp_release_bot_android', - 'WebKit Linux (dbg)': 'swarming_gn_debug_bot_x64', - 'WebKit Linux ASAN': 'swarming_gn_asan_lsan_release_bot_x64', - 'WebKit Linux Leak': 'swarming_gn_release_bot_x64', - 'WebKit Linux MSAN': 'swarming_gn_msan_release_bot_x64', - 'WebKit Linux Trusty': 'swarming_gn_release_bot_x64', - 'WebKit Linux': 'swarming_gn_release_bot_x64', - 'WebKit Mac Builder (dbg)': 'swarming_gyp_debug_bot_x64', - 'WebKit Mac Builder': 'swarming_gyp_release_bot_x64', + 'Android Builder': 'android_gn_release_bot_minimal_symbols', + 'WebKit Android (Nexus4)': 'none', + 'WebKit Linux (dbg)': 'swarming_gn_debug_bot', + 'WebKit Linux ASAN': 'swarming_gn_asan_lsan_release_bot', + 'WebKit Linux Leak': 'swarming_gn_release_bot', + 'WebKit Linux MSAN': 'swarming_gn_msan_release_bot', + 'WebKit Linux Trusty': 'swarming_gn_release_bot', + 'WebKit Linux': 'swarming_gn_release_bot', + 'WebKit Mac Builder (dbg)': 'swarming_gyp_debug_bot', + 'WebKit Mac Builder': 'swarming_gyp_release_bot', 'WebKit Mac10.10': 'none', 'WebKit Mac10.11 (dbg)': 'none', - 'WebKit Mac10.11 (retina)': 'swarming_gyp_release_bot_x64', + 'WebKit Mac10.11 (retina)': 'swarming_gyp_release_bot', 'WebKit Mac10.11': 'none', - 'WebKit Mac10.9': 'none', + 'WebKit Mac10.9': 'swarming_gyp_release_bot', 'WebKit Win Builder (dbg)': 'swarming_gyp_debug_bot_minimal_symbols_x86', 'WebKit Win Builder': 'swarming_gyp_release_bot_minimal_symbols_x86', 'WebKit Win x64 Builder (dbg)': - 'swarming_gyp_debug_bot_minimal_symbols_x64', - 'WebKit Win x64 Builder': 'swarming_gyp_release_bot_minimal_symbols_x64', + 'swarming_gn_debug_bot_minimal_symbols_x64', + 'WebKit Win x64 Builder': 'swarming_gn_release_bot_minimal_symbols_x64', 'WebKit Win10': 'none', 'WebKit Win7 (dbg)': 'none', 'WebKit Win7': 'none', }, - 'chromium.webrtc.fyi': { - 'Android Builder (dbg)': 'tbd', - 'Android Builder ARM64 (dbg)': 'tbd', - 'Mac Builder': 'tbd', - 'Win Builder': 'tbd', + 'chromium.webrtc': { + 'Linux Builder': 'gn_release_bot_chrome_with_codecs', + 'Linux Tester': 'none', + 'Mac Builder': 'chrome_with_codecs_blink_logging_gyp_release_trybot', + 'Mac Tester': 'none', + 'Win Builder': 'chrome_with_codecs_blink_logging_gyp_release_trybot_x86', + 'Win10 Tester': 'none', + 'Win7 Tester': 'none', + 'Win8 Tester': 'none', + }, - 'Android GN (dbg)': 'android_gn_debug_bot', - 'Android GN': 'android_gn_release_bot', + 'chromium.webrtc.fyi': { + 'Android Builder (dbg)': 'android_gn_debug_static_bot', + 'Android Builder ARM64 (dbg)': 'android_gn_debug_static_bot_arm64', 'Android Tests (dbg) (K Nexus5)': 'none', 'Android Tests (dbg) (L Nexus5)': 'none', 'Android Tests (dbg) (L Nexus6)': 'none', @@ -535,9 +580,11 @@ 'Android Tests (dbg) (L Nexus9)': 'none', 'Linux Builder': 'gn_release_bot_chrome_with_codecs', 'Linux Tester': 'none', + 'Mac Builder': 'chrome_with_codecs_blink_logging_gyp_release_trybot', 'Mac GN (dbg)': 'gn_debug_static_bot_chrome_with_codecs', 'Mac GN': 'gn_release_bot_chrome_with_codecs', 'Mac Tester': 'none', + 'Win Builder': 'chrome_with_codecs_blink_logging_gyp_release_trybot_x86', 'Win x64 GN (dbg)': 'gn_debug_bot_minimal_symbols_chrome_with_codecs', 'Win x64 GN': 'gn_release_bot_minimal_symbols_chrome_with_codecs', 'Win10 Tester': 'none', @@ -548,10 +595,8 @@ # Windows bots take too long to link w/ full symbols and time out. 'Win Builder': 'swarming_gyp_release_bot_minimal_symbols_x86', 'Win Builder (dbg)': 'swarming_gyp_debug_bot_minimal_symbols_x86', - 'Win x64 Builder': 'swarming_gyp_release_bot_minimal_symbols_x64', - 'Win x64 Builder (dbg)': 'swarming_gyp_debug_bot_minimal_symbols_x64', - 'Win x64 GN (dbg)': 'gn_debug_bot_minimal_symbols', - 'Win x64 GN': 'gn_release_bot_minimal_symbols', + 'Win x64 Builder': 'swarming_gn_release_bot_minimal_symbols_x64', + 'Win x64 Builder (dbg)': 'swarming_gn_debug_bot_minimal_symbols_x64', 'Win 7 Tests x64 (1)': 'none', 'Win10 Tests x64': 'none', 'Win7 (32) Tests': 'none', @@ -559,10 +604,11 @@ 'Win7 Tests (dbg)(1)': 'none', 'Win8 Aura': 'gn_release_bot_minimal_symbols_x86', 'Win8 GN (dbg)': 'gn_debug_bot_minimal_symbols_x86', + 'WinClang64 (dbg)': 'win_clang_debug_bot', }, 'official.desktop': { - 'blimp-engine': 'gn_blimp_debug', + 'blimp-engine': '//build/args/bots/official.desktop/blimp-engine.gn', 'mac64': 'gyp_official', 'precise64': 'gn_official', @@ -588,42 +634,29 @@ }, 'tryserver.blink': { - 'linux_chromium_gn_rel': 'tbd', - - 'blink_presubmit': 'none', - 'linux_blink_compile_dbg': - 'swarming_gn_debug_bot_minimal_symbols_x64', - 'linux_blink_compile_rel': - 'swarming_gn_release_trybot_minimal_symbols_x64', - 'linux_blink_dbg': - 'swarming_gn_debug_bot_minimal_symbols_x64', - 'linux_blink_rel': - 'swarming_gn_release_trybot_minimal_symbols_x64', - 'linux_blink_rel_ng': - 'swarming_gn_release_trybot_minimal_symbols_x64', - 'mac_blink_compile_dbg': - 'swarming_gyp_debug_bot_minimal_symbols_x64', - 'mac_blink_compile_rel': - 'swarming_gyp_release_bot_minimal_symbols_x64', - 'mac_blink_dbg': - 'swarming_gyp_debug_bot_minimal_symbols_x64', - 'mac_blink_rel': 'swarming_gyp_release_trybot_minimal_symbols_x64', - 'win_blink_compile_dbg': 'swarming_gyp_debug_bot_minimal_symbols_x86', - 'win_blink_compile_rel': - 'swarming_gyp_release_trybot_minimal_symbols_x86', - 'win_blink_dbg': 'swarming_gyp_debug_bot_minimal_symbols_x86', - 'win_blink_rel': 'swarming_gyp_release_trybot_minimal_symbols_x86', + # Most tryservers should have '_trybot' in their config names, but + # 'release_trybot' includes 'dcheck_always_on', and the blink + # release trybots must *not* enable dchecks, because that could + # cause them to produce different baselines than the release + # waterfall bots, and run-webkit-tests can't handle that (by design). + 'linux_blink_compile_dbg': 'swarming_gn_debug_trybot', + 'linux_blink_compile_rel': 'swarming_gn_release_bot_minimal_symbols', + 'linux_blink_dbg': 'swarming_gn_debug_trybot', + 'linux_blink_rel': 'swarming_gn_release_bot_minimal_symbols', + 'mac_blink_compile_dbg': 'swarming_gyp_debug_trybot', + 'mac_blink_compile_rel': 'swarming_gyp_release_bot_minimal_symbols', + 'mac_blink_dbg': 'swarming_gyp_debug_trybot', + 'mac_blink_rel': 'swarming_gyp_release_bot_minimal_symbols', + 'win_blink_compile_dbg': 'swarming_gyp_debug_trybot_x86', + 'win_blink_compile_rel': 'swarming_gyp_release_bot_minimal_symbols_x86', + 'win_blink_dbg': 'swarming_gyp_debug_trybot_x86', + 'win_blink_rel': 'swarming_gyp_release_bot_minimal_symbols_x86', }, 'tryserver.chromium.android': { - 'android_amp': 'tbd', - 'android_archive_rel_ng': 'tbd', - 'android_coverage': 'tbd', - 'android_swarming_rel': 'tbd', - 'cast_shell_android': 'tbd', - - 'android_arm64_dbg_recipe': 'swarming_android_gyp_debug_trybot_arm64', - 'android_blink_rel': 'swarming_android_gyp_release_trybot', + 'android_archive_rel_ng': 'android_gn_release_trybot', + 'android_arm64_dbg_recipe': 'swarming_android_gn_debug_trybot_arm64', + 'android_blink_rel': 'swarming_android_gn_release_trybot', 'android_chromium_gn_compile_dbg': 'android_gn_debug_trybot', 'android_chromium_gn_compile_rel': 'android_gn_release_trybot', 'android_chromium_gn_rel': 'android_gn_release_trybot', @@ -634,80 +667,86 @@ 'android_chromium_variable_clang': 'findit', 'android_chromium_variable_gn': 'findit', 'android_chromium_variable_nexus4': 'findit', - 'android_clang_dbg_recipe': 'android_clang_asan_findbugs_gyp_debug_trybot', - 'android_compile_dbg': 'swarming_android_gyp_debug_trybot', + 'android_clang_dbg_recipe': 'android_clang_asan_findbugs_gn_debug_trybot', + 'android_compile_dbg': 'swarming_android_gn_debug_trybot', 'android_compile_mips_dbg': 'android_gn_debug_trybot_mipsel', - 'android_compile_rel': 'swarming_android_gyp_release_trybot', + 'android_compile_rel': 'swarming_android_gn_release_trybot', 'android_compile_x64_dbg': 'android_gn_debug_trybot_x64', 'android_compile_x86_dbg': 'android_gn_debug_trybot_x86', + 'android_coverage': 'android_gn_debug_trybot_java_coverage', # TODO(crbug/597596): Switch this back to debug_trybot when cronet's # shared library loading is fixed. 'android_cronet_tester': 'android_cronet_gn_debug_static_bot', - 'linux_android_dbg_ng': 'swarming_android_gyp_debug_trybot', - 'linux_android_rel_ng': 'swarming_android_gyp_release_trybot', + 'android_swarming_rel': 'swarming_android_gn_release_trybot', + 'cast_shell_android': 'android_cast_gn_debug_static_bot', + 'linux_android_dbg_ng': 'swarming_android_gn_debug_trybot', + 'linux_android_rel_ng': 'swarming_android_gn_release_trybot', }, 'tryserver.chromium.angle': { - 'mac_angle_dbg_ng': 'tbd', - 'mac_angle_rel_ng': 'tbd', - 'linux_angle_dbg_ng': 'swarming_gpu_fyi_tests_gn_debug_trybot', 'linux_angle_rel_ng': 'swarming_gpu_fyi_tests_gn_release_trybot', - 'win_angle_dbg_ng': - 'swarming_gpu_tests_deqp_gles_gyp_debug_bot_minimal_symbols_x86', - 'win_angle_rel_ng': - 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_minimal_symbols_x86', + 'mac_angle_dbg_ng': 'swarming_gpu_fyi_tests_gyp_debug_trybot', + 'mac_angle_rel_ng': 'swarming_gpu_fyi_tests_gyp_release_trybot', + 'win_angle_dbg_ng': 'swarming_gpu_tests_deqp_gles_gyp_debug_trybot_x86', + 'win_angle_rel_ng': 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_x86', 'win_angle_x64_dbg_ng': - 'swarming_gpu_tests_deqp_gles_gyp_debug_bot_minimal_symbols_x64', + 'swarming_gpu_tests_deqp_gles_gyp_debug_trybot_x64', 'win_angle_x64_rel_ng': - 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_minimal_symbols_x64', + 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_x64', }, 'tryserver.chromium.linux': { - 'Chromium Linux Codesearch Builder': 'tbd', - 'ChromiumOS Codesearch Builder': 'tbd', - 'chromeos_amd64-generic_chromium_compile_only_ng': 'tbd', - 'chromeos_daisy_chromium_compile_only_ng': 'tbd', - 'chromeos_x86-generic_chromium_compile_only_ng': 'tbd', - 'linux_chromium_browser_side_navigation_rel': 'tbd', - 'linux_chromium_chromeos_asan_rel_ng': 'tbd', - 'linux_chromium_chromeos_asan_variable': 'tbd', - 'linux_chromium_chromeos_compile_dbg_ng': 'tbd', - 'linux_chromium_chromeos_dbg_ng': 'tbd', - 'linux_chromium_chromeos_msan_rel_ng': 'tbd', - 'linux_chromium_chromeos_ozone_rel_ng': 'tbd', - 'linux_chromium_chromeos_variable': 'tbd', - 'linux_chromium_variable': 'tbd', - + 'Chromium Linux Codesearch Builder': 'codesearch_gn', + 'ChromiumOS Codesearch Builder': 'codesearch_gn', 'cast_shell_linux': 'cast_gn_release_trybot', 'chromeos_amd64-generic_variable': 'findit', + 'chromeos_amd64-generic_chromium_compile_only_ng': 'cros_chrome_sdk_gn', + 'chromeos_daisy_chromium_compile_only_ng': 'cros_chrome_sdk_gn', 'chromeos_daisy_variable': 'findit', + 'chromeos_x86-generic_chromium_compile_only_ng': 'cros_chrome_sdk_gn', 'chromeos_x86-generic_variable': 'findit', 'chromium_presubmit': 'none', + 'closure_compilation': 'closure_compilation', 'linux_arm': 'swarming_gyp_release_trybot_arm', 'linux_chromium_archive_rel_ng': 'noswarming_gn_release_bot', 'linux_chromium_asan_rel_ng': 'swarming_asan_lsan_gyp_release_trybot', 'linux_chromium_asan_variable': 'findit', + 'linux_chromium_browser_side_navigation_rel': 'gyp_release_trybot', 'linux_chromium_cast_variable': 'findit', - 'linux_chromium_cfi_rel_ng': 'gn_cfi_release_trybot', + 'linux_chromium_cfi_rel_ng': 'gn_cfi_release_static_dcheck_always_on', + 'linux_chromium_chromeos_asan_rel_ng': + 'swarming_asan_lsan_chromeos_gyp_release_trybot', + 'linux_chromium_chromeos_asan_variable': 'findit', + 'linux_chromium_chromeos_compile_dbg_ng': + 'swarming_chromeos_gyp_debug_trybot', 'linux_chromium_chromeos_compile_rel_ng': - 'swarming_chromeos_gyp_release_trybot', + 'swarming_chromeos_gn_release_trybot', + 'linux_chromium_chromeos_dbg_ng': + 'swarming_chromeos_gyp_debug_trybot', + 'linux_chromium_chromeos_msan_rel_ng': + 'swarming_chromeos_msan_gyp_release_trybot', + 'linux_chromium_chromeos_ozone_rel_ng': + 'swarming_chromeos_gyp_ozone_release_trybot', 'linux_chromium_chromeos_rel_ng': 'swarming_chromeos_gyp_release_trybot', + 'linux_chromium_chromeos_variable': 'findit', 'linux_chromium_chromeos_variable_chrome': 'findit', 'linux_chromium_clobber_rel_ng': 'gn_release_trybot', - 'linux_chromium_compile_dbg_32_ng': 'swarming_gyp_debug_trybot_x86', + 'linux_chromium_compile_dbg_32_ng': 'swarming_gn_debug_trybot_x86', 'linux_chromium_compile_dbg_ng': 'swarming_gn_debug_trybot', 'linux_chromium_compile_rel_ng': 'swarming_gn_release_trybot', - 'linux_chromium_dbg_32_ng': 'swarming_gyp_debug_trybot_x86', + 'linux_chromium_dbg_32_ng': 'swarming_gn_debug_trybot_x86', 'linux_chromium_dbg_ng': 'swarming_gn_debug_trybot', 'linux_chromium_gn_chromeos_dbg': 'chromeos_gn_debug_bot', 'linux_chromium_gn_chromeos_rel': 'chromeos_ozone_gn_release_trybot', 'linux_chromium_gn_chromeos_variable': 'findit', 'linux_chromium_gn_upload': 'gn_linux_upload', 'linux_chromium_msan_rel_ng': 'swarming_msan_gyp_release_trybot', - 'linux_chromium_practice_rel_ng': 'gyp_release_trybot', 'linux_chromium_rel_ng': 'swarming_gpu_tests_gn_release_trybot', 'linux_chromium_tsan_rel_ng': 'swarming_tsan_gyp_release_trybot', + 'linux_chromium_tsan_rel_ng': + 'swarming_gyp_tsan_disable_nacl_release_trybot', + 'linux_chromium_variable': 'findit', 'linux_chromium_variable_32': 'findit', 'linux_chromium_variable_chrome': 'findit', 'linux_chromium_variable_clobber': 'findit', @@ -717,37 +756,30 @@ 'linux_chromium_webkit_leak_variable': 'findit', 'linux_chromium_webkit_msan_variable': 'findit', 'linux_chromium_webkit_variable': 'findit', - 'linux_ecs_ozone': 'embedded_gyp_debug_bot', - 'linux_full_bisect_builder': 'swarming_gyp_release_bot', 'linux_nacl_sdk': 'nacl_annotator', 'linux_nacl_sdk_build': 'nacl_annotator', 'linux_optional_gpu_tests_rel': 'swarming_gpu_fyi_tests_gn_release_trybot', 'linux_site_isolation': 'gn_release_trybot', 'linux_upload_clang': 'gn_release_bot', - 'linux_valgrind': 'gyp_valgrind_release_bot', }, 'tryserver.chromium.mac': { - 'mac_chromium_10.10_rel_ng': 'tbd', - 'mac_chromium_archive_rel_ng': 'tbd', - 'mac_chromium_asan_rel_ng': 'tbd', - 'mac_chromium_asan_variable': 'tbd', - 'mac_chromium_compile_dbg_ng': 'tbd', - 'mac_chromium_compile_rel_ng': 'tbd', - 'mac_chromium_dbg_ng': 'tbd', - 'mac_chromium_rel_ng': 'tbd', - 'mac_optional_gpu_tests_rel': 'tbd', - - 'ios_dbg_simulator': 'ios_gyp', - 'ios_dbg_simulator_gn': 'ios_gn', - 'ios_dbg_simulator_ninja': 'ios_gyp', - 'ios_rel_device': 'ios_gyp', - 'ios_rel_device_gn': 'ios_gn', - 'ios_rel_device_ninja': 'ios_gyp', - 'mac_chromium_gn_dbg': 'gn_debug_static_bot', + 'ios-device': 'ios_gyp', + 'ios-device-gn': 'ios_gn', + 'ios-simulator': 'ios_gyp', + 'ios-simulator-gn': 'ios_gn', + 'mac_chromium_10.10_rel_ng': 'swarming_gpu_tests_gyp_release_trybot', + 'mac_chromium_archive_rel_ng': 'noswarming_gyp_release_trybot', + 'mac_chromium_asan_rel_ng': 'swarming_asan_dcheck_gyp_release_bot', + 'mac_chromium_asan_variable': 'findit', + 'mac_chromium_compile_dbg_ng': 'swarming_gyp_debug_trybot', + 'mac_chromium_compile_rel_ng': 'swarming_gpu_tests_gyp_release_trybot', + 'mac_chromium_dbg_ng': 'swarming_gyp_debug_trybot', + 'mac_chromium_gn_dbg': 'gn_debug_bot', 'mac_chromium_gn_rel': 'gn_release_trybot', 'mac_chromium_gn_upload': 'gn_release_bot', + 'mac_chromium_rel_ng': 'swarming_gpu_tests_gyp_release_trybot', 'mac_chromium_variable': 'findit', 'mac_chromium_variable_10.10': 'findit', 'mac_chromium_variable_10.10_layout': 'findit', @@ -757,6 +789,8 @@ 'mac_chromium_variable_layout': 'findit', 'mac_nacl_sdk': 'nacl_annotator', 'mac_nacl_sdk_build': 'nacl_annotator', + 'mac_optional_gpu_tests_rel': + 'swarming_gpu_fyi_tests_gyp_release_trybot', 'mac_upload_clang': 'gn_release_bot', }, @@ -804,23 +838,19 @@ }, 'tryserver.chromium.win': { - 'win10_chromium_x64_rel_ng': - 'swarming_gyp_release_trybot_minimal_symbols_x64', - 'win8_chromium_gn_dbg': 'gn_debug_bot_minimal_symbols_x86', + 'win10_chromium_x64_rel_ng': 'swarming_gn_release_trybot_x64', + 'win10_chromium_x64_rel_ng_exp': 'swarming_gn_release_trybot_x64', + 'win8_chromium_gn_dbg': 'swarming_gn_debug_trybot_x86', 'win8_chromium_gn_upload': 'gn_release_bot_minimal_symbols_x86', 'win8_chromium_ng': 'gn_release_trybot_x86', - 'win_archive': 'noswarming_gyp_release_trybot_minimal_symbols_x86', - 'win_chromium_compile_dbg_ng': - 'swarming_gyp_debug_bot_minimal_symbols_x86', + 'win_x64_archive': 'noswarming_gyp_release_trybot_x64', + 'win_archive': 'noswarming_gyp_release_trybot_x86', + 'win_chromium_compile_dbg_ng': 'swarming_gyp_debug_trybot_x86', 'win_chromium_compile_rel_ng': - 'swarming_gpu_tests_gyp_release_trybot_minimal_symbols_x86', - 'win_chromium_gn_x64_dbg': 'gn_debug_bot_minimal_symbols', - 'win_chromium_gn_x64_rel': 'gn_release_trybot', - 'win_chromium_dbg_ng': 'swarming_gyp_debug_bot_minimal_symbols_x86', - 'win_chromium_rel_ng': - 'swarming_gpu_tests_gyp_release_trybot_minimal_symbols_x86', - 'win_chromium_syzyasan_rel': - 'swarming_gyp_syzyasan_release_trybot_minimal_symbols_x86', + 'swarming_gpu_tests_gyp_release_trybot_x86', + 'win_chromium_dbg_ng': 'swarming_gyp_debug_trybot_x86', + 'win_chromium_rel_ng': 'swarming_gpu_tests_gyp_release_trybot_x86', + 'win_chromium_syzyasan_rel': 'swarming_gyp_syzyasan_release_trybot_x86', 'win_chromium_variable': 'findit', 'win_chromium_variable_archive': 'findit', 'win_chromium_variable_chrome': 'findit', @@ -829,26 +859,24 @@ 'win_chromium_variable_webkit_layout': 'findit', 'win_chromium_variable_webkit_win7_builder': 'findit', 'win_chromium_variable_webkit_win7_builder_x64': 'findit', - 'win_chromium_x64_rel_ng': - 'swarming_gyp_release_trybot_minimal_symbols_x64', + 'win_chromium_x64_rel_ng': 'swarming_gn_release_trybot_x64', 'win_clang': 'win_clang_debug_bot', - 'win_clang_dbg': 'swarming_gyp_clang_debug_bot_minimal_symbols_x86', - 'win_clang_rel': - 'swarming_gyp_clang_official_release_trybot_minimal_symbols_x86', + 'win_clang_dbg': 'swarming_gyp_clang_debug_trybot_x86', + 'win_clang_rel': 'swarming_gyp_clang_official_release_trybot_x86', 'win_clang_x64_dbg': 'win_clang_debug_bot', - 'win_clang_x64_rel': - 'swarming_gyp_clang_official_release_trybot_minimal_symbols_x64', + 'win_clang_x64_rel': 'swarming_gyp_clang_official_release_trybot_x64', 'win_nacl_sdk': 'nacl_annotator', 'win_nacl_sdk_build': 'nacl_annotator', 'win_optional_gpu_tests_rel': - 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_minimal_symbols_x86', + 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_x86', 'win_pgo': 'gyp_official_winpgo', 'win_upload_clang': 'gn_release_bot', + 'win_chrome_official': 'gyp_official_goma_minimal_symbols_x86', }, 'tryserver.v8': { 'v8_android_chromium_gn_dbg': 'android_gn_debug_bot', - 'v8_linux_blink_rel': 'swarming_gn_release_trybot_minimal_symbols_x64', + 'v8_linux_blink_rel': 'swarming_gn_release_trybot_x64', 'v8_linux_chromium_gn_rel': 'gn_release_trybot', }, }, @@ -860,26 +888,26 @@ # is not necessarily so (i.e., we might have mac, win, and linux # bots all using the 'gn_release_bot' config). 'configs': { - 'android_asan_gn_debug_bot_minimal_symbols': [ - 'android', 'asan', 'gn', 'debug_bot_minimal_symbols', + 'android_asan_gn_clang_shared_debug_minimal_symbols': [ + 'android', 'asan', 'gn', 'clang', 'shared', 'debug', 'minimal_symbols', ], - 'android_cast_gyp_debug_static_bot': [ - 'android', 'cast', 'gyp', 'debug_static_bot', + 'android_cast_gn_debug_static_bot': [ + 'android', 'cast', 'gn', 'clang', 'debug_static_bot', ], - 'android_clang_no_chrome_plugins_asan_gn_debug_bot_minimal_symbols': [ - 'android', 'clang_no_chrome_plugins', 'asan', 'gn', + 'android_clang_asan_findbugs_gn_debug_bot_minimal_symbols': [ + 'android', 'clang', 'asan', 'findbugs', 'gn', 'debug_bot_minimal_symbols', ], - 'android_clang_asan_findbugs_gyp_debug_bot_minimal_symbols': [ - 'android', 'clang', 'asan', 'findbugs', 'gyp', - 'debug_bot_minimal_symbols', + 'android_clang_asan_findbugs_gn_debug_trybot': [ + 'android', 'clang', 'asan', 'findbugs', 'gn', 'debug_trybot', ], - 'android_clang_asan_findbugs_gyp_debug_trybot': [ - 'android', 'clang', 'asan', 'findbugs', 'gyp', 'debug_trybot', + 'android_clang_tot_asan': [ + 'android_without_codecs', 'clang_tot', 'asan', 'gn', + 'shared', 'debug', 'minimal_symbols', ], 'android_cronet_data_reduction_proxy_gn_release_bot_minimal_symbols': [ @@ -935,10 +963,6 @@ 'android', 'gn', 'debug_static_bot', 'arm64', ], - 'android_gn_debug_static_bot_mipsel': [ - 'android', 'gn', 'debug_static_bot', 'mipsel', - ], - 'android_gn_debug_static_bot_x64': [ 'android', 'gn', 'debug_static_bot', 'x64', ], @@ -947,10 +971,26 @@ 'android', 'gn', 'debug_static_bot', 'x86', ], + 'android_gn_debug_static_minimal_symbols_mipsel': [ + 'android', 'gn', 'debug', 'static', 'minimal_symbols', 'mipsel', + ], + + 'android_gn_debug_static_trybot': [ + 'android', 'gn', 'debug_static_trybot', + ], + + 'android_gn_debug_static_trybot_arm64': [ + 'android', 'gn', 'debug_static_trybot', 'arm64', + ], + 'android_gn_debug_trybot': [ 'android', 'gn', 'debug_trybot', ], + 'android_gn_debug_trybot_java_coverage': [ + 'android', 'gn', 'debug_trybot', 'java_coverage', + ], + 'android_gn_debug_trybot_mipsel': [ 'android', 'gn', 'debug_trybot', 'mipsel', ], @@ -975,16 +1015,8 @@ 'android', 'gn', 'release_trybot', ], - 'android_gyp_debug_static_bot': [ - 'android', 'gyp', 'debug_static_bot', - ], - - 'android_gyp_debug_static_bot_arm64': [ - 'android', 'gyp', 'debug_static_bot', 'arm64', - ], - - 'android_without_codecs_gyp_release_bot_minimal_symbols': [ - 'android_without_codecs', 'gyp', 'release_bot_minimal_symbols', + 'android_without_codecs_gn_release_bot_minimal_symbols': [ + 'android_without_codecs', 'gn', 'release_bot_minimal_symbols', ], 'cast_gn_release_bot': [ @@ -995,6 +1027,14 @@ 'cast', 'gn', 'release_trybot', ], + 'chrome_with_codecs_blink_logging_gyp_release_trybot': [ + 'chrome_with_codecs', 'blink_logging', 'gyp', 'release_trybot', + ], + + 'chrome_with_codecs_blink_logging_gyp_release_trybot_x86': [ + 'chrome_with_codecs', 'blink_logging', 'gyp', 'release_trybot', 'x86', + ], + 'chromeos_gn_debug_bot': [ 'chromeos', 'gn', 'debug_bot', ], @@ -1007,8 +1047,21 @@ 'chromeos', 'ozone', 'gn', 'release_trybot', ], - 'embedded_gyp_debug_bot': [ - 'embedded', 'gyp', 'debug_bot', + 'closure_compilation': [ + # The closure bots run their own recipe and shouldn't go through MB. + 'gyp', 'error', + ], + + 'codesearch_gn': [ + # The Codesearch bots run their own recipe and invoke GN directly. + 'error', 'gn' + ], + + # The 'cros_chrome_sdk_* configs are placeholders that indicate + # that the GYP_DEFINES (or GN args) are set by the `cros chrome-sdk` + # wrapper and need to be looked at specially. + 'cros_chrome_sdk_gn': [ + 'gn', 'cros_chrome_sdk', ], # The 'findit' config is used by the *_variable_* bots, which run @@ -1020,39 +1073,37 @@ 'error', ], - # This is the "deployment" config for the blimp builds. Currently - # we want them to be debug, non-optimized builds (and we don't need any - # chrome branding), so we don't use the "official" mixin. - 'gn_blimp_debug': [ - 'gn', 'blimp', 'debug', - ], - - 'gn_cfi_release_bot': [ - 'gn', 'cfi', 'release_bot', + 'gn_cfi_diag_release_static': [ + 'gn', 'cfi', 'cfi_diag', 'release', 'static', ], - 'gn_cfi_release_trybot': [ - 'gn', 'cfi', 'release_trybot', + 'gn_cfi_release_static': [ + 'gn', 'cfi', 'release', 'static', ], - 'gn_cfi_diag_release_bot': [ - 'gn', 'cfi', 'cfi_diag', 'release_bot', + 'gn_cfi_release_static_dcheck_always_on': [ + 'gn', 'cfi', 'release', 'static', 'dcheck_always_on', ], 'gn_debug_bot': [ 'gn', 'debug_bot', ], - 'gn_debug_bot_minimal_symbols': [ - 'gn', 'debug_bot_minimal_symbols', + 'gn_debug_bot_minimal_symbols_chrome_with_codecs': [ + 'gn', 'debug_bot_minimal_symbols', 'chrome_with_codecs', ], 'gn_debug_bot_minimal_symbols_x86': [ 'gn', 'debug_bot_minimal_symbols', 'x86', ], - 'gn_debug_static_bot': [ - 'gn', 'debug_static_bot', + 'gn_debug_libfuzzer_asan': [ + 'gn', 'debug', 'libfuzzer', 'asan', 'proprietary_codecs', 'pdf_xfa', + 'disable_nacl', + ], + + 'gn_debug_static_bot_chrome_with_codecs': [ + 'gn', 'debug_static_bot', 'chrome_with_codecs', ], 'gn_linux_upload': [ @@ -1067,7 +1118,9 @@ 'gn', 'official', 'goma', ], - 'gn_official_goma_lto': ['gn', 'official', 'goma', 'lto'], + 'gn_official_goma_lto': [ + 'gn', 'official', 'goma', 'lto', + ], 'gn_official_goma_minimal_symbols_android': [ 'gn', 'official', 'goma', 'minimal_symbols', 'android', @@ -1081,22 +1134,166 @@ 'gn', 'release_bot', ], - 'gn_release_bot_minimal_symbols': [ - 'gn', 'release_bot_minimal_symbols', + 'gn_release_bot_chrome_with_codecs': [ + 'gn', 'release_bot', 'chrome_with_codecs', + ], + + 'gn_release_bot_minimal_symbols_chrome_with_codecs': [ + 'gn', 'release_bot_minimal_symbols', 'chrome_with_codecs', ], 'gn_release_bot_minimal_symbols_x86': [ 'gn', 'release_bot_minimal_symbols', 'x86', ], + 'gn_release_bot_x86': [ + 'gn', 'release_bot', 'x86', + ], + + 'gn_release_drmemory_drfuzz': [ + 'gn', 'release', 'drmemory', 'drfuzz', 'proprietary_codecs', + ], + + 'gn_release_drmemory_drfuzz_x86': [ + 'gn', 'release', 'drmemory', 'drfuzz', 'x86', 'proprietary_codecs', + ], + + 'gn_release_libfuzzer_asan': [ + 'gn', 'release', 'libfuzzer', 'asan', 'proprietary_codecs', 'pdf_xfa', + 'disable_nacl', + ], + + 'gn_release_libfuzzer_msan': [ + 'gn', 'release', 'libfuzzer', 'msan', 'proprietary_codecs', 'pdf_xfa', + 'disable_nacl', + ], + 'gn_release_libfuzzer_ubsan': [ + 'gn', 'release', 'libfuzzer', 'ubsan_security', 'proprietary_codecs', + 'pdf_xfa', 'disable_nacl', + ], + 'gn_release_trybot': [ 'gn', 'release_trybot', ], + 'gn_release_trybot_x64': [ + 'gn', 'release_trybot', 'x64', + ], + 'gn_release_trybot_x86': [ 'gn', 'release_trybot', 'x86', ], + 'gn_windows_analyze': [ + 'gn', 'no_symbols', 'disable_precompiled_headers', + 'shared', 'x86', 'win_analyze', + ], + + 'gn_ubsan_vptr_release_bot': [ + 'gn', 'ubsan_vptr', 'ubsan_no_recover_hack', 'release_bot', + ], + + 'gyp_asan_edge_fuzzer_v8_heap_chromeos_codecs_release_bot_hybrid': [ + 'gyp', 'asan', 'edge', 'fuzzer', 'v8_heap', 'chromeos_codecs', + 'release_bot', 'hybrid', + ], + + 'gyp_asan_edge_fuzzer_v8_heap_debug_bot_hybrid': [ + 'gyp', 'asan', 'edge', 'fuzzer', 'v8_heap', 'debug_bot', 'hybrid', + ], + + 'gyp_asan_edge_fuzzer_v8_heap_release_bot_hybrid': [ + 'gyp', 'asan', 'edge', 'fuzzer', 'v8_heap', 'release_bot', 'hybrid', + ], + + 'gyp_asan_edge_fuzzer_v8_heap_release_static_x86': [ + 'gyp', 'asan', 'edge', 'fuzzer', 'v8_heap', 'release', 'static', 'x86', + ], + + 'gyp_asan_edge_fuzzer_v8_heap_symbolized_release_bot_hybrid': [ + 'gyp', 'asan', 'edge', 'fuzzer', 'v8_heap', 'symbolized', + 'release_bot', 'hybrid', + ], + + 'gyp_asan_fuzzer_v8_heap_chrome_with_codecs_release_bot': [ + 'gyp', 'asan', 'fuzzer', 'v8_heap', 'chrome_with_codecs', 'release_bot', + ], + + 'gyp_asan_fuzzer_v8_heap_chrome_with_codecs_release_static_x86': [ + 'gyp', 'asan', 'fuzzer', 'v8_heap', 'chrome_with_codecs', + 'release', 'static', 'x86', + ], + + 'gyp_asan_fuzzer_v8_heap_debug_symbols_static_bot': [ + 'gyp', 'asan', 'fuzzer', 'v8_heap', 'debug_symbols_static_bot', + ], + + 'gyp_asan_fuzzer_v8_heap_release_bot': [ + 'gyp', 'asan', 'fuzzer', 'v8_heap', 'release_bot', + ], + + 'gyp_asan_fuzzer_v8_heap_release_static_x86': [ + 'gyp', 'asan', 'fuzzer', 'v8_heap', 'release', 'static', 'x86', + ], + + 'gyp_asan_lsan_edge_fuzzer_debug_bot': [ + 'gyp', 'asan', 'lsan', 'edge', 'fuzzer', 'debug_bot', + ], + + 'gyp_asan_lsan_edge_fuzzer_v8_heap_chromeos_codecs_release_bot': [ + 'gyp', 'asan', 'lsan', 'edge', 'v8_heap', 'chromeos_codecs', + 'release_bot', + ], + + 'gyp_asan_lsan_edge_fuzzer_v8_heap_release_bot': [ + 'gyp', 'asan', 'lsan', 'edge', 'fuzzer', 'v8_heap', 'release_bot', + ], + + 'gyp_asan_lsan_edge_fuzzer_v8_heap_symbolized_release_bot': [ + 'gyp', 'asan', 'lsan', 'edge', 'v8_heap', 'symbolized', 'release_bot', + ], + + 'gyp_chromeos_asan_lsan_edge_fuzzer_v8_heap_release_bot': [ + 'gyp', 'chromeos', 'asan', 'lsan', 'edge', 'fuzzer', 'v8_heap', + 'release_bot', + ], + + 'gyp_chromeos_with_codecs_debug_bot': [ + 'gyp', 'chromeos_with_codecs', 'debug_bot', + ], + + 'gyp_clang_minimal_symbols_shared_release_bot_x86': [ + 'gyp', 'clang', 'minimal_symbols', 'shared_release_bot', 'x86', + ], + + 'gyp_debug_bot': [ + 'gyp', 'debug_bot', + ], + + 'gyp_debug_bot_minimal_symbols_x64': [ + 'gyp', 'debug_bot_minimal_symbols', 'x64', + ], + + 'gyp_debug_bot_minimal_symbols_x86': [ + 'gyp', 'debug_bot_minimal_symbols', 'x86', + ], + + 'gyp_drmemory_shared_release_x86': [ + 'gyp', 'drmemory', 'shared', 'release', 'x86', + ], + + 'gyp_drmemory_shared_release_x64': [ + 'gyp', 'drmemory', 'shared', 'release', 'x64', + ], + + 'gyp_msan_edge_release_bot': [ + 'gyp', 'msan', 'edge', 'release_bot', + ], + + 'gyp_msan_no_origins_edge_release_bot': [ + 'gyp', 'msan_no_origins', 'edge', 'release_bot', + ], + 'gyp_official': [ 'gyp', 'official', ], @@ -1135,8 +1332,12 @@ 'gyp', 'official', 'x64', ], - 'gyp_release_bot_android': [ - 'gyp', 'release_bot', 'android', + 'gyp_release_bot': [ + 'gyp', 'release_bot', + ], + + 'gyp_release_bot_minimal_symbols_x86': [ + 'gyp', 'release_bot_minimal_symbols', 'x86' ], 'gyp_release_trybot': [ @@ -1147,46 +1348,28 @@ 'gyp', 'release_trybot', 'x64', ], - 'gn_release_libfuzzer_asan': [ - 'gn', 'release', 'libfuzzer', 'asan', 'proprietary_codecs', 'pdf_xfa', - 'disable_nacl', - ], - - 'gn_release_libfuzzer_msan': [ - 'gn', 'release', 'libfuzzer', 'msan', 'proprietary_codecs', 'pdf_xfa', - 'disable_nacl', - ], - 'gn_release_libfuzzer_ubsan': [ - 'gn', 'release', 'libfuzzer', 'ubsan_security', 'proprietary_codecs', - 'pdf_xfa', 'disable_nacl', - ], - - 'gn_release_drmemory_drfuzz_x86': [ - 'gn', 'release', 'drmemory', 'drfuzz', 'x86', 'proprietary_codecs', - ], - 'gn_release_drmemory_drfuzz': [ - 'gn', 'release', 'drmemory', 'drfuzz', 'proprietary_codecs', + 'gyp_shared_release_bot_minimal_symbols_x86': [ + 'gyp', 'shared_release_bot', 'minimal_symbols', 'x86', ], - 'gn_windows_analyze': [ - 'gn', 'no_symbols', 'disable_precompiled_headers', - 'shared', 'x86', 'win_analyze', + 'gyp_syzyasan_no_pch_win_z7_x86': [ + 'gyp', 'syzyasan', 'no_pch', 'win_z7', 'x86', ], - 'gyp_valgrind_release_bot': [ - 'gyp', 'valgrind', 'release_bot', + 'gyp_tsan_disable_nacl_line_tables_debug_bot': [ + 'gyp', 'tsan', 'disable_nacl', 'line_tables', 'debug_bot', ], - 'gyp_valgrind_chromeos_release_bot': [ - 'gyp', 'chromeos', 'valgrind', 'release_bot', + 'gyp_tsan_disable_nacl_line_tables_release_bot': [ + 'gyp', 'tsan', 'disable_nacl', 'line_tables', 'release_bot', ], - 'gyp_drmemory_shared_release_x86': [ - 'gyp', 'drmemory', 'shared', 'release', 'x86', + 'gyp_ubsan_release_bot': [ + 'gyp', 'ubsan', 'release_bot', ], - 'gyp_drmemory_shared_release_x64': [ - 'gyp', 'drmemory', 'shared', 'release', 'x64', + 'gyp_ubsan_vptr_edge_release_bot': [ + 'gyp', 'ubsan_vptr', 'edge', 'release_bot', ], # The 'ios' configs are just used for auditing. iOS bots @@ -1198,6 +1381,10 @@ 'ios_gyp': ['gyp', 'error'], + 'mac_views_browser_gyp_release_bot': [ + 'mac_views_browser', 'gyp', 'release_bot', + ], + # This is used to indicate that the bot runs the nacl annotator-based # configs and switching them is out of scope for MB. 'nacl_annotator': [ 'error' ], @@ -1208,10 +1395,22 @@ 'error', ], + 'noswarming_gn_debug_bot_x64': [ + 'noswarming', 'gn', 'debug_bot', 'x64', + ], + 'noswarming_gn_release_bot': [ 'noswarming', 'gn', 'release_bot', ], + 'noswarming_gn_release_bot_minimal_symbols_x64': [ + 'noswarming', 'gn', 'release_bot', 'minimal_symbols', 'x64', + ], + + 'noswarming_gn_release_bot_x64': [ + 'noswarming', 'gn', 'release_bot', 'x64', + ], + 'noswarming_gyp_release_bot_mac_strip': [ 'noswarming', 'gyp', 'release_bot', 'mac_strip', ], @@ -1220,42 +1419,78 @@ 'noswarming', 'gyp', 'release_bot', 'minimal_symbols', 'x86', ], - 'noswarming_gyp_release_trybot_minimal_symbols_x86': [ - 'noswarming', 'gyp', 'release_trybot', 'minimal_symbols', 'x86', + 'noswarming_gyp_release_bot_x64': [ + 'noswarming', 'gyp', 'release_bot', 'x64', ], - 'swarming_android_gn_release_bot_minimal_symbols': [ - 'swarming', 'android', 'gn', 'release_bot_minimal_symbols', + 'noswarming_gyp_release_trybot': [ + 'noswarming', 'gyp', 'release_trybot', + ], + + 'noswarming_gyp_release_trybot_x64': [ + 'noswarming', 'gyp', 'release_trybot', 'x64', + ], + + 'noswarming_gyp_release_trybot_x86': [ + 'noswarming', 'gyp', 'release_trybot', 'x86', + ], + + 'swarming_android_gn_debug_static_bot': [ + 'swarming', 'android', 'gn', 'debug_static_bot', ], - 'swarming_android_gyp_debug_static_bot': [ - 'swarming', 'android', 'gyp', 'debug_static_bot', + 'swarming_android_gn_debug_static_bot_arm64': [ + 'swarming', 'android', 'gn', 'debug_static_bot', 'arm64', ], - 'swarming_android_gyp_debug_static_bot_arm64': [ - 'swarming', 'android', 'gyp', 'debug_static_bot', 'arm64', + 'swarming_android_gn_debug_trybot': [ + 'swarming', 'android', 'gn', 'debug_trybot', ], - 'swarming_android_gyp_debug_trybot': [ - 'swarming', 'android', 'gyp', 'debug_trybot', + 'swarming_android_gn_debug_trybot_arm64': [ + 'swarming', 'android', 'gn', 'debug_trybot', 'arm64', ], - 'swarming_android_gyp_debug_trybot_arm64': [ - 'swarming', 'android', 'gyp', 'debug_trybot', 'arm64', + 'swarming_android_gn_release_bot_minimal_symbols': [ + 'swarming', 'android', 'gn', 'release_bot_minimal_symbols', + ], + + 'swarming_android_gn_release_bot_minimal_symbols_arm64': [ + 'swarming', 'android', 'gn', 'release_bot_minimal_symbols', 'arm64', ], - 'swarming_android_gyp_release_bot_minimal_symbols': [ - 'swarming', 'android', 'gyp', 'release_bot_minimal_symbols', + 'swarming_android_gn_release_trybot': [ + 'swarming', 'android', 'gn', 'release_trybot', ], - 'swarming_android_gyp_release_trybot': [ - 'swarming', 'android', 'gyp', 'release_trybot', + 'swarming_asan_dcheck_gyp_release_bot': [ + 'swarming', 'asan', 'dcheck_always_on', 'gyp', 'release_bot', + ], + + 'swarming_asan_lsan_chromeos_gyp_release_trybot': [ + 'swarming', 'asan', 'lsan', 'chromeos', 'release_trybot', ], 'swarming_asan_lsan_gyp_release_trybot': [ 'swarming', 'asan', 'lsan', 'release_trybot', ], + 'swarming_chromeos_gn_release_trybot': [ + 'swarming', 'chromeos_with_codecs', 'gn', 'release_trybot', + ], + + 'swarming_chromeos_gyp_debug_bot': [ + 'swarming', 'chromeos_with_codecs', 'gyp', 'debug_bot', + ], + + 'swarming_chromeos_gyp_debug_trybot': [ + 'swarming', 'chromeos_with_codecs', 'gyp', 'debug_trybot', + ], + + 'swarming_chromeos_gyp_ozone_release_trybot': [ + 'swarming', 'chromeos_with_codecs', 'gyp', 'ozone', 'release_trybot', + ], + 'swarming_chromeos_gyp_release_bot': [ 'swarming', 'chromeos_with_codecs', 'gyp', 'release_bot', ], @@ -1264,31 +1499,87 @@ 'swarming', 'chromeos_with_codecs', 'gyp', 'release_trybot', ], - 'swarming_msan_gyp_release_trybot': [ + 'swarming_chromeos_msan_gyp_release_trybot': [ 'swarming', 'chromeos', 'msan', 'gyp', 'release_trybot', ], - 'swarming_gn_asan_lsan_release_bot_x64': [ - 'swarming', 'gn', 'asan', 'lsan', 'release_bot', 'x64', + 'swarming_chromeos_ozone_gyp_release_bot': [ + 'chromeos_with_codecs', 'goma', 'gyp', 'ozone', 'static', 'swarming', ], - 'swarming_gn_msan_release_bot_x64': [ - 'swarming', 'gn', 'msan', 'release_bot', 'x64', + 'swarming_clang_tot_lld_release_shared': [ + # TODO(crbug.com/605819): Enable debug info in release builds. + 'swarming', 'gn', 'clang_tot', 'release', 'shared', 'use_lld', ], - 'swarming_gpu_fyi_tests_gn_debug_bot': [ - 'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn', - 'debug_bot', 'angle_deqp_tests', + 'swarming_clang_tot_shared_debug': [ + 'swarming', 'gn', 'clang_tot', 'shared', 'debug', ], - 'swarming_gpu_fyi_tests_gn_debug_trybot': [ - 'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn', - 'debug_trybot', 'angle_deqp_tests', + 'swarming_gn_asan_lsan_release_bot': [ + 'swarming', 'gn', 'asan', 'lsan', 'release_bot', + ], + + 'swarming_gn_debug_bot': [ + 'swarming', 'gn', 'debug_bot', + ], + + 'swarming_gn_debug_bot_minimal_symbols_x64': [ + 'swarming', 'gn', 'debug_bot_minimal_symbols', 'x64', + ], + + 'swarming_gn_debug_bot_x86': [ + 'swarming', 'gn', 'debug_bot', 'x86', + ], + + 'swarming_gn_debug_trybot': [ + 'swarming', 'gn', 'debug_trybot', + ], + + 'swarming_gn_debug_trybot_x86': [ + 'swarming', 'gn', 'debug_trybot', 'x86', + ], + + 'swarming_gn_msan_release_bot': [ + 'swarming', 'gn', 'msan', 'release_bot', + ], + + 'swarming_gn_release_bot': [ + 'swarming', 'gn', 'release_bot', + ], + + 'swarming_gn_release_bot_arm': [ + 'swarming', 'gn', 'release_bot', 'arm', 'crosscompile', + ], + + 'swarming_gn_release_bot_minimal_symbols': [ + 'swarming', 'gn', 'release_bot_minimal_symbols', + ], + + 'swarming_gn_release_bot_minimal_symbols_x64': [ + 'swarming', 'gn', 'release_bot_minimal_symbols', 'x64', + ], + + 'swarming_gn_release_bot_x64': [ + 'swarming', 'gn', 'release_bot', 'x64', ], - 'swarming_gpu_fyi_tests_gn_release_bot': [ + 'swarming_gn_release_trybot': [ + 'swarming', 'gn', 'release_bot', + ], + + 'swarming_gn_release_trybot_x64': [ + 'swarming', 'gn', 'release_trybot', 'x64', + ], + + 'swarming_gpu_fyi_tests_chromeos_gyp_release_trybot': [ + 'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gyp', + 'release_trybot', 'angle_deqp_tests', 'chromeos', + ], + + 'swarming_gpu_fyi_tests_gn_debug_trybot': [ 'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn', - 'release_bot', 'angle_deqp_tests', + 'debug_trybot', 'angle_deqp_tests', ], 'swarming_gpu_fyi_tests_gn_release_trybot': [ @@ -1296,103 +1587,115 @@ 'release_bot', 'angle_deqp_tests', ], - 'swarming_gpu_tests_deqp_gles_gyp_debug_bot_minimal_symbols_x64': [ - 'swarming', 'gpu_tests', 'angle_deqp_tests', - 'internal_gles2_conform_tests', 'gyp', 'debug_bot', - 'minimal_symbols', 'x64', + 'swarming_gpu_fyi_tests_gyp_clang_debug_trybot_x86': [ + 'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gyp', + 'clang', 'debug_trybot', 'x86', ], - 'swarming_gpu_tests_deqp_gles_gyp_debug_bot_minimal_symbols_x86': [ - 'swarming', 'gpu_tests', 'angle_deqp_tests', - 'internal_gles2_conform_tests', 'gyp', 'debug_bot', - 'minimal_symbols', 'x86', + 'swarming_gpu_fyi_tests_gyp_debug_trybot': [ + 'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gyp', + 'debug_trybot', ], - 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_minimal_symbols_x64': [ - 'swarming', 'gpu_tests', 'angle_deqp_tests', - 'internal_gles2_conform_tests', 'gyp', 'release_trybot', - 'minimal_symbols', 'x64', + 'swarming_gpu_fyi_tests_gyp_release_trybot': [ + 'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gyp', + 'release_trybot', ], - 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_minimal_symbols_x86': [ + 'swarming_gpu_tests_deqp_gles_gyp_debug_trybot_x64': [ 'swarming', 'gpu_tests', 'angle_deqp_tests', - 'internal_gles2_conform_tests', 'gyp', 'release_trybot', - 'minimal_symbols', 'x86', + 'internal_gles2_conform_tests', 'gyp', 'debug_trybot', 'x64', ], - 'swarming_gpu_tests_deqp_gles_gyp_release_bot_minimal_symbols_x64': [ + 'swarming_gpu_tests_deqp_gles_gyp_debug_trybot_x86': [ 'swarming', 'gpu_tests', 'angle_deqp_tests', - 'internal_gles2_conform_tests', 'gyp', 'release_bot', - 'minimal_symbols', 'x64', + 'internal_gles2_conform_tests', 'gyp', 'debug_trybot', 'x86', ], - 'swarming_gpu_tests_deqp_gles_gyp_release_bot_minimal_symbols_x86': [ + 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_x64': [ 'swarming', 'gpu_tests', 'angle_deqp_tests', - 'internal_gles2_conform_tests', 'gyp', 'release_bot', - 'minimal_symbols', 'x86', + 'internal_gles2_conform_tests', 'gyp', 'release_trybot', 'x64', ], - 'swarming_gpu_tests_gn_debug_bot': [ - 'swarming', 'gpu_tests', 'gn', 'debug_bot', + 'swarming_gpu_tests_deqp_gles_gyp_release_trybot_x86': [ + 'swarming', 'gpu_tests', 'angle_deqp_tests', + 'internal_gles2_conform_tests', 'gyp', 'release_trybot', 'x86', ], - 'swarming_gpu_tests_gn_release_bot': [ - 'swarming', 'gpu_tests', 'gn', 'release_bot', + 'swarming_gpu_tests_gn_debug_trybot': [ + 'swarming', 'gpu_tests', 'gn', 'debug_trybot', ], 'swarming_gpu_tests_gn_release_trybot': [ 'swarming', 'gpu_tests', 'gn', 'release_trybot', ], - 'swarming_gpu_tests_gyp_debug_bot_minimal_symbols_x86': [ - 'swarming', 'gpu_tests', 'gyp', 'debug_bot', 'minimal_symbols', 'x86', + 'swarming_gpu_tests_gyp_debug_trybot': [ + 'swarming', 'gpu_tests', 'gyp', 'debug_trybot', ], - 'swarming_gpu_tests_gyp_release_bot_minimal_symbols_x86': [ - 'swarming', 'gpu_tests', 'gyp', 'release_bot', 'minimal_symbols', 'x86', + 'swarming_gpu_tests_gyp_debug_trybot_x86': [ + 'swarming', 'gpu_tests', 'gyp', 'debug_trybot', 'x86', ], - 'swarming_gpu_tests_gyp_release_trybot_minimal_symbols_x86': [ - 'swarming', 'gpu_tests', 'gyp', 'release_trybot', 'minimal_symbols', - 'x86', + 'swarming_gpu_tests_gyp_release_bot': [ + 'swarming', 'gpu_tests', 'gyp', 'release_bot', ], - 'swarming_gn_debug_bot': [ - 'swarming', 'gn', 'debug_bot', + 'swarming_gpu_tests_gyp_release_bot_minimal_symbols_x86': [ + 'swarming', 'gpu_tests', 'gyp', 'release_bot', 'minimal_symbols', 'x86', ], - 'swarming_gn_debug_bot_minimal_symbols_x64': [ - 'swarming', 'gn', 'debug_bot_minimal_symbols', 'x64', + 'swarming_gpu_tests_gyp_release_bot_x86': [ + 'swarming', 'gpu_tests', 'gyp', 'release_bot', ], - 'swarming_gn_debug_bot_x64': [ - 'swarming', 'gn', 'debug_bot', 'x64', + 'swarming_gpu_tests_gyp_release_trybot': [ + 'swarming', 'gpu_tests', 'gyp', 'release_trybot', ], - 'swarming_gn_debug_trybot': [ - 'swarming', 'gn', 'debug_trybot', + 'swarming_gpu_tests_gyp_release_trybot_x86': [ + 'swarming', 'gpu_tests', 'gyp', 'release_trybot', 'x86', ], - 'swarming_gn_release_bot': [ - 'swarming', 'gn', 'release_bot', + ('swarming_gyp_asan_clang_edge_fuzzer' + '_static_v8_heap_x86_full_symbols_release'): [ + 'swarming', 'gyp', 'asan', 'clang_tot', 'edge', 'fuzzer', 'static', + 'v8_heap', 'full_symbols', 'release', ], - 'swarming_gn_release_bot_x64': [ - 'swarming', 'gn', 'release_bot', 'x64', + 'swarming_gyp_asan_clang_fuzzer_shared_v8_heap_x86_full_symbols_release': [ + 'swarming', 'gyp', 'asan', 'clang_tot', 'fuzzer', 'shared', 'v8_heap', + 'full_symbols', 'release', ], - 'swarming_gn_release_trybot': [ - 'swarming', 'gn', 'release_bot', + 'swarming_gyp_asan_clang_fuzzer_static_v8_heap_x86_full_symbols_release': [ + 'swarming', 'gyp', 'asan', 'clang_tot', 'fuzzer', 'static', 'v8_heap', + 'full_symbols', 'release', ], - 'swarming_gn_release_trybot_minimal_symbols_x64': [ - 'swarming', 'gn', 'release_trybot', 'minimal_symbols', 'x64', + 'swarming_gyp_asan_clang_tot_full_symbols_static_release': [ + 'swarming', 'gyp', 'asan', 'clang_tot', 'full_symbols', 'static', + 'release', + ], + + 'swarming_gyp_chromeos_msan_release_bot': [ + 'swarming', 'gyp', 'chromeos', 'msan', 'release_bot', ], 'swarming_gyp_clang_debug_bot_minimal_symbols_x86': [ 'swarming', 'gyp', 'clang', 'debug_bot', 'minimal_symbols', 'x86', ], + 'swarming_gyp_clang_debug_trybot_x86': [ + 'swarming', 'gyp', 'clang', 'debug_trybot', 'x86', + ], + + 'swarming_gyp_clang_minimal_symbols_shared_release_bot_x64': [ + 'swarming', 'gyp', 'clang', 'minimal_symbols', 'shared_release_bot', + 'x64', + ], + 'swarming_gyp_clang_official_release_bot_minimal_symbols_x64': [ 'swarming', 'gyp', 'clang', 'official', 'release_bot', 'minimal_symbols', 'x64', @@ -1403,98 +1706,144 @@ 'minimal_symbols', 'x86', ], - 'swarming_gyp_clang_official_release_trybot_minimal_symbols_x64': [ - 'swarming', 'gyp', 'clang', 'official', 'release_trybot', - 'minimal_symbols', 'x64', + 'swarming_gyp_clang_official_release_trybot_x64': [ + 'swarming', 'gyp', 'clang', 'official', 'release_trybot', 'x64', ], - 'swarming_gyp_clang_official_release_trybot_minimal_symbols_x86': [ - 'swarming', 'gyp', 'clang', 'official', 'release_trybot', - 'minimal_symbols', 'x86', + 'swarming_gyp_clang_official_release_trybot_x86': [ + 'swarming', 'gyp', 'clang', 'official', 'release_trybot', 'x86', ], - 'swarming_gyp_debug_bot_minimal_symbols_x64': [ - 'swarming', 'gyp', 'debug_bot_minimal_symbols', 'x64', + 'swarming_gyp_clang_shared_release_bot_minimal_symbols_x86': [ + 'swarming', 'gyp', 'clang', 'shared_release_bot', 'minimal_symbols', + 'x86', ], - 'swarming_gyp_debug_bot_minimal_symbols_x86': [ - 'swarming', 'gyp', 'debug_bot_minimal_symbols', 'x86', + 'swarming_gyp_clang_tot_asan_lsan_static_release': [ + 'swarming', 'gyp', 'clang_tot', 'asan', 'lsan', 'static', 'release', ], - 'swarming_gyp_debug_bot_no_symbols_x86': [ - 'swarming', 'gyp', 'debug_bot', 'no_symbols', 'x86', + 'swarming_gyp_clang_tot_edge_ubsan_no_recover_hack_static_release': [ + 'swarming', 'gyp', 'clang_tot', 'edge', 'ubsan_no_recover_hack', + 'static', 'release', ], - 'swarming_gyp_debug_bot_x64': [ - 'swarming', 'gyp', 'debug_bot', 'x64', + 'swarming_gyp_clang_tot_linux_dump_symbols_shared_release': [ + # Enable debug info, as on official builders, to catch issues with + # optimized debug info. + 'swarming', 'gyp', 'clang_tot', 'linux_dump_symbols', + 'shared', 'release', ], - 'swarming_gyp_debug_trybot_x86': [ - 'swarming', 'gyp', 'debug_trybot', 'x86', + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'debug', ], - 'swarming_gyp_release_bot': [ - 'swarming', 'gyp', 'release_bot', + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug_use_lld_x64': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'debug', + 'use_lld', 'x64', ], - 'swarming_gyp_release_bot_arm': [ - 'swarming', 'gyp', 'release_bot', 'arm', 'crosscompile', + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug_use_lld_x86': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'debug', + 'use_lld', 'x86', ], - 'swarming_gyp_release_bot_minimal_symbols_x64': [ - 'swarming', 'gyp', 'release_bot_minimal_symbols', 'x64', + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug_x64': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'debug', + 'x64', ], - 'swarming_gyp_release_bot_minimal_symbols_x86': [ - 'swarming', 'gyp', 'release_bot_minimal_symbols', 'x86', + 'swarming_gyp_clang_tot_minimal_symbols_shared_debug_x86': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'debug', + 'x86', ], - 'swarming_gyp_release_bot_x64': [ - 'swarming', 'gyp', 'release_bot', 'x64', + 'swarming_gyp_clang_tot_minimal_symbols_shared_release_use_lld_x64': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'release', + 'use_lld', 'x64', ], - 'swarming_gyp_release_trybot_arm': [ - 'swarming', 'gyp', 'release_trybot', 'arm', 'crosscompile', + 'swarming_gyp_clang_tot_minimal_symbols_shared_release_use_lld_x86': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'release', + 'use_lld', 'x86', ], - 'swarming_gyp_release_trybot_minimal_symbols_x64': [ - 'swarming', 'gyp', 'release_trybot', 'minimal_symbols', 'x64', + 'swarming_gyp_clang_tot_minimal_symbols_shared_release': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'release', ], - 'swarming_gyp_release_trybot_minimal_symbols_x86': [ - 'swarming', 'gyp', 'release_trybot', 'minimal_symbols', 'x86', + 'swarming_gyp_clang_tot_minimal_symbols_shared_release_x64': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'release', + 'x64', ], - 'swarming_gyp_syzyasan_release_trybot_minimal_symbols_x86': [ - 'swarming', 'gyp', 'syzyasan', 'release_trybot', 'minimal_symbols', + 'swarming_gyp_clang_tot_minimal_symbols_shared_release_x86': [ + 'swarming', 'gyp', 'clang_tot', 'minimal_symbols', 'shared', 'release', 'x86', ], - 'swarming_tsan_gyp_release_trybot': [ - 'swarming', 'disable_nacl', 'tsan', 'gyp', 'release_trybot', + 'swarming_gyp_clang_tot_official_minimal_symbols_static_release_x64': [ + 'swarming', 'gyp', 'clang_tot', 'official', 'minimal_symbols', 'static', + 'release', 'x64', ], - 'gn_debug_bot_minimal_symbols_chrome_with_codecs': [ - 'gn', 'debug_bot_minimal_symbols', 'chrome_with_codecs', + 'swarming_gyp_clang_tot_official_minimal_symbols_static_release_x86': [ + 'swarming', 'gyp', 'clang_tot', 'official', 'minimal_symbols', 'static', + 'release', 'x86', ], - 'gn_debug_static_bot_chrome_with_codecs': [ - 'gn', 'debug_static_bot', 'chrome_with_codecs', + 'swarming_gyp_debug_bot': [ + 'swarming', 'gyp', 'debug_bot', ], - 'gn_release_bot_chrome_with_codecs': [ - 'gn', 'release_bot', 'chrome_with_codecs', + 'swarming_gyp_debug_bot_minimal_symbols_x86': [ + 'swarming', 'gyp', 'debug_bot_minimal_symbols', 'x86', ], - 'gn_release_bot_minimal_symbols_chrome_with_codecs': [ - 'gn', 'release_bot_minimal_symbols', 'chrome_with_codecs', + 'swarming_gyp_debug_trybot': [ + 'swarming', 'gyp', 'debug_trybot', + ], + + 'swarming_gyp_debug_trybot_x86': [ + 'swarming', 'gyp', 'debug_trybot', 'x86', + ], + + 'swarming_gyp_msan_release_bot': [ + 'swarming', 'gyp', 'msan', 'release_bot', + ], + + 'swarming_gyp_release_bot': [ + 'swarming', 'gyp', 'release_bot', ], - # This indicates that we haven't yet set up this bot w/ MB. This is - # different from 'none' in that a bot set to 'none' should never do - # compiles; a bot set to 'tbd' should do compiles but we haven't - # added the entries yet. - 'tbd': ['error'], + 'swarming_gyp_release_bot_minimal_symbols': [ + 'swarming', 'gyp', 'release_bot_minimal_symbols', + ], + + 'swarming_gyp_release_bot_minimal_symbols_x86': [ + 'swarming', 'gyp', 'release_bot_minimal_symbols', 'x86', + ], + + 'swarming_gyp_release_trybot_arm': [ + 'swarming', 'gyp', 'release_trybot', 'arm', 'crosscompile', + ], + + 'swarming_gyp_syzyasan_release_trybot_x86': [ + 'swarming', 'gyp', 'syzyasan', 'release_trybot', 'x86', + ], + + 'swarming_gyp_tsan_disable_nacl_release_bot': [ + 'swarming', 'gyp', 'tsan', 'disable_nacl', 'release_bot', + ], + + 'swarming_gyp_tsan_disable_nacl_release_trybot': [ + 'swarming', 'gyp', 'tsan', 'disable_nacl', 'release_trybot', + ], + + 'swarming_msan_gyp_release_trybot': [ + 'swarming', 'msan', 'gyp', 'release_trybot', + ], 'win_clang_debug_bot': [ 'gn', 'clang', 'debug_bot_minimal_symbols', @@ -1547,14 +1896,19 @@ 'gyp_defines': 'asan=1', }, - # Removes dependencies on X11 and audio libraries for a containerized - # build. - 'blimp': { - 'gn_args': ('use_aura=true use_ozone=true use_alsa=false ' - 'use_pulseaudio=false use_cups=false use_glib=false ' - 'use_low_quality_image_interpolation=true'), - 'gyp_defines': ('use_aura=1 use_ozone=1 use_alsa=0 ' - 'use_pulseaudio=0 use_cups=0 use_glib=0'), + 'blink_logging': { + 'gn_args': 'blink_logging_always_on=true', + 'gyp_defines': 'blink_logging_always_on=1', + }, + + 'ffmpeg_branding_chrome': { + 'gn_args': 'ffmpeg_branding="Chrome"', + 'gyp_defines': 'ffmpeg_branding=Chrome', + }, + + 'ffmpeg_branding_chromeos': { + 'gn_args': 'ffmpeg_branding="ChromeOS"', + 'gyp_defines': 'ffmpeg_branding=ChromeOS', }, 'cast': { @@ -1573,8 +1927,7 @@ }, 'chrome_with_codecs': { - 'gn_args': 'ffmpeg_branding="Chrome" proprietary_codecs=true', - 'gyp_defines': 'ffmpeg_branding=Chrome proprietary_codecs=1', + 'mixins': ['ffmpeg_branding_chrome', 'proprietary_codecs'], }, 'chromeos': { @@ -1582,15 +1935,17 @@ 'gyp_defines': 'chromeos=1', }, + 'chromeos_codecs': { + 'mixins': ['ffmpeg_branding_chromeos', 'proprietary_codecs'], + }, + 'chromeos_with_codecs': { - 'gn_args': 'ffmpeg_branding="ChromeOS" proprietary_codecs=true', - 'gyp_defines': 'ffmpeg_branding=ChromeOS proprietary_codecs=1', - 'mixins': ['chromeos'], + 'mixins': ['chromeos', 'chromeos_codecs'], }, - 'clang_no_chrome_plugins': { - 'gn_args': 'clang_use_chrome_plugins=false', - 'gyp_defines': 'clang_use_chrome_plugins=0', + 'clang_tot': { + 'gn_args': 'llvm_force_head_revision=true clang_use_chrome_plugins=false', + 'gyp_defines': 'llvm_force_head_revision=1 clang_use_chrome_plugins=0', 'mixins': ['clang'], }, @@ -1601,9 +1956,22 @@ 'cronet': { 'gn_args': ('disable_file_support=true disable_ftp_support=true ' - 'enable_websockets=false'), + 'enable_websockets=false use_platform_icu_alternatives=true ' + 'disable_brotli_filter=true'), 'gyp_defines': ('disable_file_support=1 disable_ftp_support=1 ' - 'enable_websockets=0'), + 'enable_websockets=0 use_platform_icu_alternatives=1 ' + 'disable_brotli_filter=1'), + }, + + 'cros_chrome_sdk': { + # This is used so that the cros chrome_sdk (simplechrome) builders + # can manage the list of GYP_DEFINES and gn args in their .ebuild + # files and just pass through the desired arguments, hence not + # really using MB. If a bot uses this mixin, we expect that + # both GYP_DEFINES and GN_ARGS are set in the environment, + # and that GYP_DEFINES has chromeos=1 and GN_ARGS has + # target_os="chromeos" in it. + 'cros_passthrough': True, }, 'crosscompile': { @@ -1636,10 +2004,19 @@ 'mixins': ['debug_bot', 'minimal_symbols'], }, + 'debug_symbols_static_bot': { + 'mixins': ['debug', 'static', 'goma'], + }, + 'debug_static_bot': { 'mixins': ['debug', 'static', 'minimal_symbols', 'goma'], }, + 'debug_static_trybot': { + 'mixins': ['debug', 'static', 'dcheck_always_on', 'minimal_symbols', + 'goma'], + }, + 'debug_trybot': { 'mixins': ['debug_bot_minimal_symbols'], }, @@ -1654,9 +2031,9 @@ 'gyp_defines': 'chromium_win_pch=0', }, - 'embedded': { - 'gn_args': 'error', - 'gyp_defines': 'embedded=1', + 'edge': { + 'gn_args': 'sanitizer_coverage_flags="edge"', + 'gyp_defines': 'sanitizer_coverage=edge', }, # This mixin is used to force configs that use it to fail. It @@ -1668,11 +2045,26 @@ 'gyp_defines': 'target_arch=unknown', }, + 'ffmpeg_branding_chromeos': { + 'gn_args': 'ffmpeg_branding="ChromeOS"', + 'gyp_defines': 'ffmpeg_branding=ChromeOS', + }, + 'findbugs': { 'gn_args': 'run_findbugs=true', 'gyp_defines': 'run_findbugs=1', }, + 'full_symbols': { + 'gn_args': 'symbol_level=2', + 'gyp_defines': 'fastbuild=0', + }, + + 'fuzzer': { + 'gn_args': 'error', # TODO(GYP): implement enable_ipc_fuzzer=true + 'gyp_defines': 'enable_ipc_fuzzer=1', + }, + 'gn_linux_upload': { 'type': 'gn', @@ -1688,8 +2080,8 @@ 'goma': { # The MB code will properly escape goma_dir if necessary in the GYP # code path; the GN code path needs no escaping. - 'gn_args': 'use_goma=true goma_dir="$(goma_dir)"', - 'gyp_defines': 'use_goma=1 gomadir=$(goma_dir)', + 'gn_args': 'use_goma=true', + 'gyp_defines': 'use_goma=1', }, 'gpu_tests': { @@ -1698,13 +2090,33 @@ 'gyp': {'type': 'gyp'}, + 'hybrid': { + 'gn_args': 'error', # TODO(GYP): figure out the equivalent for this + 'gyp_defines': 'v8_target_arch=arm target_arch=ia32 host_arch=x86_64', + 'mixins': ['disable_nacl'], + }, + 'internal_gles2_conform_tests': { 'gn_args': 'internal_gles2_conform_tests=true', 'gyp_defines': 'internal_gles2_conform_tests=1', }, + 'java_coverage': { + 'gn_args': 'emma_coverage=true emma_filter="org.chromium.*"', + }, + 'libfuzzer': { 'gn_args': 'use_libfuzzer=true' }, + 'line_tables': { + 'gn_args': '', # TODO(GYP): check that this is not needed + 'gyp_defines': 'debug_extra_cflags="-gline-tables-only"', + }, + + 'linux_dump_symbols': { + 'gn_args': 'error', # TODO(crbug.com/605819): implement this. + 'gyp_defines': 'linux_dump_symbols=1', + }, + 'ubsan_security': { 'gn_args': 'is_ubsan_security=true' }, 'lsan': { @@ -1722,6 +2134,11 @@ 'gyp_defines': 'mac_strip_release=1', }, + 'mac_views_browser': { + 'gn_args': 'mac_views_browser=true', + 'gyp_defines': 'mac_views_browser=1', + }, + 'minimal_symbols': { 'gn_args': 'symbol_level=1', 'gyp_defines': 'fastbuild=1', @@ -1739,6 +2156,18 @@ 'use_prebuilt_instrumented_libraries=1'), }, + 'msan_no_origins': { + 'gn_args': ('is_msan=true msan_track_origins=0 ' + 'use_prebuilt_instrumented_libraries=true'), + 'gyp_defines': ('msan=1 msan_track_origins=0 ' + 'use_prebuilt_instrumented_libraries=1'), + }, + + 'no_pch': { + 'gn_args': 'disable_precompiled_headers=true', + 'gyp_defines': 'chromium_win_pch=0', + }, + 'no_symbols': { 'gn_args': 'symbol_level=0', 'gyp_defines': 'fastbuild=2', @@ -1792,6 +2221,10 @@ 'gyp_defines': 'component=shared_library', }, + 'shared_release_bot': { + 'mixins': ['shared', 'release', 'goma'] + }, + 'static': { 'gn_args': 'is_component_build=false', 'gyp_defines': 'component=static_library', @@ -1802,6 +2235,12 @@ 'gyp_defines': 'test_isolation_mode=prepare', }, + 'symbolized': { + 'gn_args': 'error', # TODO(GYP): add an equivalent flag for this + 'gyp_defines': + 'release_extra_cflags="-O1 -fno-inline-functions -fno-inline"', + }, + 'syzyasan': { 'gn_args': 'is_syzyasan=true', 'gyp_defines': 'syzyasan=1' @@ -1812,11 +2251,44 @@ 'gyp_defines': 'tsan=1', }, + 'ubsan': { + 'gn_args': 'is_ubsan=true', + 'gyp_defines': 'ubsan=1', + }, + + 'ubsan_no_recover_hack': { + # TODO(krasin): Remove when https://llvm.org/bugs/show_bug.cgi?id=25569 + # is fixed and just use ubsan_vptr instead. + 'mixins': ['ubsan_vptr'], + 'gn_args': 'is_ubsan_no_recover=true', + 'gyp_defines': 'release_extra_cflags=-fno-sanitize-recover=undefined', + }, + + 'ubsan_vptr': { + 'gn_args': 'is_ubsan_vptr=true', + 'gyp_defines': 'ubsan_vptr=1', + }, + + 'use_lld': { + 'gn_args': 'use_lld=true', + 'gyp_defines': 'use_lld=1', + }, + + 'v8_heap': { + 'gn_args': 'error', # TODO(GYP): implement v8_enable_verify_heap=true + 'gyp_defines': 'v8_enable_verify_heap=1', + }, + 'win_analyze': { 'gn_args': 'use_vs_code_analysis=true', 'gyp_defines': 'win_analyze=1', }, + 'win_z7': { + 'gn_args': 'error', # TODO(GYP): implement win_z7=true + 'gyp_defines': 'win_z7=1', + }, + 'x64': { 'gn_args': 'target_cpu="x64"', 'gyp_defines': 'target_arch=x64', @@ -1833,10 +2305,5 @@ 'gn_args': 'is_component_build=true enable_iterator_debugging=false', 'gyp_defines': 'component=shared_library build_for_tool=drmemory', }, - - 'valgrind': { - # TODO: add gn_args for 'build_for_tool=memcheck' - 'gyp_defines': 'build_for_tool=memcheck', - } }, } diff --git a/chromium/tools/mb/mb_unittest.py b/chromium/tools/mb/mb_unittest.py index dbb093d3898..20ed720e374 100755 --- a/chromium/tools/mb/mb_unittest.py +++ b/chromium/tools/mb/mb_unittest.py @@ -56,6 +56,8 @@ class FakeMBW(mb.MetaBuildWrapper): return self.files[path] def WriteFile(self, path, contents, force_verbose=False): + if self.args.dryrun or self.args.verbose or force_verbose: + self.Print('\nWriting """\\\n%s""" to %s.\n' % (contents, path)) self.files[path] = contents def Call(self, cmd, env=None, buffer_output=True): @@ -118,6 +120,7 @@ TEST_CONFIG = """\ 'fake_gyp_crosscompile_builder': 'gyp_crosscompile', 'fake_gn_debug_builder': 'gn_debug_goma', 'fake_gyp_builder': 'gyp_debug', + 'fake_gn_args_bot': '//build/args/bots/fake_master/fake_gn_args_bot.gn', }, }, 'mixins': { @@ -131,8 +134,8 @@ TEST_CONFIG = """\ 'gyp': {'type': 'gyp'}, 'gn': {'type': 'gn'}, 'goma': { - 'gn_args': 'use_goma=true goma_dir="$(goma_dir)"', - 'gyp_defines': 'goma=1 gomadir=$(goma_dir)', + 'gn_args': 'use_goma=true', + 'gyp_defines': 'goma=1', }, 'rel': { 'gn_args': 'is_debug=false', @@ -176,6 +179,9 @@ class UnitTest(unittest.TestCase): def fake_mbw(self, files=None, win32=False): mbw = FakeMBW(win32=win32) mbw.files.setdefault(mbw.default_config, TEST_CONFIG) + mbw.files.setdefault( + mbw.ToAbsPath('//build/args/bots/fake_master/fake_gn_args_bot.gn'), + 'is_debug = false\n') if files: for path, contents in files.items(): mbw.files[path] = contents @@ -299,18 +305,36 @@ class UnitTest(unittest.TestCase): }) def test_gn_gen(self): + mbw = self.fake_mbw() self.check(['gen', '-c', 'gn_debug_goma', '//out/Default', '-g', '/goma'], - ret=0, - out=('/fake_src/buildtools/linux64/gn gen //out/Default ' - '\'--args=is_debug=true use_goma=true goma_dir="/goma"\' ' - '--check\n')) + mbw=mbw, ret=0) + self.assertMultiLineEqual(mbw.files['/fake_src/out/Default/args.gn'], + ('goma_dir = "/goma"\n' + 'is_debug = true\n' + 'use_goma = true\n')) + + # Make sure we log both what is written to args.gn and the command line. + self.assertIn('Writing """', mbw.out) + self.assertIn('/fake_src/buildtools/linux64/gn gen //out/Default --check', + mbw.out) mbw = self.fake_mbw(win32=True) self.check(['gen', '-c', 'gn_debug_goma', '-g', 'c:\\goma', '//out/Debug'], - mbw=mbw, ret=0, - out=('c:\\fake_src\\buildtools\\win\\gn.exe gen //out/Debug ' - '"--args=is_debug=true use_goma=true goma_dir=\\"' - 'c:\\goma\\"" --check\n')) + mbw=mbw, ret=0) + self.assertMultiLineEqual(mbw.files['c:\\fake_src\\out\\Debug\\args.gn'], + ('goma_dir = "c:\\\\goma"\n' + 'is_debug = true\n' + 'use_goma = true\n')) + self.assertIn('c:\\fake_src\\buildtools\\win\\gn.exe gen //out/Debug ' + '--check\n', mbw.out) + + mbw = self.fake_mbw() + self.check(['gen', '-m', 'fake_master', '-b', 'fake_gn_args_bot', + '//out/Debug'], + mbw=mbw, ret=0) + self.assertEqual( + mbw.files['/fake_src/out/Debug/args.gn'], + 'import("//build/args/bots/fake_master/fake_gn_args_bot.gn")\n') def test_gn_gen_fails(self): @@ -388,9 +412,13 @@ class UnitTest(unittest.TestCase): def test_gn_lookup_goma_dir_expansion(self): self.check(['lookup', '-c', 'gn_rel_bot', '-g', '/foo'], ret=0, - out=("/fake_src/buildtools/linux64/gn gen _path_ " - "'--args=is_debug=false use_goma=true " - "goma_dir=\"/foo\"'\n" )) + out=('\n' + 'Writing """\\\n' + 'goma_dir = "/foo"\n' + 'is_debug = false\n' + 'use_goma = true\n' + '""" to _path_/args.gn.\n\n' + '/fake_src/buildtools/linux64/gn gen _path_\n')) def test_gyp_analyze(self): mbw = self.check(['analyze', '-c', 'gyp_rel_bot', '//out/Release', @@ -437,7 +465,6 @@ class UnitTest(unittest.TestCase): def test_validate(self): mbw = self.fake_mbw() - mbw.files[mbw.default_config] = TEST_CONFIG self.check(['validate'], mbw=mbw, ret=0) def test_bad_validate(self): diff --git a/chromium/tools/md_browser/md_browser.py b/chromium/tools/md_browser/md_browser.py index 2b968525320..f2e05f9308d 100644..100755 --- a/chromium/tools/md_browser/md_browser.py +++ b/chromium/tools/md_browser/md_browser.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python # Copyright 2015 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. @@ -25,12 +26,16 @@ def main(argv): parser = argparse.ArgumentParser(prog='md_browser') parser.add_argument('-p', '--port', type=int, default=8080, help='port to run on (default = %(default)s)') + parser.add_argument('-d', '--directory', type=str, default=SRC_DIR) args = parser.parse_args(argv) try: - s = Server(args.port, SRC_DIR) + s = Server(args.port, args.directory) print("Listening on http://localhost:%s/" % args.port) - print(" Try loading http://localhost:%s/docs/README.md" % args.port) + if os.path.isfile(os.path.join(args.directory, 'docs', 'README.md')): + print(" Try loading http://localhost:%s/docs/README.md" % args.port) + elif os.path.isfile(os.path.join(args.directory, 'README.md')): + print(" Try loading http://localhost:%s/README.md" % args.port) s.serve_forever() s.shutdown() return 0 @@ -71,7 +76,7 @@ class Server(SocketServer.TCPServer): def __init__(self, port, top_level): SocketServer.TCPServer.__init__(self, ('0.0.0.0', port), Handler) self.port = port - self.top_level = top_level + self.top_level = os.path.abspath(top_level) def server_bind(self): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -89,7 +94,7 @@ class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): full_path = os.path.abspath(os.path.join(self.server.top_level, path[1:])) - if not full_path.startswith(SRC_DIR): + if not full_path.startswith(self.server.top_level): self._DoUnknown() elif path == '/doc.css': self._DoCSS('doc.css') @@ -142,9 +147,11 @@ class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): self.wfile.write('<html><body>I do not know how to serve %s.</body>' '</html>' % self.path) - def _Read(self, relpath): + def _Read(self, relpath, relative_to=None): + if relative_to is None: + relative_to = self.server.top_level assert not relpath.startswith(os.sep) - path = os.path.join(self.server.top_level, relpath) + path = os.path.join(relative_to, relpath) with codecs.open(path, encoding='utf-8') as fp: return fp.read() @@ -154,7 +161,8 @@ class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): self.end_headers() def _WriteTemplate(self, template): - contents = self._Read(os.path.join('tools', 'md_browser', template)) + contents = self._Read(os.path.join('tools', 'md_browser', template), + relative_to=SRC_DIR) self.wfile.write(contents.encode('utf-8')) diff --git a/chromium/tools/origin_trials/OWNERS b/chromium/tools/origin_trials/OWNERS index d9278608565..0d67a41a799 100644 --- a/chromium/tools/origin_trials/OWNERS +++ b/chromium/tools/origin_trials/OWNERS @@ -1,3 +1 @@ -dhnishi@chromium.org -iclelland@chromium.org -mek@chromium.org +file://content/common/origin_trials/OWNERS diff --git a/chromium/tools/origin_trials/eftest.key b/chromium/tools/origin_trials/eftest.key index 10015d89550..3a7a7a91955 100644 --- a/chromium/tools/origin_trials/eftest.key +++ b/chromium/tools/origin_trials/eftest.key @@ -1 +1 @@ -gôÍ* +g*
CLg(ɐv,Ku:(pҚY+dV:
\ No newline at end of file diff --git a/chromium/tools/polymer/generate_compiled_resources_gyp.py b/chromium/tools/polymer/generate_compiled_resources_gyp.py index 38f81578ab4..d825b171a6f 100755 --- a/chromium/tools/polymer/generate_compiled_resources_gyp.py +++ b/chromium/tools/polymer/generate_compiled_resources_gyp.py @@ -32,7 +32,11 @@ _COMPILED_RESOURCES_TEMPLATE = """ def main(created_by, html_files): targets = "" - for html_file in html_files: + def _target_name(target_file): + assert target_file.endswith(".html") + return path.basename(target_file)[:-len(".html")] + "-extracted" + + for html_file in sorted(html_files, key=_target_name): html_base = path.basename(html_file) if html_base in _POLYMERS: continue @@ -52,7 +56,7 @@ def main(created_by, html_files): dependencies.append(_WEB_ANIMATIONS_TARGET) continue - target = import_base[:-5] + "-extracted" + target = _target_name(import_base) if not path.isfile(path.join(html_dir, import_dir, target + ".js")): continue diff --git a/chromium/tools/roll_angle.py b/chromium/tools/roll_angle.py index 6432cc4a093..2b253ee56ee 100755 --- a/chromium/tools/roll_angle.py +++ b/chromium/tools/roll_angle.py @@ -102,7 +102,7 @@ def _GenerateCLDescriptionCommand(angle_current, angle_new, bugs, tbr): def GetBugString(bugs): bug_str = 'BUG=' for bug in bugs: - bug_str += str(bug) + ',' + bug_str += bug + ',' return bug_str.rstrip(',') if angle_current.git_commit != angle_new.git_commit: @@ -219,6 +219,7 @@ class AutoRoller(object): ['git','log', '%s..%s' % (angle_current.git_commit, angle_new.git_commit)], working_dir=working_dir).split('\n') + ignored_projects = set(['angleproject']) bugs = set() for line in lines: line = line.strip() @@ -226,12 +227,13 @@ class AutoRoller(object): if line.startswith(bug_prefix): bugs_strings = line[len(bug_prefix):].split(',') for bug_string in bugs_strings: - try: - bugs.add(int(bug_string)) - except: - # skip this, it may be a project specific bug such as - # "angleproject:X" or an ill-formed BUG= message - pass + ignore_bug = False + for ignored_project in ignored_projects: + if bug_string.startswith(ignored_project + ':'): + ignore_bug = True + break + if not ignore_bug: + bugs.add(bug_string) return bugs def _UpdateReadmeFile(self, readme_path, new_revision): diff --git a/chromium/tools/roll_webgl_conformance.py b/chromium/tools/roll_webgl_conformance.py index 7ea056f1f50..4c9eb73d641 100755 --- a/chromium/tools/roll_webgl_conformance.py +++ b/chromium/tools/roll_webgl_conformance.py @@ -20,7 +20,11 @@ extra_trybots = [ { "mastername": "tryserver.chromium.mac", "buildernames": ["mac_optional_gpu_tests_rel"] - } + }, + { + "mastername": "tryserver.chromium.linux", + "buildernames": ["linux_optional_gpu_tests_rel"] + }, ] SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -229,7 +233,7 @@ class AutoRoller(object): readme.write(m) readme.truncate() - def PrepareRoll(self, ignore_checks, skip_tryjobs): + def PrepareRoll(self, ignore_checks, run_tryjobs): # TODO(kjellander): use os.path.normcase, os.path.join etc for all paths for # cross platform compatibility. @@ -280,7 +284,7 @@ class AutoRoller(object): self._RunCommand(['git', 'cl', 'upload'], extra_env={'EDITOR': 'true'}) - if not skip_tryjobs: + if run_tryjobs: # Kick off tryjobs. base_try_cmd = ['git', 'cl', 'try'] self._RunCommand(base_try_cmd) @@ -365,11 +369,10 @@ def main(): help=('Skips checks for being on the master branch, dirty workspaces and ' 'the updating of the checkout. Will still delete and create local ' 'Git branches.')) - parser.add_argument('--skip-tryjobs', action='store_true', default=False, - help=('Skip the dry-run tryjobs for the newly generated CL. Use this ' - 'when you expect to have to make many changes to the WebGL ' - 'conformance test expectations in the same CL and want to avoid ' - 'wasted tryjobs.')) + parser.add_argument('--run-tryjobs', action='store_true', default=False, + help=('Start the dry-run tryjobs for the newly generated CL. Use this ' + 'when you have no need to make changes to the WebGL conformance ' + 'test expectations in the same CL and want to avoid.')) parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Be extra verbose in printing of log messages.') args = parser.parse_args() @@ -383,7 +386,7 @@ def main(): if args.abort: return autoroller.Abort() else: - return autoroller.PrepareRoll(args.ignore_checks, args.skip_tryjobs) + return autoroller.PrepareRoll(args.ignore_checks, args.run_tryjobs) if __name__ == '__main__': sys.exit(main()) diff --git a/chromium/tools/roll_webrtc.py b/chromium/tools/roll_webrtc.py index f016fb39c15..4291c3820f5 100755 --- a/chromium/tools/roll_webrtc.py +++ b/chromium/tools/roll_webrtc.py @@ -36,8 +36,9 @@ TRYJOB_STATUS_SLEEP_SECONDS = 30 # Use a shell for subcommands on Windows to get a PATH search. IS_WIN = sys.platform.startswith('win') WEBRTC_PATH = os.path.join('third_party', 'webrtc') -LIBJINGLE_PATH = os.path.join('third_party', 'libjingle', 'source', 'talk') -LIBJINGLE_README = os.path.join('third_party', 'libjingle', 'README.chromium') +# Run these CQ trybots in addition to the default ones in infra/config/cq.cfg. +EXTRA_TRYBOTS = ('tryserver.chromium.linux:linux_chromium_archive_rel_ng;' + 'tryserver.chromium.mac:mac_chromium_archive_rel_ng') # Result codes from build/third_party/buildbot_8_4p1/buildbot/status/results.py # plus the -1 code which is used when there's no result yet. @@ -152,38 +153,20 @@ def _PrintTrybotsStatus(tryjob_results): print '%s: %s' % (status, ','.join(sorted(name_list))) -def _GenerateCLDescriptionCommand(webrtc_current, libjingle_current, - webrtc_new, libjingle_new): - delim = '' - webrtc_str = '' +def _GenerateCLDescriptionCommand(webrtc_current, webrtc_new): def GetChangeLogURL(git_repo_url, current_hash, new_hash): return '%s/+log/%s..%s' % (git_repo_url, current_hash[0:7], new_hash[0:7]) - if webrtc_current.git_commit != webrtc_new.git_commit: - webrtc_str = 'WebRTC %s:%s' % (webrtc_current.commit_position, - webrtc_new.commit_position) - webrtc_changelog_url = GetChangeLogURL(webrtc_current.git_repo_url, - webrtc_current.git_commit, - webrtc_new.git_commit) - - libjingle_str = '' - if libjingle_current.git_commit != libjingle_new.git_commit: - if webrtc_str: - delim += ', ' - libjingle_str = 'Libjingle %s:%s' % (libjingle_current.commit_position, - libjingle_new.commit_position) - libjingle_changelog_url = GetChangeLogURL(libjingle_current.git_repo_url, - libjingle_current.git_commit, - libjingle_new.git_commit) - - description = [ '-m', 'Roll ' + webrtc_str + delim + libjingle_str ] - if webrtc_str: - description.extend(['-m', webrtc_str]) - description.extend(['-m', 'Changes: %s' % webrtc_changelog_url]) - if libjingle_str: - description.extend(['-m', libjingle_str]) - description.extend(['-m', 'Changes: %s' % libjingle_changelog_url]) + webrtc_str = 'WebRTC %s:%s' % (webrtc_current.commit_position, + webrtc_new.commit_position) + webrtc_changelog_url = GetChangeLogURL(webrtc_current.git_repo_url, + webrtc_current.git_commit, + webrtc_new.git_commit) + + description = [ '-m', 'Roll ' + webrtc_str ] + description.extend(['-m', 'Changes: %s' % webrtc_changelog_url]) description.extend(['-m', 'TBR=']) + description.extend(['-m', 'CQ_EXTRA_TRYBOTS=%s' % EXTRA_TRYBOTS]) return description @@ -299,26 +282,22 @@ class AutoRoller(object): deps_filename = os.path.join(self._chromium_src, 'DEPS') deps = _ParseDepsFile(deps_filename) webrtc_current = self._GetDepsCommitInfo(deps, WEBRTC_PATH) - libjingle_current = self._GetDepsCommitInfo(deps, LIBJINGLE_PATH) # Find ToT revisions. webrtc_latest = self._GetCommitInfo(WEBRTC_PATH) - libjingle_latest = self._GetCommitInfo(LIBJINGLE_PATH) if IS_WIN: # Make sure the roll script doesn't use Windows line endings. self._RunCommand(['git', 'config', 'core.autocrlf', 'true']) self._UpdateDep(deps_filename, WEBRTC_PATH, webrtc_latest) - self._UpdateDep(deps_filename, LIBJINGLE_PATH, libjingle_latest) if self._IsTreeClean(): - print 'The latest revision is already rolled for WebRTC and libjingle.' + print 'The latest revision is already rolled for WebRTC.' self._DeleteRollBranch() else: - self._UpdateReadmeFile(LIBJINGLE_README, libjingle_latest.commit_position) description = _GenerateCLDescriptionCommand( - webrtc_current, libjingle_current, webrtc_latest, libjingle_latest) + webrtc_current, webrtc_latest) logging.debug('Committing changes locally.') self._RunCommand(['git', 'add', '--update', '.']) self._RunCommand(['git', 'commit'] + description) @@ -397,7 +376,7 @@ class AutoRoller(object): def main(): parser = argparse.ArgumentParser( - description='Find webrtc and libjingle revisions for roll.') + description='Find webrtc revisions for roll.') parser.add_argument('--abort', help=('Aborts a previously prepared roll. ' 'Closes any associated issues and deletes the roll branches'), diff --git a/chromium/tools/valgrind/chrome_tests.py b/chromium/tools/valgrind/chrome_tests.py index e108384f1b1..57df8bbd4be 100755 --- a/chromium/tools/valgrind/chrome_tests.py +++ b/chromium/tools/valgrind/chrome_tests.py @@ -322,7 +322,9 @@ class ChromeTests: return self.SimpleTest("chrome", "cast_unittests") def TestCC(self): - return self.SimpleTest("cc", "cc_unittests") + return self.SimpleTest("cc", "cc_unittests", + cmd_args=[ + "--cc-layer-tree-test-long-timeout"]) def TestChromeApp(self): return self.SimpleTest("chrome_app", "chrome_app_unittests") diff --git a/chromium/tools/valgrind/drmemory/suppressions.txt b/chromium/tools/valgrind/drmemory/suppressions.txt index 36f69910dae..bb77522a41f 100644 --- a/chromium/tools/valgrind/drmemory/suppressions.txt +++ b/chromium/tools/valgrind/drmemory/suppressions.txt @@ -487,27 +487,6 @@ NPCTRL.dll!DllGetClassObject NPCTRL.dll!DllGetClassObject HANDLE LEAK -name=http://crbug.com/373333 -system call NtGdiCreateCompatibleDC -*!CreateCompatibleDC -*!SkScalerContext_GDI::SkScalerContext_GDI -*!LogFontTypeface::onCreateScalerContext -*!SkTypeface::createScalerContext -*!SkGlyphCache::VisitCache -... -*!SkPaint::descriptorProc -... -*!blink::RenderBlockFlow::layoutBlockFlow -*!blink::RenderBlockFlow::layoutBlock -*!blink::RenderBlock::layout - -HANDLE LEAK -name=https://github.com/DynamoRIO/drmemory/issues/1545 -system call NtGdiCreateCompatibleDC -GDI32.dll!CreateCompatibleDC -skia.dll!LogFontTypeface::onGetTableData - -HANDLE LEAK name=http://crbug.com/379000 system call NtCreate* ... @@ -810,3 +789,22 @@ ipc.dll!IPC::internal::ChannelReader::HandleTranslatedMessage ipc.dll!IPC::internal::ChannelReader::TranslateInputData ipc.dll!IPC::internal::ChannelReader::AsyncReadComplete ipc.dll!IPC::ChannelWin::OnIOCompleted + +UNADDRESSABLE ACCESS +name=bug_604078 +content.dll!content::BluetoothBlacklist::PopulateWithServerProvidedValues +content.dll!content::BluetoothBlacklist::BluetoothBlacklist +content.dll!content::BluetoothBlacklist::Get + + +UNINITIALIZED READ +name=bug_608111 +DWrite.dll!DWriteCreateFactory +skia.dll!SkDWriteFontFileStreamWrapper::GetFileSize +... +blink_platform.dll!blink::SimpleFontData::platformWidthForGlyph + +UNADDRESSABLE ACCESS +name=bug_608064 +*!ExtensionService::NotifyExtensionLoaded +*!ExtensionService::AddExtension diff --git a/chromium/tools/valgrind/drmemory/suppressions_full.txt b/chromium/tools/valgrind/drmemory/suppressions_full.txt index a03efb6cb78..97b85cc140f 100644 --- a/chromium/tools/valgrind/drmemory/suppressions_full.txt +++ b/chromium/tools/valgrind/drmemory/suppressions_full.txt @@ -1350,23 +1350,6 @@ name=http://crbug.com/57266 (2) *!vp8_* LEAK -name=http://crbug.com/70062 -*!PR_Calloc -*!PR_NewLock -... -*!InitSessionCacheLocks -*!initSessionCacheLocksLazily -*!PR_CallOnce -*!ssl_InitSessionCacheLocks -*!lock_cache -*!ssl_LookupSID -*!ssl2_BeginClientHandshake -*!ssl_Do1stHandshake -*!SSL_ForceHandshake -*!net::SSL*SocketNSS::DoHandshake -*!net::SSL*SocketNSS::DoHandshakeLoop - -LEAK name=http://crbug.com/74417 a *!replace_operator_new *!disk_cache::BackendImpl::CreateEntryImpl @@ -1407,13 +1390,6 @@ name=http://crbug.com/80550 (2) *!RenderWidgetHost::WasRestored LEAK -name=http://crbug.com/87612 -... -*!SSL_ConfigSecureServer -*!net::SSLServerSocketNSS::InitializeSSLOptions -*!net::SSLServerSocketNSS::Handshake - -LEAK name=http://crbug.com/88640 *!generic_cpp_alloc *!operator new @@ -1520,19 +1496,6 @@ UNINITIALIZED READ name=bug_343663 blink_web.dll!blink::RenderBlock::computeInlinePreferredLogicalWidths -UNINITIALIZED READ -name=bug_343797 -... -blink_web.dll!blink::MediaQueryExp::create -blink_web.dll!blink::BisonCSSParser::createFloatingMediaQueryExp -blink_web.dll!cssyyparse - -UNINITIALIZED READ -name=bug_343915 -blink_web.dll!blink::BisonCSSParser::parseFlex -blink_web.dll!blink::BisonCSSParser::parseValue -blink_web.dll!cssyyparse - UNADDRESSABLE ACCESS name=BUG_343958 blink_web.dll!blink::Node::getFlag @@ -1605,13 +1568,6 @@ skia.dll!SkCanvas::drawBitmap content.dll!content::ScreenshotData::EncodeOnWorker UNINITIALIZED READ -name=bug_363487 -blink_web.dll!blink::RenderLayerCompositor::updateIfNeeded -blink_web.dll!blink::RenderLayerCompositor::updateIfNeededRecursive -blink_web.dll!blink::FrameView::updateLayoutAndStyleForPainting -blink_web.dll!blink::PageAnimator::updateLayoutAndStyleForPainting - -UNINITIALIZED READ name=bug_365101 *!device::BluetoothAdapterWin::AdapterStateChanged @@ -1635,13 +1591,6 @@ name=bug_42043 ... QuickTime.qts!* -UNINITIALIZED READ -name=bug_369141 -... -*!blink::RenderLayerClipper::updateClipRects -*!blink::RenderLayerClipper::parentClipRects -*!blink::RenderLayerClipper::backgroundClipRect - HANDLE LEAK name=bug_370178 system call NtCreateEvent @@ -1831,8 +1780,8 @@ KERNELBASE.dll!DuplicateHandle KERNEL32.dll!DuplicateHandle base.dll!base::SharedMemory::ShareToProcessCommon gl_wrapper.dll!gl::GLImageSharedMemory::Initialize -content.dll!content::GpuChannel::CreateImageForGpuMemoryBuffer -content.dll!content::GpuCommandBufferStub::OnCreateImage +*!*::GpuChannel::CreateImageForGpuMemoryBuffer +*!*::GpuCommandBufferStub::OnCreateImage HANDLE LEAK name=https://crbug.com/481305 @@ -1858,26 +1807,6 @@ aura.dll!aura::WindowTreeHostPlatform::WindowTreeHostPlatform aura.dll!aura::WindowTreeHost::Create UNINITIALIZED READ -name=bug_492821 -*!blink::CSSPropertyParser::validUnit -... -*!blink::CSSPropertyParser::parseValue -*!blink::CSSPropertyParser::parseValue -*!blink::CSSParserImpl::consumeDeclarationValue -*!blink::CSSParserImpl::consumeDeclaration -*!blink::CSSParserImpl::consumeDeclarationList -*!blink::CSSParserImpl::consumeStyleRule -*!blink::CSSParserImpl::consumeQualifiedRule -*!blink::CSSParserImpl::consumeRuleList<> -*!blink::CSSParserImpl::parseStyleSheet -*!blink::CSSParser::parseSheet -*!blink::StyleSheetContents::parseStringAtPosition -*!blink::StyleEngine::parseSheet -*!blink::StyleEngine::createSheet -*!blink::StyleElement::createSheet -*!blink::StyleElement::process - -UNINITIALIZED READ name=bug_493167 system call NtWriteFile parameter #5 KERNELBASE.dll!WriteFile @@ -2121,17 +2050,6 @@ content.dll!content::PepperGraphics2DHost::Create content.dll!content::ContentRendererPepperHostFactory::CreateResourceHost UNINITIALIZED READ -name=bug_591092 -webcore_shared.dll!std::_Equal<> -webcore_shared.dll!WTF::operator==<> -webcore_shared.dll!blink::CSSVariableData::operator== -webcore_shared.dll!blink::dataEquivalent<> -webcore_shared.dll!blink::dataEquivalent<> -... -webcore_shared.dll!blink::Document::updateStyle -webcore_shared.dll!blink::Document::updateLayoutTree - -UNINITIALIZED READ name=bug_593594 blink_platform.dll!qcms_transform_data_rgba_out_lut_sse2 blink_platform.dll!qcms_transform_data_type diff --git a/chromium/tools/valgrind/gtest_exclude/base_unittests.gtest.txt b/chromium/tools/valgrind/gtest_exclude/base_unittests.gtest.txt index 989459dcb55..c98265df11c 100644 --- a/chromium/tools/valgrind/gtest_exclude/base_unittests.gtest.txt +++ b/chromium/tools/valgrind/gtest_exclude/base_unittests.gtest.txt @@ -7,10 +7,6 @@ WatchdogTest.AlarmTest TimerTest.RepeatingTimer TimerTest.RepeatingTimer_Cancel -# Crashes occasionally, see http://crbug.com/7477 -base::ObserverListThreadSafeTest.CrossThreadObserver -base::ObserverListThreadSafeTest.CrossThreadNotifications - # Hangs sometimes on linux, see http://crbug.com/22138 ClipboardTest.* diff --git a/chromium/tools/valgrind/gtest_exclude/browser_tests.gtest-drmemory.txt b/chromium/tools/valgrind/gtest_exclude/browser_tests.gtest-drmemory.txt index 80514c28ab2..3166fdcc4fe 100644 --- a/chromium/tools/valgrind/gtest_exclude/browser_tests.gtest-drmemory.txt +++ b/chromium/tools/valgrind/gtest_exclude/browser_tests.gtest-drmemory.txt @@ -58,9 +58,6 @@ SmartSessionRestoreTest.CorrectLoadingOrder # https://crbug.com/516368 PushMessagingBrowserTest.PushEventSuccess -# https://crbug.com/519039 -AppViewTest.KillGuestCommunicatingWithWrongAppView - # https://crbug.com/519087 ExtensionTabsTest.GetAllWindowsAllTypes @@ -144,6 +141,7 @@ HostedAppTest* ImageWriterPrivateApiTest.TestWriteFromFile InlineInstallPrivateApiTestApp* InstallGoodExtensionSettingsWebUITest.showOptions +ManageProfileUITestAsync.CreateExistingSupervisedUser MaterialHistoryBrowserTest* MimeHandlerViewTest.Abort MimeHandlerViewTest.EmbeddedDataUrlObject @@ -151,9 +149,15 @@ MultilanguageOptionsWebUI* PDFExtensionTest* PasswordsPrivateApiTest.RequestPlaintextPassword PolicyPref* +PredictorBrowserTest* ProfileWindow* PushMessagingBrowserTest.SubscribeWithoutKeySuccessNotificationsGranted SubframeTaskBrowserTest.TaskManagerShowsSubframeTasks SyncSetupWebUITestAsync.RestoreSyncDataTypes +WebRtcDisableEncryptionFlagBrowserTest.VerifyEncryption WebUIWebView* +WebrtcEventLogApiTest* ZoomControllerBrowserTest.NavigationResetsManualMode + +# https://crbug.com/603334 +AppViewTests/AppViewTest.KillGuestCommunicatingWithWrongAppView/* diff --git a/chromium/tools/valgrind/gtest_exclude/cc_unittests.gtest-drmemory_win32.txt b/chromium/tools/valgrind/gtest_exclude/cc_unittests.gtest-drmemory_win32.txt index 563f0c76243..66cf2c53f6c 100644 --- a/chromium/tools/valgrind/gtest_exclude/cc_unittests.gtest-drmemory_win32.txt +++ b/chromium/tools/valgrind/gtest_exclude/cc_unittests.gtest-drmemory_win32.txt @@ -43,6 +43,7 @@ LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime.RunMultiThread_DirectRenderer LayerTreeHostCopyRequestCompletionCausesCommit.RunMultiThread_DirectRenderer LayerTreeHostCopyRequestTestLostOutputSurface.RunMultiThread_DirectRenderer LayerTreeHostTestStartPageScaleAnimation.RunMultiThread_DelegatingRenderer +LayerTreeHostTestStartPageScaleAnimation.RunMultiThread_DirectRenderer # https://crbug.com/571268 LayerTreeHostTestGpuRasterDeviceSizeChanged.* diff --git a/chromium/tools/valgrind/gtest_exclude/components_unittests.gtest.txt b/chromium/tools/valgrind/gtest_exclude/components_unittests.gtest.txt index 9289e21187b..ecc05cfbadb 100644 --- a/chromium/tools/valgrind/gtest_exclude/components_unittests.gtest.txt +++ b/chromium/tools/valgrind/gtest_exclude/components_unittests.gtest.txt @@ -6,6 +6,3 @@ AudioDirectiveListTest.* # http://crbug.com/523462 PluginsFieldTrialTest.NoPrefLeftBehind - -# Fails under valgrind Linux, see http://crbug.com/587664 -DataReductionProxyConfigServiceClientTest.HTTPRequests diff --git a/chromium/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt b/chromium/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt index 676da4d82b3..53187ebcd99 100644 --- a/chromium/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt +++ b/chromium/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt @@ -64,3 +64,17 @@ WebRtcMediaRecorderTest.MediaRecorderPeerConnection # https://crbug.com/592320 SitePerProcessBrowserTest.SubframeGestureEventRouting + +# https://crbug.com/603337 +SingleProcessMemoryTracingTest.ManyInterleavedDumps +SingleProcessMemoryTracingTest.RendererInitiatedSingleDump + +# https://crbug.com/608081 +SitePerProcessBrowserTest.NavigateRemoteFrameToBlankAndDataURLs +SitePerProcessBrowserTest.RFPHDestruction + +# https://crbug.com/608117 +WebRtcDataChannelTest.DataChannelGC + +# https://crbug.com/611557 +FindRequestManagerTest.RapidFire diff --git a/chromium/tools/valgrind/gtest_exclude/content_unittests.gtest-drmemory_win32.txt b/chromium/tools/valgrind/gtest_exclude/content_unittests.gtest-drmemory_win32.txt index 4cc5686e176..f12d3ced4dd 100644 --- a/chromium/tools/valgrind/gtest_exclude/content_unittests.gtest-drmemory_win32.txt +++ b/chromium/tools/valgrind/gtest_exclude/content_unittests.gtest-drmemory_win32.txt @@ -11,3 +11,6 @@ RenderWidgetCompositorOutputSurfaceTest.FallbackSuccessNormalSuccess # http://crbug.com/554665 WebContentsVideoCaptureDeviceTest.VariableResolution_AnyWithinLimits WebContentsVideoCaptureDeviceTest.VariableResolution_FixedAspectRatio + +# https://crbug.com/604056 +CodecProfiles/RTCVideoDecoderTest.GetVDAErrorCounterForTesting* diff --git a/chromium/tools/valgrind/gtest_exclude/net_unittests.gtest-drmemory_win32.txt b/chromium/tools/valgrind/gtest_exclude/net_unittests.gtest-drmemory_win32.txt index c865baf0e4f..8388d668f14 100644 --- a/chromium/tools/valgrind/gtest_exclude/net_unittests.gtest-drmemory_win32.txt +++ b/chromium/tools/valgrind/gtest_exclude/net_unittests.gtest-drmemory_win32.txt @@ -34,3 +34,9 @@ ProxyResolverV8TracingWrapperTest.* # https://crbug.com/598953 *QuicConnectionTest.TooManyReceivedPackets* + +# https://crbug.com/604611 +BidirectionalStreamTest.* + +# https://crbug.com/611533 +*HttpStreamFactoryBidirectionalQuicTest.RequestBidirectionalStreamImpl* diff --git a/chromium/tools/valgrind/gtest_exclude/remoting_unittests.gtest-drmemory_win32.txt b/chromium/tools/valgrind/gtest_exclude/remoting_unittests.gtest-drmemory_win32.txt index 276d6acb4d8..038c5ef41ec 100644 --- a/chromium/tools/valgrind/gtest_exclude/remoting_unittests.gtest-drmemory_win32.txt +++ b/chromium/tools/valgrind/gtest_exclude/remoting_unittests.gtest-drmemory_win32.txt @@ -13,6 +13,3 @@ RdpClientTest.Basic # https://crbug.com/581519 Webrtc/ConnectionTest.Video/0 - -# https://crbug.com/599769 -RemoteSecurityKeyMessageReaderTest.MultipleMessages diff --git a/chromium/tools/valgrind/gtest_exclude/unit_tests.gtest-drmemory_win32.txt b/chromium/tools/valgrind/gtest_exclude/unit_tests.gtest-drmemory_win32.txt index 06fd527ed91..673468a845e 100644 --- a/chromium/tools/valgrind/gtest_exclude/unit_tests.gtest-drmemory_win32.txt +++ b/chromium/tools/valgrind/gtest_exclude/unit_tests.gtest-drmemory_win32.txt @@ -84,3 +84,6 @@ SigninErrorNotifierTest.NoErrorAuthStatusProviders # https://crbug.com/577410 PluginInfoMessageFilterTest.FindEnabledPlugin + +# https://crbug.com/612590 +NativeDesktopMediaListTest.UpdateThumbnail diff --git a/chromium/tools/valgrind/memcheck/suppressions.txt b/chromium/tools/valgrind/memcheck/suppressions.txt index 9d5b4ad330d..d844892a633 100644 --- a/chromium/tools/valgrind/memcheck/suppressions.txt +++ b/chromium/tools/valgrind/memcheck/suppressions.txt @@ -625,17 +625,6 @@ fun:_ZN4base6Thread10ThreadMainEv } { - # also bug 17979. It's a nest of leaks. - bug_17385 - Memcheck:Leak - fun:_Znw* - ... - fun:_ZN3IPC12ChannelProxy7Context13CreateChannel*Channel4ModeE - fun:_ZN3IPC12ChannelProxy4Init* - ... - fun:_ZN3IPC11SyncChannel*Channel4Mode*Listener* -} -{ bug_17540_16661 Memcheck:Leak fun:_Znw* @@ -929,21 +918,11 @@ fun:_ZN14GpuProcessHost4InitEv } { - bug_67261a - Memcheck:Leak - fun:_Znw* - ... - fun:_ZN3sql10Connection18GetUniqueStatementEPKc - fun:_ZN3sql10Connection18GetCachedStatementERKNS_11StatementIDEPKc - fun:_ZN8appcache16AppCacheDatabase22PrepareCachedStatementERKN3sql11StatementIDEPKcPNS1_9StatementE -} -{ bug_67261b Memcheck:Leak fun:_Znw* fun:_ZN3sql10Connection18GetUniqueStatementEPKc fun:_ZN3sql10Connection18GetCachedStatementERKNS_11StatementIDEPKc - fun:_ZN3sql9MetaTable19PrepareGetStatementEPNS_9StatementEPKc ... fun:_ZN7storage13QuotaDatabase28IsOriginDatabaseBootstrappedEv } @@ -1211,15 +1190,6 @@ obj:* } { - bug_100982 - Memcheck:Leak - fun:_Znw* - fun:_ZN5blink12RenderRegion22setRenderBoxRegionInfoEPKNS_9RenderBoxEiib - fun:_ZNK7blink9RenderBox19renderBoxRegionInfoEPNS_12RenderRegionEiNS0_24RenderBoxRegionInfoFlagsE - ... - fun:_ZN5blink11RenderBlock5paintERNS_9PaintInfoERKNS_8IntPointE -} -{ bug_101750 Memcheck:Leak fun:malloc @@ -2011,24 +1981,13 @@ fun:_ZN5blink24DocumentThreadableLoader11loadRequestERKNS_15ResourceRequestENS_19SecurityCheckPolicyE } { - bug_340952 - Memcheck:Leak - fun:_Znw* - fun:_ZN5blink15DOMWrapperWorldC2Eii - fun:_ZN5blink15DOMWrapperWorldC1Eii - fun:_ZN5blink15DOMWrapperWorld6createEii - fun:_ZN5blink15DOMWrapperWorld9mainWorldEv - ... - fun:_ZN7content22BufferedDataSourceTestC2Ev -} -{ bug_340752 Memcheck:Uninitialized ... - fun:_ZN5blink4Heap19checkAndMarkPointerEPNS_7VisitorEPh + fun:_ZN5blink10ThreadHeap19checkAndMarkPointerEPNS_7VisitorEPh fun:_ZN5blink11ThreadState10visitStackEPNS_7VisitorE ... - fun:_ZN5blink4Heap14collectGarbageENS_7BlinkGC10StackState* + fun:_ZN5blink10ThreadHeap14collectGarbageENS_7BlinkGC10StackState* } { bug_342591 @@ -2233,19 +2192,6 @@ fun:_ZN7content28ShellURLRequestContextGetter20GetURLRequestContextEv } { - bug_381065 - Memcheck:Leak - fun:_Znw* - ... - fun:_ZN5blink18ModulesInitializer4initEv - fun:_ZN5blink19initializeWithoutV8EPNS_8PlatformE - fun:_ZN5blink10initializeEPNS_8PlatformE - fun:_ZN7content27TestBlinkWebUnitTestSupportC2Ev - fun:_ZN7content27TestBlinkWebUnitTestSupportC1Ev - fun:_ZN7content17UnitTestTestSuiteC2EPN4base9TestSuiteE - fun:_ZN7content17UnitTestTestSuiteC1EPN4base9TestSuiteE -} -{ bug_385381 Memcheck:Unaddressable fun:_ZN5blink23FrameLoaderStateMachine9advanceToENS0_5StateE @@ -2474,20 +2420,6 @@ fun:_ZN2v88internal27Runtime_CreateObjectLiteralEiPPNS0_6ObjectEPNS0_7IsolateE } { - bug_399853_a - Memcheck:Uninitialized - fun:_ZNK8SkStroke10strokePathERK6SkPathPS0_ - fun:_ZNK11SkStrokeRec11applyToPathEP6SkPathRKS0_ - fun:_ZNK7SkPaint11getFillPathERK6SkPathPS0_PK6SkRect -} -{ - bug_399853_b - Memcheck:Uninitialized - fun:_ZNK8SkStroke10strokePathERK6SkPathPS0_ - fun:_ZNK11SkStrokeRec11applyToPathEP6SkPathRKS0_ - fun:_ZN15SkScalerContext15internalGetPathERK7SkGlyphP6SkPathS4_P8SkMatrix -} -{ bug_417119 Memcheck:Leak fun:_Znw* @@ -2714,16 +2646,6 @@ fun:_ZN7content26ResourceDispatcherHostImpl23OnRenderViewHostCreatedEiibb } { - bug_492821 - Memcheck:Uninitialized - fun:_ZN5blink17CSSPropertyParser9validUnitEPNS_14CSSParserValueENS0_5UnitsENS_13CSSParserModeENS0_31ReleaseParsedCalcValueConditionE - fun:_ZN5blink17CSSPropertyParser9validUnitEPNS_14CSSParserValueENS0_5UnitsENS0_31ReleaseParsedCalcValueConditionE - ... - fun:_ZN5blink17CSSPropertyParser10parseValueENS_13CSSPropertyIDEb - fun:_ZN5blink17CSSPropertyParser10parseValueENS_13CSSPropertyID* - fun:_ZN5blink13CSSParserImpl23consumeDeclarationValueENS_19CSSParserTokenRangeENS_13CSSPropertyIDEbNS_13StyleRuleBase4TypeE -} -{ bug_514434 Memcheck:Leak fun:malloc @@ -2963,13 +2885,6 @@ fun:_ZN5blink9FrameView6layoutEv } { - bug_571272 - Memcheck:Overlap - fun:memcpy* - fun:_ZN3net10QuicFramer14EncryptPayloadENS_15EncryptionLevel* - fun:_ZN3net17QuicPacketCreator15SerializePacketEPcm -} -{ bug_571543 Memcheck:Leak ... @@ -2984,12 +2899,11 @@ bug_576259_a Memcheck:Uninitialized fun:_ZN7GrGLGpu11bindTextureEiRK15GrTextureParamsbP11GrGLTexture + ... fun:_ZN7GrGLGpu12flushGLStateERK10GrPipelineRK20GrPrimitiveProcessor fun:_ZN7GrGLGpu6onDrawERK10GrPipelineRK20GrPrimitiveProcessorPK6GrMeshi fun:_ZN5GrGpu4drawERK10GrPipelineRK20GrPrimitiveProcessorPK6GrMeshi fun:_ZN13GrVertexBatch6onDrawEP17GrBatchFlushState - ... - fun:_ZN2cc17SingleThreadProxy36ScheduledActionDrawAndSwapIfPossibleEv } { bug_576259_b @@ -3017,7 +2931,6 @@ fun:_ZN5blink14PersistentBaseINS_15StyleFilterDataELNS_31WeaknessPersistentConfigurationE0ELNS_38CrossThreadnessPersistentConfigurationE0EEnwEm fun:_ZN5blink26RefCountedGarbageCollectedINS_15StyleFilterDataEE13makeKeepAliveEv fun:_ZN5blink26RefCountedGarbageCollectedINS_15StyleFilterDataEE3refEv - fun:_ZN3WTF6RefPtrIN5blink15StyleFilterDataEEC2IS2_EERKNS_6RawPtrIT_EEPNSt9enable_ifIXsr3std10is_base_ofIS2_S6_EE5valueEvE4typeE fun:_ZN5blink7DataRefINS_15StyleFilterDataEE4initEv fun:_ZN5blink13ComputedStyle18createInitialStyleEv fun:_ZN5blink13ComputedStyle19mutableInitialStyleEv @@ -3145,14 +3058,12 @@ fun:_ZN4base4BindIMN7content21ChromeAppCacheServiceEFvRKNS_8FilePathEPNS1_15ResourceContextEPN3net23URLRequestContextGetterE13scoped_refptrIN7storage20SpecialStoragePolicyEEEJPS2_S3_S7_SB_IS9_ESE_EEENS_8CallbackINS_8internal22MakeUnboundRunTypeImplIT_JDpT0_EE4TypeEEESM_DpOSN_ } { - bug_600484 + bug_602964 Memcheck:Leak fun:_Znw* - fun:_ZN4mojo3edk2js13HandleWrapper6Create* - fun:_ZN3gin9ConverterIN4mojo6Handle* - fun:_ZN3gin11ConvertToV8IN4mojo6Handle* - fun:_ZN3gin10ToV8TraitsIN4mojo6HandleELb0EE14TryConvertToV8* - fun:_ZN3gin14TryConvertToV8IN4mojo6Handle* - fun:_ZN3gin10Dictionary3SetIN4mojo6Handle* - fun:_ZN4mojo3edk2js12_GLOBAL__N_114CreateDataPipe* + fun:_ZN4base4BindIMNS_12_GLOBAL__N_121PostTaskAndReplyRelayEFvvEJNS_8internal17UnretainedWrapper* + fun:_ZN4base8internal20PostTaskAndReplyImpl16PostTaskAndReplyERKN15tracked_objects8LocationERKNS* + fun:_ZN4base10TaskRunner16PostTaskAndReplyERKN15tracked_objects8LocationERKNS_8CallbackIFvvELNS* + fun:_ZN4base26PostTaskAndReplyWithResultIN3net20WifiPHYLayerProtocolES2_EEbPNS* + fun:_ZN7metrics22NetworkMetricsProvider25ProbeWifiPHYLayerProtocolEv } diff --git a/chromium/tools/valgrind/memcheck/suppressions_linux.txt b/chromium/tools/valgrind/memcheck/suppressions_linux.txt index 870cee2d360..7474efa0b63 100644 --- a/chromium/tools/valgrind/memcheck/suppressions_linux.txt +++ b/chromium/tools/valgrind/memcheck/suppressions_linux.txt @@ -126,18 +126,3 @@ fun:_ZN2ui16AXTreeSerializerIPN5views16AXAuraObjWrapperENS_10AXNodeDataENS_10AXTreeDataEE16SerializeChangesES3_PNS_16AXTreeUpdateBaseIS4_S5_EE fun:_ZN35AXTreeSourceAuraTest_Serialize_Test8TestBodyEv } -{ - bug_588849a - Memcheck:Leak - fun:_Znw* - fun:_ZN4base4BindIMN6syncer15ModelSafeWorkerEFvNS_8CallbackIFvNS1_14ModelSafeGroupEELNS_8internal8CopyModeE1EEEEJPS2_RS8_EEENS3_INS6_22MakeUnboundRunTypeImplIT_JDpT0_EE4TypeELS7_1EEESE_DpOSF_ - fun:_ZN6syncer15ModelSafeWorker28UnregisterForLoopDestructionEN4base8CallbackIFvNS_14ModelSafeGroupEELNS1_8internal8CopyModeE1EEE - fun:_ZN12browser_sync20SyncBackendRegistrar8ShutdownEv -} -{ - bug_588849b - Memcheck:Leak - fun:_Znw* - fun:_ZN30ProfileSyncServiceAutofillTest24CreateDataTypeControllerEN6syncer9ModelTypeE - fun:_ZN30ProfileSyncServiceAutofillTest16StartSyncServiceERKN4base8CallbackIF*syncer9ModelTypeE -} diff --git a/chromium/tools/vim/ninja-build.vim b/chromium/tools/vim/ninja-build.vim index 70e5a83cf21..76e2049f791 100644 --- a/chromium/tools/vim/ninja-build.vim +++ b/chromium/tools/vim/ninja-build.vim @@ -41,17 +41,17 @@ def path_to_source_root(): return candidate -def path_to_build_dir(configuration): - """Returns <chrome_root>/<output_dir>/(Release|Debug).""" +def path_to_build_dir(): + """Returns <chrome_root>/<output_dir>/(Release|Debug|<other>).""" chrome_root = path_to_source_root() sys.path.append(os.path.join(chrome_root, 'tools', 'vim')) from ninja_output import GetNinjaOutputDirectory - return GetNinjaOutputDirectory(chrome_root, configuration) + return GetNinjaOutputDirectory(chrome_root) -def compute_ninja_command_for_current_buffer(configuration=None): +def compute_ninja_command_for_current_buffer(): """Returns the shell command to compile the file in the current buffer.""" - build_dir = path_to_build_dir(configuration) + build_dir = path_to_build_dir() # ninja needs filepaths for the ^ syntax to be relative to the # build directory. @@ -65,8 +65,8 @@ def compute_ninja_command_for_current_buffer(configuration=None): vim.command('return "%s"' % build_cmd) -def compute_ninja_command_for_targets(targets='', configuration=None): - build_cmd = ' '.join(['ninja', '-C', path_to_build_dir(configuration), +def compute_ninja_command_for_targets(targets=''): + build_cmd = ' '.join(['ninja', '-C', path_to_build_dir(), targets]) vim.command('return "%s"' % build_cmd) endpython diff --git a/chromium/tools/vim/ninja_output.py b/chromium/tools/vim/ninja_output.py index 5bb638ab6d9..e6add1302c8 100644 --- a/chromium/tools/vim/ninja_output.py +++ b/chromium/tools/vim/ninja_output.py @@ -10,8 +10,8 @@ import itertools import re -def GetNinjaOutputDirectory(chrome_root, configuration=None): - """Returns <chrome_root>/<output_dir>/(Release|Debug). +def GetNinjaOutputDirectory(chrome_root): + """Returns <chrome_root>/<output_dir>/(Release|Debug|<other>). If either of the following environment variables are set, their value is used to determine the output directory: @@ -20,11 +20,7 @@ def GetNinjaOutputDirectory(chrome_root, configuration=None): Otherwise, all directories starting with the word out are examined. - The output directory must contain {configuration}/build.ninja (if - configuration is None, both Debug and Release will be checked). - - The configuration chosen is the one most recently generated/built, - but can be overriden via the <configuration> parameter. + The configuration chosen is the one most recently generated/built. """ output_dirs = [] @@ -45,15 +41,13 @@ def GetNinjaOutputDirectory(chrome_root, configuration=None): if os.path.isdir(out): output_dirs.append(os.path.relpath(out, start = chrome_root)) - configs = ['Debug', 'Release', 'Default'] - if configuration: - configs = [configuration] - def generate_paths(): - for out_dir, config in itertools.product(output_dirs, configs): - path = os.path.join(chrome_root, out_dir, config) - if os.path.exists(os.path.join(path, 'build.ninja')): - yield path + for out_dir in output_dirs: + out_path = os.path.join(chrome_root, out_dir) + for config in os.listdir(out_path): + path = os.path.join(out_path, config) + if os.path.exists(os.path.join(path, 'build.ninja')): + yield path def approx_directory_mtime(path): # This is a heuristic; don't recurse into subdirectories. |