Alibaba Cloud Compiler is a C++ compiler developed by Alibaba Cloud based on Clang/LLVM 13, an open source community version of Clang/LLVM. Alibaba Cloud Compiler inherits all options and parameters from Clang/LLVM 13, is deeply optimized for Alibaba Cloud infrastructure, and provides additional features to deliver better user experience. This topic describes how to install and use Alibaba Cloud Compiler on Alibaba Cloud Linux 3 to build high-performance C++ applications quickly.
Background information
Alibaba Cloud Compiler significantly improves compilation and build speed compared with GCC and other Clang/LLVM versions in the following aspects:
Different techniques, such as profile-guided optimization (PGO), are used in Alibaba Cloud Compiler to tune the Clang/LLVM compiler for faster compilation. Alibaba Cloud Compiler builds large-scale C++ code much faster than other compilers, such as GCC.
The lld linker of Clang/LLVM performs better than the GNU linker used by GCC, especially when processing large binary files.
Based on the C++20 Module feature support, we have modularized the C++ standard library to form
std-module
. After your business code is integrated with minimal effort, compilation can be accelerated.
Alibaba Cloud Compiler uses technologies such as Alibaba Cloud Compiler(LLVM) ThinLTO, AutoFDO, and CoreBOLT to optimize program performance to varying degrees. Alibaba Cloud Compiler can run on different architectures, such as x86 and Arm64, and is tuned for YiTian 710 processors to attain additional performance gains.
Alibaba Cloud Compiler supports Coroutines and Modules and provides modularized standard libraries. Alibaba Cloud provides yaLanTingLibs that includes components commonly used by C++ developers, such as the coroutine library, serialization library, Remote Procedure Call (RPC) library, and HTTP feature.
NoteyaLanTingLibs is a collection of modern C++ utility libraries that provide high-performance and easy-to-use modern C++ utility libraries for C++ developers to build high-performance modern C++ applications.
Prerequisites
An Elastic Compute Service (ECS) instance that runs Alibaba Cloud Linux 3 is created. For more information, see Create an instance.
You can use Alibaba Cloud Compiler only on Alibaba Cloud Linux 3.
Alibaba Cloud compiler compilation
Run the following command to install Alibaba Cloud Compiler:
sudo yum install -y alibaba-cloud-compiler
Run the following command to install
libstdc++-devel
:libstdc++-devel
provides header files for the GNU Standard C++ Library.sudo yum -y install libstdc++-devel
Run the following command to import environment variables:
export PATH=/opt/alibaba-cloud-compiler/bin:$PATH
The following examples show how to use Alibaba Cloud Compiler for compilation:
Simple compilation example
Run the following command to create a
hello.cpp
file:Press the
i
key to enter edit mode, and then copy and paste the following content:Press the
Esc
key, enter:wq
, and then press theEnter
key to save the configuration.Run the following command to compile the modularized C++ code:
Run the following command to execute the program:
./hello.cpp.out
The following figure shows the result, which indicates that the program is executed successfully.
sudo vim hello.cpp
#include <iostream> int main() { std::cout << "hello C++" << std::endl; return 0; }
clang++ -O2 hello.cpp -o hello.cpp.out
Compile using C++20 coroutine and modules
Alibaba Cloud Compiler supports C++20 Coroutines and Modules, which allow C++ developers to compile in a more efficient manner and improve compilation performance. For examples of coroutines, see Use the C++ RPC library and Use the C++ HTTP library.
NoteCoroutines are a programming concept that allows you to suspend function execution and then resume the execution at a later time. This is significantly different from traditional function calls, which execute from start to finish once called. Coroutines provide a more flexible control flow mechanism that simplifies asynchronous programming and generator pattern implementation.
In traditional C++ programming, code is organized into header files (
.h
/.hpp
) and source files (.cpp
), and declarations in header files must be included in each source file that uses them through the#include
preprocessing directive. Compilers may repeatedly parse the same header files due to this convention. As a result, compilation time increases. Modules are introduced as an approach to optimize code organization and increase compilation efficiency.
When you use Clang to compile C++ programs, you can configure parameters. The following table describes the parameters.
Parameter
Description
-std=
Specifies the C++ feature. The coroutine and Modules features take effect after
-std=c++20
is specified.--precompile
Compiles module units into binary module interface (BMI) files.
-fprebuilt-module-path
Specifies the path in which to search for BMI files.
-fstd-modules
Specifies that files for std modules are compiled.
-fmodules-export-all
Specifies that all declarations in the current modules are marked as
export
.-fmodules-export-macros
Enables modules to export macros.
-try-load-bmi-when-preprocessing
Searches for BMI files during preprocessing.
-fstd-module-path
Specifies the path in which to search for std modules.
-fcoro-aligned-allocation
Prefers aligned allocation for C++ Coroutines.
Compilation example:
Run the following command to create a
Hello.cppm
file:sudo vim Hello.cppm
Press the
i
key to enter edit mode, and then copy and paste the following content:module; #include <iostream> export module Hello; export void hello() { std::cout << "Hello World!\n"; }
Press the
Esc
key, enter:wq
, and then press theEnter
key to save the configuration.Run the following command to create a
use.cpp
file:sudo vim use.cpp
Press the
i
key to enter edit mode, and then copy and paste the following content:import Hello; int main() { hello(); return 0; }
Press the
Esc
key, enter:wq
, and then press theEnter
key to save the configuration.Run the following command to compile the modularized C++ code:
# Precompile the module interface to generate the Hello.pcm file. clang++ -std=c++20 Hello.cppm --precompile -o Hello.pcm # Compile the main program and link the module to generate the executable Hello.out file. clang++ -std=c++20 use.cpp -fprebuilt-module-path=. Hello.pcm -o Hello.out
Run the following command to run the program:
./Hello.out
The following figure shows the result, which indicates that the program is executed successfully.
(Optional) Use the C++ yaLanTingLibs library
You can use yaLanTingLibs, which is a collection of standard C++ libraries that provide the coroutine library, serialization library, RPC library, and HTTP feature based on C++20 Coroutines and the C++ template metaprogramming feature. For more information about yaLanTingLibs, visit yalantinglibs and async_simple.
The serialization library is a software library used to serialize and deserialize data. Serialization is the process of converting a data structure or object status into a form that can be stored in files or buffers or transmitted over networks. Correspondingly, deserialization is the process of restoring the stored or transmitted format to the original data structure or object status.
RPC is a library that is used for interprocess communication (IPC). RPC allows C++ programs to execute functions or methods that reside on a remote machine as if the functions or methods were local. RPC abstracts away from details, such as network transmission, serialization, deserialization, and routes, and allows developers to focus on the business logic of their applications.
HTTP is an application-layer protocol for distributed, collaborative, hypermedia information systems.
coro_http
is a high-performance and easy-to-use HTTP library implemented by using C++20 coroutines. It includes an HTTP server and an HTTP client to help users quickly develop HTTP applications.
Run the following command to install the yaLanTingLibs library:
sudo yum install -y yalantinglibs-devel
Use the serialization library, RPC library, and HTTP library of yaLanTingLibs.
Use the yaLanTingLibs serialization library
Run the following command to create a
test.cpp
file:sudo vim test.cpp
Press the
i
key to enter edit mode, and then copy and paste the following content:#include <iostream> #include "ylt/struct_pack.hpp" struct person { int age; std::string name; }; int main() { person tom{.age=20,.name="tom"}; auto buffer = struct_pack::serialize(tom); auto tom2 = struct_pack::deserialize<person>(buffer); std::cout<<"age: "<<tom2.value().age<<", name: "<<tom2.value().name<<std::endl; return 0; }
Press the
Esc
key, enter:wq
, and then press theEnter
key to save the configuration.Run the following command to compile the program:
clang++ test.cpp -std=c++20 -o test
Run the following command to execute the program:
./test
The following figure shows the result, which indicates that the program is executed successfully.
Use the C++ RPC library
Run the following command to create a
server.cpp
file on the server:sudo vim server.cpp
Press the
i
key to enter edit mode, and then copy and paste the following content:#include "ylt/coro_rpc/coro_rpc_server.hpp" std::string ping(std::string ping) { return "Receive: " + ping + ". Return pong."; } int main() { coro_rpc::coro_rpc_server server{1 , 8801}; server.register_handler<ping>(); return server.start(); }
Press the
Esc
key, enter:wq
, and then press theEnter
key to save the configuration.Run the following command to create a
client.cpp
file on the client:sudo vim client.cpp
Press the
i
key to enter edit mode, and then copy and paste the following content:#include <iostream> #include "ylt/coro_rpc/coro_rpc_client.hpp" std::string ping(std::string); async_simple::coro::Lazy<void> example(){ coro_rpc::coro_rpc_client client; auto ec = co_await client.connect("localhost","8801"); assert(!ec); auto ret = co_await client.call<ping>("ping"); std::cout << ret.value() << std::endl; co_return; }; int main(){ async_simple::coro::syncAwait(example()); return 0; }
Press the
Esc
key, enter:wq
, and then press theEnter
key to save the configuration.Run the following command on the server to compile the server-side program:
clang++ server.cpp -I /usr/include/ylt/thirdparty -std=c++20 -o server -lpthread
Run the following command on the client to compile the client-side program:
NoteBefore you compile the client-side program, make sure that Alibaba Cloud Compiler is installed on the client and environment variables are imported to the client. For more information, see Alibaba Cloud Compiler compilation.
clang++ client.cpp -I /usr/include/ylt/thirdparty -std=c++20 -o client -lpthread
Run the following command on the server or client to start the server and client:
./server & ./client
The following result is returned. The preceding log entries describe the entire process from starting the RPC server, the RPC server listening to RPC requests, the RPC client sending RPC requests, the RPC server processing the RPC requests, to the RPC client closing the connection.
Use the C++ HTTP library
Run the following command to create an
http.cpp
file on the server:sudo vim http.cpp
Press the
i
key to enter edit mode, and then copy and paste the following content:#include <iostream> #include "ylt/coro_http/coro_http_client.hpp" #include "ylt/coro_http/coro_http_server.hpp" using namespace std::chrono_literals; using namespace coro_http; async_simple::coro::Lazy<void> basic_usage() { coro_http_server server(1, 9001); server.set_http_handler<GET>( "/get", [](coro_http_request &req, coro_http_response &resp) { resp.set_status_and_content(status_type::ok, "ok"); }); server.async_start(); std::this_thread::sleep_for(300ms); coro_http_client client{}; auto result = co_await client.async_get("http://127.0.0.1:9001/get"); assert(result.status == 200); assert(result.resp_body == "ok"); for (auto [key, val] : result.resp_headers) { std::cout << key << ": " << val << "\n"; } } int main() { async_simple::coro::syncAwait(basic_usage()); }
Press the
Esc
key, enter:wq
, and then press theEnter
key to save the configuration.Run the following command to compile the HTTP program:
clang++ http.cpp -I /usr/include/ylt/thirdparty -std=c++20 -o http -lpthread
Run the following command to execute the HTTP program:
./http
The following figure shows the result, which indicates that the program is executed successfully.