记录 build Acl 的相关

日常并不写 c++ 项目,看到 Acl 这个库比较有意思,就试着编译了一下 samples

照猫画虎,记录一下遇到的相关问题

Acl

https://github.com/acl-dev/acl

Acl – One Advanced C/C++ Library for Unix/Windows

Acl build

BUILD.md 但感觉写的比较简单,还是看了 Makefile

最后用make all_lib && make packinstall生成 include 和 lib

Sample build

Sample 代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <thread>
#include "acl_cpp/lib_acl.hpp"

void run(void) {
const char* addr = "127.0.0.1:8088";
acl::server_socket server;
if (!server.open(addr)) { // Bind and listen the local address.
return;
}

while (true) {
acl::socket_stream* conn = server.accept(); // Wait for connection.
if (conn == NULL) {
break;
}
std::thread thread([=] { // Start one thread to handle the connection.
char buf[256];
int ret = conn->read(buf, sizeof(buf), false); // Read data.
if (ret > 0) {
conn->write(buf, ret); // Write the received data.
}
delete conn;
});
thread.detach();
}
}

环境为 macOS,g++ 为 clang,vim 编辑会提示一些问题

  • #include “acl_cpp/lib_acl.hpp” 这行报文件找不到
  • std::thread thread([=] { 这行报expected_expression: expected expression

第一个是因为 clang 不知道你的 include 路径

第二个是[=] {} lambda 表达式是C++11标准,也需要告诉一下 clang

这两个问题都可以用compile_flags.txt解决

方法是在本文件同目录下生成compile_flags.txt文件,内容为

1
2
-std=c++11
-I../include/acl-lib

就跟传给 gcc / g++ 的参数一样,但更推荐的是compile_commands.json的方式,并且是在编译时自动生成

于是我们写CMakeLists.txt

CMake

引入 CMake 调整目录结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.
├── CMakeLists.txt
├── apps
│   └── main.cpp
├── build
├── include
│   └── acl-lib
│   ├── acl
│   ├── acl_cpp
│   ├── fiber
│   └── protocol
├── lib
│   └── libacl_all.a
└── src
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cmake_minimum_required(VERSION 3.5)
project(MyProject VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)

add_executable(test apps/main.cpp)

target_link_libraries(test PUBLIC acl_all)
target_link_directories(test
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib>
$<INSTALL_INTERFACE:lib>
)

target_include_directories(test
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/acl-lib>
$<INSTALL_INTERFACE:include/acl-lib>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)

在 CMakeLists 中指定 C++ 标准 11

指定 include 的头文件地址,include 为第三方库目录,src 为私有代码库目录

指定 libacl_all.a 文件所在路径

最后在 build 目录下

1
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ..

会生成compile_commands.json

1
2
3
4
5
6
7
[
{
"directory": "/Users/hbspy/test/acl/build",
"command": "/Library/Developer/CommandLineTools/usr/bin/c++ -I/Users/hbspy/test/acl/include/acl-lib -I/Users/hbspy/test/acl/src -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk -std=gnu++11 -o CMakeFiles/test.dir/apps/main.cpp.o -c /Users/hbspy/test/acl/apps/main.cpp",
"file": "/Users/hbspy/test/acl/apps/main.cpp"
}
]

这里还会报一个错,ld: entry point (_main) undefined.

原因 clang 没找到入口的 main 函数,把 samples 中的 void run 改成 int main 并修改一下 return 细节就可以了

此时的 vim 中,已经可以正确的根据生成的 compile_commands.json 找到 include 的头文件地址

以及认识[=] {}这样的 C++11 标准了

可喜可贺