{"id":24589385,"url":"https://github.com/ppebb/cosmo-stub-generator","last_synced_at":"2025-03-17T22:05:46.876Z","repository":{"id":271970776,"uuid":"915141182","full_name":"ppebb/cosmo-stub-generator","owner":"ppebb","description":"Generate a stub for any C library for use with Cosmopolitan","archived":false,"fork":false,"pushed_at":"2025-01-16T04:15:34.000Z","size":602,"stargazers_count":14,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-24T08:15:28.154Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Lua","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/ppebb.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}},"created_at":"2025-01-11T04:34:08.000Z","updated_at":"2025-01-17T20:31:01.000Z","dependencies_parsed_at":"2025-01-11T05:26:56.134Z","dependency_job_id":"fe9f5800-6304-4ac9-86b1-74bc237d0579","html_url":"https://github.com/ppebb/cosmo-stub-generator","commit_stats":null,"previous_names":["ppebb/cosmo-stub-generator"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppebb%2Fcosmo-stub-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppebb%2Fcosmo-stub-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppebb%2Fcosmo-stub-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppebb%2Fcosmo-stub-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ppebb","download_url":"https://codeload.github.com/ppebb/cosmo-stub-generator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244117640,"owners_count":20400743,"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","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":[],"created_at":"2025-01-24T08:15:34.510Z","updated_at":"2025-03-17T22:05:46.838Z","avatar_url":"https://github.com/ppebb.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cosmo-stub-generator\n\nThis project uses libclang to parse the header files of any project and output\na stub for use with [cosmopolitan](https://github.com/jart/cosmopolitan).\n\n## Generating Stubs\n\n0. Have lua 5.4\n1. Build libclang-lua (make sure to checkout submodules), following the\n   instructions at https://github.com/ppebb/libclang-lua.\n2. Install [luafilesystem](https://lunarmodules.github.io/luafilesystem/)\n3. Add a header file to `./specs` that `#include`s whichever headers you wish\n   to process\n4. Add a lua file to `./specs` which returns a table in the following format,\n   with gobject as an example:\n    ```lua\n    local utils = require(\"src.utils\")\n\n    return {\n        -- The name of the stub, will output in ./stubs/name-stub\n        name = \"gobject\",\n        -- A list of filters (written as lua patterns) for the paths containing\n        -- your header files. If you don't have these, libclang will traverse\n        -- every header in the entire translation unit, and you'll end up with\n        -- things like time.h in your stub\n        filter = { \"%/usr%/include%/glib%-2%.0%/gobject%/\", \"%/usr%/include%/glib%-2%.0%/glib%-object%.h%/\" },\n        -- The header file you want to use from step 1, any path. The below will\n        -- resolve to ./specs/gobject_spec.h\n        hfile = utils.path_combine(utils.spec_path(), \"gobject_spec.h\"),\n        -- The shared object, the name is just used as the variable name internally\n        -- for the loaded so, fnames is a list of acceptable library names which will\n        -- be searched on program launch\n        so = { name = \"gobject\", fnames = { \"libgobject-2.0.so\", \"libgobject-2.0-0.dll\" } },\n        -- The directories for libclang to search for headers in, included using\n        -- the -isystem argument\n        search_dirs = {\n            \"/usr/include/glib-2.0/\",\n            \"/usr/lib/glib-2.0/include/\",\n        },\n        -- Headers to include in your generated stub\n        header_includes = {\n            \"glib-object.h\",\n        },\n        -- Optional, function bodies you can define to be included in the stub to\n        -- overwrite ones automatically generated. Use cases include variadic\n        -- functions which do not map correctly to an automatically located function\n        -- taking a va_list\n        explicit_function_bodies = {\n            -- From https://github.com/GNOME/glib/blob/83200855579964a20d3929f37a37431e4952d156/gobject/gobject.c#L2406\n            g_object_new = [[gpointer g_object_new(GType object_type, const gchar *first_property_name, ...) {\n        GObject *object;\n        va_list var_args;\n\n        /* short circuit for calls supplying no properties */\n        if (!first_property_name)\n            return stub_funcs.ptr_g_object_new_with_properties(object_type, 0, NULL, NULL);\n\n        va_start(var_args, first_property_name);\n        object = stub_funcs.ptr_g_object_new_valist(object_type, first_property_name, var_args);\n        va_end(var_args);\n\n        return object;\n    }]],\n            -- From https://github.com/GNOME/glib/blob/7129521966fa7c4cd876b2aa429f1c8d50290902/gobject/gsignal.c#L1399\n            g_signal_new = [[guint g_signal_new (const gchar *signal_name, GType itype, GSignalFlags signal_flags, guint class_offset, GSignalAccumulator accumulator, gpointer accu_data, GSignalCMarshaller c_marshaller, GType return_type, guint n_params, ...) {\n        va_list args;\n        guint signal_id;\n\n        g_return_val_if_fail(signal_name != NULL, 0);\n        va_start(args, n_params);\n\n        signal_id = stub_funcs.ptr_g_signal_new_valist(signal_name, itype, signal_flags,\n            class_offset ? stub_funcs.ptr_g_signal_type_cclosure_new(itype, class_offset): NULL,\n            accumulator, accu_data, c_marshaller, return_type, n_params, args);\n\n        va_end(args);\n\n        return signal_id;\n    }]],\n        },\n    }\n    ```\n    Additional examples can be located in the `./specs` directory\n5. `require` your lua spec in the `stubs` table in `./src/generate.lua`\n6. Run `lua src/generate.lua path/to/clang/include`, path/to/clang/include should be somewhere like `/usr/lib/clang/19/include/`\n\n## Included Stubs\n\nThis repository includes full[^1] stubs for\n* GTK (and GSK, GDK)\n* GLib\n* GIO\n* GObject,\n* GModule\n* GIRepository\n* GLFW\n* OpenGL\n* SDL2\n* SDL2_ttf\n\n[^1]: Some variadic functions may be\nmissing, but their equivalents should exist.\n\n## Using Stubs\n\nThe stubs should work out of the box, just copy the relevant stub directory\n(alongside `./stubs/stub.c` and `./stubs/stub.h`) and then include them in your\nproject. If you don't want 12000 lines of C to appear, add them to\nlinguist-vendored (see `.gitattributes` at the root of this repository).  \n\nIn your main function, make sure you initialize each stub on program launch and\nclose them on program load. The functions follow the naming convention\n`initialize_soname()` and `close_soname()`, using the sonames provided in the\nspec.\n\n\n## Notes\n\nCertain function attributes and keywords may not be handled\ncurrently.`noreturn` functions alongside `volatile` and `restrict` parameters\nare examples which are handled. For anything similar that is missing, open up\nan issue or a PR.\n\nAdditionally, libclang resolves types such as `unsigned int` or `unsigned char`\nto `UInt` and `UChar`, which must be manually handled. Refer to the function\n`cxtype_name` in `./src/generate.lua`. I have not handled every case, so if you\nencounter one not present then you can add another case there (PRs welcome!).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fppebb%2Fcosmo-stub-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fppebb%2Fcosmo-stub-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fppebb%2Fcosmo-stub-generator/lists"}