{"id":29553439,"url":"https://github.com/fededp/libmodule","last_synced_at":"2025-09-07T10:38:40.062Z","repository":{"id":54152628,"uuid":"123963483","full_name":"FedeDP/libmodule","owner":"FedeDP","description":"C simple and elegant implementation of an actor library ","archived":false,"fork":false,"pushed_at":"2023-06-11T19:07:38.000Z","size":1485,"stargazers_count":137,"open_issues_count":3,"forks_count":9,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-07-18T08:40:24.932Z","etag":null,"topics":["actors","bsd","c","libmodule","library","linux","linux-library","modular","oop","osx"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FedeDP.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-03-05T18:49:59.000Z","updated_at":"2025-07-07T11:38:36.000Z","dependencies_parsed_at":"2025-07-18T06:38:09.546Z","dependency_job_id":"8116a127-aa5a-4689-8f7a-3577a2fcff26","html_url":"https://github.com/FedeDP/libmodule","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/FedeDP/libmodule","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedeDP%2Flibmodule","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedeDP%2Flibmodule/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedeDP%2Flibmodule/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedeDP%2Flibmodule/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FedeDP","download_url":"https://codeload.github.com/FedeDP/libmodule/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedeDP%2Flibmodule/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274026705,"owners_count":25209739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actors","bsd","c","libmodule","library","linux","linux-library","modular","oop","osx"],"created_at":"2025-07-18T06:38:06.778Z","updated_at":"2025-09-07T10:38:40.030Z","avatar_url":"https://github.com/FedeDP.png","language":"C","readme":"# Libmodule\n\n[![CI Build](https://github.com/FedeDP/libmodule/actions/workflows/ci.yaml/badge.svg)](https://github.com/FedeDP/libmodule/actions/workflows/ci.yaml)\n[![CodeQL](https://github.com/FedeDP/libmodule/actions/workflows/codeql.yaml/badge.svg)](https://github.com/FedeDP/libmodule/actions/workflows/codeql.yaml)\n[![Documentation Status](https://readthedocs.org/projects/libmodule/badge/?version=latest)](https://libmodule.readthedocs.io/en/latest/?badge=latest)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## What is this?\n\nLibmodule offers a small and simple C implementation of an actor library that aims to let developers easily create modular C projects in a way which is both simple and elegant.  \nIndeed, libmodule was heavily inspired by my own actor library experience with [akka](https://akka.io/) for its API.  \n\n## What is a module, anyway?\n\nUnsurprisingly, module is the core concept of libmodule architecture.  \nA module is an Actor that can listen on non-pubsub events too.  \nFrankly speaking, it is denoted by a M_MOD() macro plus a bunch of mandatory callbacks, eg:\n```C\n#include \u003cmodule/mod_easy.h\u003e\n#include \u003cmodule/ctx.h\u003e\n#include \u003cunistd.h\u003e\n#include \u003cstring.h\u003e\n#include \u003cctype.h\u003e\n\nM_MOD(\"Pippo\");\n\nstatic bool m_mod_on_eval(mod_t *mod) {\n    /* Should module be started? */\n    return true;\n}\n\nstatic bool m_mod_on_start(mod_t *mod) {\n    /* Register STDIN fd */\n    m_mod_src_register(mod, STDIN_FILENO, 0, NULL);\n    return true;\n}\n\nstatic void m_mod_on_stop(mod_t *mod) {\n    \n}\n\nstatic void m_mod_on_evt(m_mod_t *mod, const m_queue_t *const evts) {\n    m_itr_foreach(evts, {\n        m_evt_t *msg = m_itr_get(m_itr);\n        switch (msg-\u003etype) {\n        case M_SRC_TYPE_FD: {\n            char c;\n            read(msg-\u003efd_evt-\u003efd, \u0026c, sizeof(char));\n            switch (tolower(c)) {\n                case 'q':\n                    m_mod_log(mod, \"Leaving...\\n\");\n                    m_mod_tell(mod, mod, \"ByeBye\", 0);\n                    break;\n                default:\n                    if (c != ' ' \u0026\u0026 c != '\\n') {\n                        m_mod_log(mod, \"Pressed '%c'\\n\", c);\n                    }\n                    break;\n            }\n            break;\n        }\n        case M_SRC_TYPE_PS:\n            if (strcmp((char *)msg-\u003eps_evt-\u003edata, \"ByeBye\") == 0) {\n                m_mod_log(\"Bye\\n\"):\n                m_ctx_quit(0);\n            }\n            break;\n        }\n    }\n}\n```\nIn this example, a \"Pippo\" module is created and will echo chars from stdin until 'q' is pressed, exiting with 0.  \nNote that it does not even need a main function, as libmodule already provides a default one as a [weak, thus overridable, symbol](https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html).  \n\n## Is it portable?\n\nYes, it is. Non-portable code is actually [compile-time-plugins](Lib/core/poll/) based.  \nOn linux, libmodule's internal loop will use epoll, while on BSD and MacOS it will use kqueue.  \nOn other OS, cmake will fallback at looking for [libkqueue](https://github.com/mheily/libkqueue), a drop-in replacement for kqueue.  \n\nFinally, it heavily relies upon gcc attributes that may or may not be available for your compiler.\n\n## Is there any documentation?\n\nYes, it is availabe at [readthedocs](http://libmodule.readthedocs.io/en/latest/).  \nThere are some simple examples too, see [Samples](Samples/) folder.  \nTo see a real project using libmodule, see [Clight](https://github.com/FedeDP/Clight) and [Clightd](https://github.com/FedeDP/Clightd).\n\n## CI\n\nLibmodule, samples and tests are built and tested with github actions on ubuntu, freebsd, and macos.  \nMoreover, tests are executed and valgrind checked too.  \nFinally, a codeQL workflow ensures code quality.  \n\n## But...why?\n\nWe all know OOP is not a solution to every problem and C is still a beautiful and much used language.  \nStill, I admit to love code modularity that OOP enforces; moreover, I realized that I was using same code abstractions over and over in my C projects (both side projects and at my job).  \nSo I thought that writing a library to achieve those same abstractions in a cleaner and simpler way was the right thing to do and could help some other dev. \n\n## Build dep and how to build\n\nYou only need cmake to build libmodule on Linux and BSD/osx; it does not depend upon external software.  \nOn other platforms, you will need [libkqueue](https://github.com/mheily/libkqueue) too.  \nTo build, you only need to issue:\n\n    $ mkdir build\n    $ cd build\n    $ cmake -G \"Unix Makefiles\" -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib ../\n    $ make\n\n*Note that libmodule can also be built as static library, by passing -DSTATIC_MODULE=true parameter to cmake.*\n\nInstallation - Generic OS\n-------------------------\n\n    # make install\n\nInstallation - Red Hat\n----------------------\n\n    $ cpack -G RPM\n\nAnd finally install generated RPM package.\n\nInstallation - Debian\n---------------------\n\n    $ cpack -G DEB\n\nAnd finally install generated DEB package.\n\nLibmodule will install a pkg-config script too: use it to link libmodule in your projects, or use \"-lmodule\" linker flag.  \nPlease note that in order to test examples, there is no need to install the library.\n\nFor Archlinux users, Libmodule is available on [AUR](https://aur.archlinux.org/packages/libmodule/).\n\n## License\nLibmodule is made available with a MIT license to encourage people to actually try it out and maybe use it inside their project, no matter if open or closed source.  \n\n*Are you using libmodule in your project? Please let me know and I will gladly list it here.*\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffededp%2Flibmodule","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffededp%2Flibmodule","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffededp%2Flibmodule/lists"}