
sudo apt install git python depot_tools is a toolkit for Chromium development. To install it you need to run: git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git export PATH="$PATH:/path/to/depot_tools" depot_tools were downloaded to the home folder, then do not use ~ in the PATH variable, otherwise problems may occur. You must use the $HOME variable: export PATH="$PATH:${HOME}/depot_tools" mkdir ~/chromium && cd ~/chromium fetch utility from depot_tools : fetch --nohooks --no-history chromium --no-history flag is used. With the story will be even longer.src folder, go to it: cd src ./build/install-build-deps.sh gclient runhooks .ninja files.example in the src folder: mkdir example src/example folder you need to create a BUILD.gn file that contains: executable("example") { sources = [ "example.cc", ] } BUILD.gn consists of a target (an executable example file) and a list of files that are needed to build a target.example.cc . To begin with, I propose to make the classic application “Hello world”: #include <iostream> int main(int argc, char **argv) { std::cout << "Hello world" << std::endl; return 0; } "//example" in the deps section in the BUILD.gn file that is located in src : ... group("gn_all") { testonly = true deps = [ ":gn_visibility", "//base:base_perftests", "//base:base_unittests", "//base/util:base_util_unittests", "//chrome/installer", "//chrome/updater", "//net:net_unittests", "//services:services_unittests", "//services/service_manager/public/cpp", "//skia:skia_unittests", "//sql:sql_unittests", "//third_party/flatbuffers:flatbuffers_unittests", "//tools/binary_size:binary_size_trybot_py", "//tools/ipc_fuzzer:ipc_fuzzer_all", "//tools/metrics:metrics_metadata", "//ui/base:ui_base_unittests", "//ui/gfx:gfx_unittests", "//url:url_unittests", # ↓↓↓↓↓↓↓↓ "//example", ] ... src folder and generate the project using the command: gn gen out/Default gn help gen example project in QtCreator, you need to run the command: gn gen --ide=qtcreator --root-target=example out/Default qtcreator out/Default/qtcreator_project/all.creator autoninja -C out/Default example ./out/Default/example #include "base/command_line.h" base in BUILD.gn . BUILD.gn should look like this: executable("example") { sources = [ "example.cc", ] deps = [ "//base", ] } example .base::CommandLine . To get a link to it, you must use the static base::CommandLine::ForCurrentProcess , but first you need to initialize it using the base::CommandLine::Init method: base::CommandLine::Init(argc, argv); auto *cmd_line = base::CommandLine::ForCurrentProcess(); - returned as base::SwitchMap (essentially, map<string, string> ) using the GetSwitches method. All other arguments are returned in the form of base::StringVector (in fact, vectr<strig> ). This knowledge is enough to implement the code for the task: for (const auto &sw : cmd_line->GetSwitches()) { std::cout << "Switch " << sw.first << ": " << sw.second << std::endl; } for (const auto &arg: cmd_line->GetArgs()) { std::cout << "Arg " << arg << std::endl; } autoninja -C out/Default example ./out/Default/example arg1 --sw1=val1 --sw2 arg2 Switch sw1: val1 Switch sw2: Arg arg1 Arg arg2 URLRequest , which already determines which client to use. A simplified diagram looks like this:
URLRequest you must use a URLRequestContext . Creating a context is a rather complicated operation, so it is recommended to use URLRequestContextBuilder . It initializes all necessary variables with default values, but, if you wish, you can change them for your own, for example: net::URLRequestContextBuilder context_builder; context_builder.DisableHttpCache(); context_builder.SetSpdyAndQuicEnabled(true /* http2 */, false /* quic */); context_builder.SetCookieStore(nullptr); base::Callback , which can be created using base::Bind .pthread on POSIX or CreateThread() on Windows). Implemented in the base::PlatformThread class, do not use directly.base::ThreadPool class. As a rule, create one copy. Tasks are sent to it using functions from base/task/post_task.h .base::TaskRunner .base::SequencedTaskRunner class.base::SingleThreadTaskRunner .base::AtExitManager - this is the class that allows you to register the operations that must be performed when the application terminates. Using it is very simple; you need to create an object on the stack: base::AtExitManager exit_manager; exit_manager goes out of scope, all registered callbacks will be executed.Thread pool , Message loop with the TYPE_IO type for processing network messages, and the Run loop is the main program loop: base::ThreadPool::CreateAndStartWithDefaultParams("downloader"); base::MessageLoop msg_loop(base::MessageLoop::TYPE_IO); base::RunLoop run_loop; Context builder to create a Context : auto ctx = net::URLRequestContextBuilder().Build(); CreateRequest method of the ctx object to create a URLRequest object. The following parameters are passed as parameters:net::URLRequest::Delegate interface. For this task, it might look like this: class MyDelegate : public net::URLRequest::Delegate { public: explicit MyDelegate(base::Closure quit_closure) : quit_closure_(std::move(quit_closure)), buf_(base::MakeRefCounted<net::IOBuffer>(BUF_SZ)) {} void OnReceivedRedirect(net::URLRequest *request, const net::RedirectInfo &redirect_info, bool *defer_redirect) override { std::cerr << "redirect to " << redirect_info.new_url << std::endl; } void OnAuthRequired(net::URLRequest* request, const net::AuthChallengeInfo& auth_info) override { std::cerr << "auth req" << std::endl; } void OnCertificateRequested(net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) override { std::cerr << "cert req" << std::endl; } void OnSSLCertificateError(net::URLRequest* request, int net_error, const net::SSLInfo& ssl_info, bool fatal) override { std::cerr << "cert err" << std::endl; } void OnResponseStarted(net::URLRequest *request, int net_error) override { std::cerr << "resp started" << std::endl; while (true) { auto n = request->Read(buf_.get(), BUF_SZ); std::cerr << "resp read " << n << std::endl; if (n == net::ERR_IO_PENDING) return; if (n <= 0) { OnReadCompleted(request, n); return; } std::cout << std::string(buf_->data(), n) << std::endl; } } void OnReadCompleted(net::URLRequest *request, int bytes_read) override { std::cerr << "completed" << std::endl; quit_closure_.Run(); } private: base::Closure quit_closure_; scoped_refptr<net::IOBuffer> buf_; }; OnResponseStarted event OnResponseStarted : the contents of the response are read until an error occurs or there is nothing to read. Since after reading the response, you need to terminate the application, the delegate must have access to the function that will interrupt the main Run loop , in this case, callback of type base::Closure . MyDelegate delegate(run_loop.QuitClosure()); auto req = ctx->CreateRequest(GURL(args[0]), net::RequestPriority::DEFAULT_PRIORITY, &delegate); req->Start(); Run loop : run_loop.Run(); autoninja -C out/Default example out/Default/example "https://example.com/" base::TaskScheduler turned into base::ThreadPool , thankfully, without changing the API.Source: https://habr.com/ru/post/455956/
All Articles