Library / SDK
acl-dev/acl avatar
acl-dev/acl

acl-dev/acl: a cross-platform C/C++ network library with coroutines, HTTP, Redis and MQTT built in

C/C++ server and network library, including coroutine,redis client,http/https/websocket,mqtt, mysql/postgresql/sqlite client with C/C++ for Linux, Android, iOS, MacOS, Windows, Harmony,etc..

3,103 stars949 forksCLGPL-2.1

At a glance

What is it?
acl (Advanced C/C++ Library) bundles coroutines, protocol clients and a server framework into one LGPL-2.1 codebase for Linux, Windows, macOS, Android, iOS and HarmonyOS. It suits teams writing C or C++ services who want the protocol work already done, and it asks for a build-system commitment in return.
Who is it for?
Adopt acl when you are writing a C or C++ service that needs HTTP, Redis, MQTT or MySQL/PostgreSQL/SQLite access and you would rather not assemble four separate client libraries. Do not adopt it when your codebase is C++17-and-later and you already depend on Boost.Asio or another event loop, or when a GPL-style copyleft obligation on a statically linked library is a problem for your distribution.
Can I use it commercially?
Yes, with conditions. LGPL-2.1 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What acl actually packages, and who ends up using it

Most C network codebases end up vendoring the same four things: an event loop, an HTTP parser, a Redis client and a database abstraction. acl ships all four in one tree, plus MQTT, Memcached, Beanstalk, Handler Socket, SMTP, ICMP, XML, JSON, MIME, BASE64, RFC2047 and RFC1035 codecs. The README describes it as a "cross-platform network communication library and server programming framework" and lists Linux, Windows, Solaris, FreeBSD, macOS, Android, iOS and HarmonyOS as targets.

The audience is narrow and specific. This is for engineers writing servers or long-running clients in C or C++, on a platform matrix that includes at least one non-Linux target. If you only ship Linux x86_64 and you are happy with libcurl plus hiredis, acl's surface area is larger than your problem. The value shows up when the same source has to compile for an Android NDK build and a Windows MSVC solution, because the repository carries ndk-build.sh, ndk-build-r9d.sh, ndk-build-r20.sh and separate acl_vc2003.sln through acl_vc2022.sln project files for that purpose.

The coroutine layer and how it hooks the system calls underneath

The design choice that shapes everything else is the coroutine implementation. Rather than asking you to write callbacks against an event loop, acl hooks the blocking system calls so ordinary-looking code becomes asynchronous. The README lists the hooked APIs: read, readv, recv, recvfrom, recvmsg on the read side; write, writev, send, sendto, sendmsg, sendfile64 on the write side; socket, listen, accept, connect, setsockopt; select, poll, epoll_create, epoll_ctl, epoll_wait; and gethostbyname, gethostbyname_r, getaddrinfo, freeaddrinfo for name resolution.

That last group matters. DNS is implemented natively inside the coroutine scheduler, so a name lookup does not stall the whole thread. The event engines supported are select, poll, epoll, kqueue, iocp and win32 GUI messages, which is what makes the same coroutine code run on a Linux server and a Windows desktop application. A shared stack mode is offered to cut memory per coroutine.

The trade-off is real. Hooking libc symbols is powerful and it is also the part most likely to surprise you in a large binary: if another library in your process also expects blocking semantics, or if you link acl statically into a plugin host, the interception scope is something you have to reason about per platform. The README documents which APIs are hooked; it does not document what happens when a third-party library calls them.

Building acl from the top-level Makefile

The repository root carries a Makefile that detects the host, sets an RPATH-style variable for linux32, linux64, aarch64, macos or mingw, and picks the system libraries. The default compiler is g++ when ENV_CC is unset, and the Linux branch adds -lpthread -lz -lrt -ldl. Builds land in ./dist/lib and ./dist/include according to the Makefile's LIB_DIST and INC_PATH variables.

The usual sequence is a plain make at the root, then the same make with an install target, since the Makefile defines DESTDIR and PREFIX (PREFIX defaults to usr) and installs headers under include/acl-lib. The README also points at BUILD.md for per-platform notes and at cmake-build.sh for a CMake path.

A first real use: compiling against the installed headers

Once the library is built and installed, the headers sit under the acl-lib include prefix and the static or shared objects under the corresponding lib directory. A minimal compile line links the acl libraries plus the system dependencies the Makefile already declared.

The exact library names differ between the C core and the C++ wrapper, so check dist/lib after the build rather than guessing. The README's Quick Start section is the authoritative place for runnable examples: it covers a simple TCP server, a simple TCP client, a coroutine TCP server, an HTTP client example, a coroutine HTTP server and a Redis client example. SAMPLES.md lists further sample code, and the test/ directory in the repository holds additional programs you can build against the same tree.

If you are targeting Android, the repository provides ndk-build.sh and the versioned ndk-build-r9d.sh and ndk-build-r20.sh wrappers, plus a build4android.sh script at the root. For iOS there is a build4ios/ directory. Those are the documented entry points; the README does not describe a single unified cross-compilation command that covers every target.

Where acl is the wrong tool

The licence is the first constraint. acl is LGPL-2.1, and the repository also contains a LICENSE.IBM file. LGPL-2.1 places conditions on how you combine the library with your own code, and those conditions differ depending on whether you link dynamically or statically. If your product ships as a single static binary and you cannot or will not provide the relinking path the licence contemplates, acl is the wrong dependency, regardless of its technical fit. This is a licensing question for your own counsel, not something the README answers.

The second constraint is the coroutine model itself. Intercepting libc calls is not a standard ABI guarantee. On a platform where the runtime, a profiler or a sandbox already wraps those symbols, you inherit an interaction you did not design. Projects that need predictable, auditable syscall behaviour in a debugger or a seccomp profile will find a callback-based event loop easier to reason about.

The third is scope. If you need HTTP and nothing else, pulling in the MQTT, Redis, Memcached, Beanstalk, SMTP and ICMP implementations adds code you have to keep patched. The README does not describe a modular build that lets you compile out individual protocol modules, so the practical unit is the whole library.

How it compares with assembling libcurl, hiredis and libuv

The alternative most teams reach for is a stack of single-purpose libraries: libcurl for HTTP and HTTPS, hiredis for Redis, libuv or Boost.Asio for the event loop, and a separate MySQL or PostgreSQL client. Each of those is smaller, has a narrower licence surface, and has its own release cadence you can pin independently.

The difference in approach is where the integration lives. With the assembled stack, you write the glue: you decide how a curl easy handle coexists with a libuv loop, you manage connection pooling yourself, and you handle the cross-platform build matrix per library. With acl, that glue is inside the library, and the coroutine hook is what makes blocking-looking client code work on top of an epoll or iocp loop. You trade control over individual components for a single build and a single API surface across eight platforms.

There is a middle path the README implies but does not spell out: acl exposes a unified abstract interface for MySQL, PostgreSQL and SQLite, and a connection pool manager, so you could adopt it only for the database layer while keeping your existing HTTP stack. Nothing in the documentation describes a supported partial-install mode, so verify that by inspecting the Makefile targets before assuming it.

Maintenance, upgrades and the licence files in the tree

The repository is not archived, and the last push was on 2026-09-14. Releases have been frequent: v3.6.8 on 2026-06-04, v3.6.7 on 2026-05-08 and v3.6.6 on 2026-03-09. That cadence suggests minor-version upgrades arrive every few weeks, and the changes.txt file at the root is where the project records what moved between them.

Upgrade cost is dominated by the build, not the API. The repository carries Visual Studio solution files from 2003 through 2022, which tells you the project keeps old toolchains alive, but it also means the build paths you must maintain multiply with each platform you support. A version bump on Linux is a make and a relink; a version bump across Linux, Android and Windows means re-running ndk-build.sh and rebuilding the relevant .sln.

On licensing, the tree contains LICENSE.txt and LICENSE.IBM. The project is described as LGPL-2.1. The presence of a second, IBM-attributed licence file means the terms are not uniform across the whole tree, so read both before you vendor any file. Nothing in the README summarises which parts fall under which file.

Editorial conclusion

Adopt acl when you are writing a C or C++ service that needs HTTP, Redis, MQTT or MySQL/PostgreSQL/SQLite access and you would rather not assemble four separate client libraries. Do not adopt it when your codebase is C++17-and-later and you already depend on Boost.Asio or another event loop, or when a GPL-style copyleft obligation on a statically linked library is a problem for your distribution. Before committing, read LICENSE.txt and LICENSE.IBM against your own linking model, then build the library from the top-level Makefile and run one sample from SAMPLES.md on the exact platform you ship on, because the README documents platform-specific build paths rather than a single portable one.

Frequently asked questions

How do I build acl on Linux?

The top-level Makefile detects the host and sets the appropriate RPATH variable for linux32, linux64 or aarch64, and the Linux branch links against pthread, z, rt and dl. Running make at the repository root produces output under ./dist/lib and ./dist/include. BUILD.md carries the per-platform notes.

Does acl support Android and iOS?

Yes. The repository includes build4android.sh, ndk-build.sh and versioned ndk-build-r9d.sh and ndk-build-r20.sh wrappers for Android, and a build4ios/ directory for iOS. The README lists Android, iOS and HarmonyOS among the supported platforms.

What licence does acl use?

The project is licensed under LGPL-2.1. The repository also contains a LICENSE.IBM file alongside LICENSE.txt, so the terms are not uniform across every file in the tree.

Which databases can acl connect to?

The README states that acl provides a unified abstract interface for MySQL, PostgreSQL and SQLite, along with a connection pool manager. It also ships client libraries for Redis, Memcached, Beanstalk and Handler Socket.

Official sources

  1. acl-dev/acl on GitHub
  2. License: LGPL-2.1
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/acl-dev-acl.svg)](https://hysenlabs.com/projects/acl-dev-acl)