autoconf学习笔记

autoconf学习笔记

configure.in/configure.ac是各种宏的集合,主要作用是编译流程的整合
具体文件生成的配置,其实是在Makefile.am里进行的,然后经过automake处理Makefile.am生成发布用的Makefile.in。
在执行configure时,将使用Makefile.in里的参数生成Makefile。

注:目前没看到autoconf和automake有自动列举目录中所有文件的能力。这点不及CMake方便。不过,可以通过脚本生成Makefile.am的方式来自动引入源文件。但Cmake没有 autoconf的 make distclean清理中间文件的能力。

Makefile.am中是使用 组合字符串的方式进行变量定义。
特定变量在后面,前面是一个指示或者已定义的标示。
比如 特定变量有 PROGRAMS LIBRARIES
inst_PROGRAMS=program_name 表明需要生成要安装的可执行文件program_name
noinst_PROGRAMS=program_name 则是不用安装的。
然后用 program_name_SOURCES= 声明所用到的源文件,
program_name_LDADD= 声明用到的库文件。
其中PROGRAMS=行所的程序文件名如果包含./等字符,在后续的变量声明中要替换成_下划线。

首先使用 autoscan 自动生成初始化的configure.scan
然后改名为configure.ac根据需要修改其中内容。
使用宏AM_INIT_AUTOMAKE来引入automake。

注意,如果要使用子目录的话,需要在configure.ac的最后AC_OUTPUT中声明生成子目录的文件,比如Makefile,Makefile.in之类。AC_OUTPUT(Makefile src/Makefile test/Makefile)
否则,即使在Makefile.am中声明了SUBDIRS也会因为缺少子目录中的Makefie而不能工作。因为automake负责生成Makefile.in,而configure负责生成Makefile.

附一个更新用脚本
#/bin/sh
set -x #enable trace
if [ -e Makefile ];then make distclean; fi

aclocal
#autoheader
automake --foreign --add-missing
autoconf
### C++ gRPC 学习教程和示例代码 #### 一、环境搭建 为了能够顺利运行C++中的gRPC程序,需要先完成开发环境的配置。这通常涉及到安装必要的依赖库以及设置编译工具链。具体来说,可以按照官方文档指导来准备所需的软件包,比如Protocol Buffers编译器`protoc`及其对应的C++插件,还有gRPC核心库等[^1]。 ```bash sudo apt-get install build-essential autoconf libtool pkg-config git clone https://github.com/protocolbuffers/protobuf.git cd protobuf ./autogen.sh && ./configure && make -j$(nproc) && sudo make install ``` 对于gRPC本身,则可以通过如下命令获取并构建: ```bash git clone --recurse-submodules -b v1.48.x https://github.com/grpc/grpc cd grpc mkdir -p cmake/build && cd cmake/build cmake ../.. make -j$(nproc) sudo make install ``` #### 二、创建Protobuf文件 接下来就是定义服务接口,在`.proto`文件里描述消息结构和服务方法。这里给出一个简单的例子——HelloWorld服务,其中包含了一个名为SayHello的方法用于接收请求并向客户端返回响应信息。 ```protobuf syntax = "proto3"; option cc_enable_arenas = true; package helloworld; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; } ``` 保存上述内容到`helloworld.proto`之后,利用之前提到过的`protoc`命令行工具将其转换成相应的头文件与源码文件以便后续使用。 #### 三、编写服务器端逻辑 基于前面所生成的服务类模板,现在可以在项目中实现具体的业务处理函数了。下面展示的是如何继承自动生成出来的基类,并重写虚函数以提供实际功能的部分代码片段。 ```cpp #include <iostream> #include "helloworld.grpc.pb.h" using namespace std; using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; using grpc::Status; using helloworld::Greeter; using helloworld::HelloReply; using helloworld::HelloRequest; class GreeterServiceImpl final : public Greeter::Service { public: Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override { string prefix("Hello "); reply->set_message(prefix + request->name()); return Status::OK; } }; ``` 这段代码实现了当接收到客户端发起的调用时会执行的操作:拼接字符串形成回复文本并通过参数传递给对方。 #### 四、启动监听进程 有了完整的协议声明加上对应的功能模块后就可以着手建立网络连接等待远端访问啦! ```cpp void RunServer() { string server_address("0.0.0.0:50051"); GreeterServiceImpl service; ServerBuilder builder; // Listen on the given address without any authentication mechanism. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); // Register "service" as the instance through which we'll communicate with // clients. In this case it corresponds to an *synchronous* service. builder.RegisterService(&service); // Finally assemble the server. unique_ptr<Server> server(builder.BuildAndStart()); cout << "Server listening on " << server_address << endl; // Wait for the server to shutdown. Note that some other thread must be // responsible for shutting down the server for this call to ever return. server->Wait(); } ``` 此部分负责初始化HTTP/2传输层设施并将指定地址开放出去供外界联系;同时注册好先前定义好的处理器对象使得每次有新链接进来都能找到合适的地方去解析数据流进而触发相应动作。 #### 五、客户端编程指南 最后一步自然是要让应用程序具备主动出击的能力咯~即构造出能向远程主机发出请求的消息体格式化为wire format再经由socket发送过去得到回应为止的过程。 ```cpp void RunClient() { string target_str("localhost:50051"); // Instantiate the client. It requires a channel, out of which the actual RPCs // are created. This channel models a connection to an endpoint specified by // the argument; you may provide extra arguments to indicate credentials, // compression Level etc. shared_ptr<Channel> channel = CreateChannel(target_str, InsecureChannelCredentials()); // Stub acts like a proxy object representing remote side entity. unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel)); // Data we are sending to the server. HelloRequest request; request.set_name("you"); // Container for the data we expect from the server. HelloReply reply; // Context for the client. It could be used to convey extra information to // the server and/or tweak certain RPC behaviors. ClientContext context; // The actual RPC. Status status = stub->SayHello(&context, request, &reply); // Act upon its status. if (status.ok()) { cout << "Greeter received: " << reply.message() << endl; } else { cerr << status.error_code() << ": " << status.error_message() << endl; } } ``` 以上便是整个流程的大致介绍,当然这只是冰山一角而已,更多高级特性和最佳实践还需要读者朋友们自行探索学习哦~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值