{"id":13803774,"url":"https://github.com/Islam0mar/CL-CXX-JIT","last_synced_at":"2025-05-13T16:32:29.757Z","repository":{"id":44052031,"uuid":"354412791","full_name":"Islam0mar/CL-CXX-JIT","owner":"Islam0mar","description":"Common Lisp and CXX interoperation  with JIT","archived":false,"fork":false,"pushed_at":"2025-01-01T21:57:50.000Z","size":1249,"stargazers_count":65,"open_issues_count":1,"forks_count":6,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-01-01T22:29:58.666Z","etag":null,"topics":["common-lisp","cpp17","interoperability","jit"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Islam0mar.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2021-04-03T23:09:10.000Z","updated_at":"2025-01-01T21:57:54.000Z","dependencies_parsed_at":"2025-01-01T22:26:14.150Z","dependency_job_id":"554d9e62-368b-4328-9b92-f4b7acfee8c5","html_url":"https://github.com/Islam0mar/CL-CXX-JIT","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Islam0mar%2FCL-CXX-JIT","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Islam0mar%2FCL-CXX-JIT/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Islam0mar%2FCL-CXX-JIT/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Islam0mar%2FCL-CXX-JIT/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Islam0mar","download_url":"https://codeload.github.com/Islam0mar/CL-CXX-JIT/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253981931,"owners_count":21994361,"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":["common-lisp","cpp17","interoperability","jit"],"created_at":"2024-08-04T01:00:37.761Z","updated_at":"2025-05-13T16:32:24.741Z","avatar_url":"https://github.com/Islam0mar.png","language":"C++","funding_links":[],"categories":["C ##"],"sub_categories":[],"readme":"#+OPTIONS: toc:3          (only include two levels in TOC)\n* CL-CXX-JIT - Common Lisp C++ JIT for exposing C++ functions\n\nThis library provides an interface to C++ from lisp. It compiles C++ code, then loads it into lisp. It was inspired by [[https://github.com/onqtam/rcrl][RCRL]] and the older project [[https://github.com/Islam0mar/cl-cxx][CL-CXX]].\n\n** API\n=(from '(\"list of string headers\") 'import \"normal string is inserted as it is\" '(\"function/function-pointer/mem-fun-pointer/lambda\" . \"name-used-in-lisp\"))=\n\n** Examples\n*** SDL2 Example\n[[sdl2.gif]]\n#+begin_src lisp\n(ql:quickload :cxx-jit)\n(setf cxx-jit:*cxx-compiler-link-libs* \"-lGL -lSDL2 -lSDL2main\")\n\n(cxx-jit:from '(\n                \"\u003cSDL2/SDL.h\u003e\")\n              'import\n              '(\"[](){return SDL_Init(SDL_Init(SDL_INIT_VIDEO));}\" . \"init\")\n              '(\"SDL_CreateWindow\" . \"create-window\")\n              '(\"SDL_CreateRenderer\" . \"create-renderer\")\n              '(\"SDL_SetRenderDrawColor\" . \"set-color\")\n              '(\"SDL_DestroyWindow\" . \"destroy-window\")\n              '(\"SDL_RenderClear\" . \"clear-renderer\")\n              '(\"SDL_RenderPresent\" . \"renderer-render\")\n              '(\"SDL_Quit\" . \"sdl-quit\"))\n\n(init)\n(setf wind (create-window \"create-window\" 0 0 600 700 0))\n(setf rend (create-renderer wind -1 0))\n(loop for x to (* 255 3)\n      for r = (if (\u003e x 255) 255 x)\n      for g = (if (\u003e x 255) (if (\u003e x (* 2 255)) 255 (rem x 256)) 0)\n      for b = (if (\u003e x (* 2 255)) (rem x 256) 0)\n      do\n         (print x)\n         (set-color rend r g b 255)\n         (clear-renderer rend)\n         (renderer-render rend)\n         (sleep 0.01))\n\n(destroy-window wind)\n(sdl-quit)\n#+end_src\n\n*** Basic Example\nStart with =(ql:quickload :cxx-jit) (in-package cxx-jit)=\n#+begin_src lisp\n  (from '(\"\u003cstring\u003e\") 'import '(\"[](std::string x){return \\\"Hi, \\\"+x;}\" . \"hi\"))\n  (hi \"there!\")\n\n  (from '(\"\u003ccmath\u003e\") 'import '(\"static_cast\u003cdouble(*)(double)\u003e(std::sin)\" . \"cpp-sin\"))\n  (cpp-sin 0d0)\n  (cpp-sin pi)\n  (cpp-sin (/ pi 2))\n\n  (from nil 'import \"struct C{ auto hi(){return \\\"Hello, World\\\\n\\\";} auto bye(){return \\\"Bye\\\";} };\" '(\"\u0026C::bye\" . \"bye\") '(\"\u0026C::hi\" . \"hi\") '(\"[](){static C x; return x;}\" . \"cc\"))\n  (cc)\n  (hi *)\n  (bye **)\n    ;;; structure  definition could be written in a header file then be used as the following:\n  (from '(\"c.hpp\") 'import '(\"\u0026C::bye\" . \"bye\") '(\"\u0026C::hi\" . \"hi\") '(\"[](){static C x; return x;}\" . \"cc\"))\n#+end_src\n\n*** Eigen Library Example\nStart with =(ql:quickload :cxx-jit) (in-package cxx-jit)=\n#+begin_src lisp\n  (from '(\"\u003cEigen/Core\u003e\" \"\u003cEigen/Core\u003e\") 'import '(\"[](Eigen::CwiseNullaryOp\u003cEigen::internal::scalar_identity_op\u003cdouble\u003e,Eigen::Matrix\u003cdouble, 3, 3\u003e\u003e x){\n    std::stringstream s;\n    s \u003c\u003c x;\n    return s.str();}\" . \"print-matrix\"))\n\n  (from '(\"\u003cEigen/Core\u003e\" \"\u003cEigen/Core\u003e\") 'import '(\"static_cast\u003cconst Eigen::CwiseNullaryOp\u003cEigen::internal::scalar_identity_op\u003cdouble\u003e,Eigen::Matrix\u003cdouble, 3, 3\u003e\u003e (*)()\u003e (\u0026Eigen::Matrix3d::Identity)\" . \"identity-matrix\"))\n\n  (print-matrix (identity-matrix))\n#+end_src\n\n** Prerequisites\n - common lisp supporting [[https://www.common-lisp.net/project/cffi/][CFFI]]\n - working C++17 compiler\n - the following variables should be set according to OS and compiler used\n|---------------------------------------------+------------------------------------------------------------------------------------------------|\n| variable                                    | default value                                                                                  |\n|---------------------------------------------+------------------------------------------------------------------------------------------------|\n| =*cxx-compiler-executable-path*=            | \"~/usr/bin/g++~\"                                                                               |\n| =*cxx-compiler-flags*=                      | \"~-std=c++17 -Wall -Wextra -I/usr/include/eigen3~\"                                             |\n| =*cxx-compiler-working-directory*=          | \"~/tmp/~\" #\\/ '/' should be the last character                                                 |\n| =+cxx-compiler-lib-name+=                   | (intern \"~plugin~\")                                                                            |\n| =+cxx-compiler-wrap-cxx-path+=              | shouldn't be changed \"~path to wrap-cxx.cpp~\"                                                  |\n| =*cxx-compiler-internal-flags*=             | \"~-shared -fPIC -Wl,--no-undefined -Wl,--no-allow-shlib-undefined~\"                            |\n|                                             | for g++ and for clang++ \"~-shared -fPIC -Wl,-undefined,error -Wl,-flat_namespace~\"             |\n| =*cxx-compiler-link-libs*=                  | \"~-lm~\" these flags are added after \"~-o output~\" to link correctly                            |\n| =*cxx-type-name-to-cffi-type-symbol-alist*= | alist to map c++ type name to cffi type example:\"~(push (cons \"long unsigned int\" :ulong) *)~\" |\n|---------------------------------------------+------------------------------------------------------------------------------------------------|\n\n** Installation\nClone into home/common-lisp directory. Then =(ql:quickload :cxx-jit-test)=\n\n** Supported Types\n|------------------+------------------|\n| C++ type         | Lisp cffi type   |\n|------------------+------------------|\n| fundamental      | same             |\n| string           | :string          |\n| class            | :pointer         |\n| std::is_function | :pointer         |\n| other            | not implemented! |\n|------------------+------------------|\n\n** Under The Hood\n + function/lambda/member_function/function_pointer is wrapped into a dummy lambda class to have a unique template specialization.\n     #+begin_src C++ \n       Import([\u0026]() { return __VA_ARGS__; });\n      #+end_src\n + =Import= function calls =DecayThenResolve= with function pointer as the template specialization so thunk pointer is omitted and we only return the direct function pointer which will be used from lisp side.\n + =InvocableTypeName= returns a vector contains: [return type, class type for class function member, args]. It resolves C++ types as follows:\n   * Fundamental types and pointers are passed directly\n   * String is converted to char* with new[] operator, should be cleared with =ClCxxDeleteObject(ptr, true)=\n   * Class/std::is_function is converted to void* with new[] operator, should be cleared with =ClCxxDeleteObject(ptr, false)=\n   * rest report an issue for other cases\n + Meta data for each function defined is passed through a lisp callback with this data:\n    #+begin_src C++\ntypedef struct {\n  // could be void*\n  void (*thunk_ptr)();\n  bool method_p;\n  const char **type;  // memory handled in C++\n  std::uint8_t type_size;\n} MetaData;\n#+end_src\n\n** NOTE\nTested on:\n - SBCL 2.0.1 on debian\n\n** Todo List\n*** TODO Add redirect stdout : =freopen(\"/tmp/tmp.txt\", \"w\", stdout);= @apemangr\n*** TODO Use trivial-garbage with =ClCxxDeleteObject=\n*** TODO Add non-polling =from=\n*** TODO Test functions\n*** TODO Benchmark\n*** TODO Better class interface\n\n** Copyright\n\nCopyright (c) 2021 Islam Omar (io1131@fayoum.edu.eg)\n\n** License\n\nLicensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FIslam0mar%2FCL-CXX-JIT","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FIslam0mar%2FCL-CXX-JIT","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FIslam0mar%2FCL-CXX-JIT/lists"}