{
"info": {
"author": "Armin Ronacher",
"author_email": "armin.ronacher@active-4.com",
"bugtrack_url": null,
"classifiers": [
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python"
],
"description": "# Milksnake\n\n
\n
\n
\n\n\nMilksnake is an extension for setuptools that allows you to distribute\ndynamic linked libraries in Python wheels in the most portable way imaginable.\n\nIt gives you a hook to invoke your own build process and to then take the\nresulting dynamic linked library.\n\n## Why?\n\nThere are already other projects that make Python and native libraries play\nalong but this one is different. Unlike other projects that build Python\nextension modules the goal of this project is to build regular native libraries\nthat are then loaded with CFFI at runtime. Why not just use CFFI? Because\nCFFI's setuptools support alone does not properly work with such wheels (it\ndoes not provide a way to build and properly tag wheels for shared libraries) and\nit does not provide a good way to invoke an external build process (like a\nmakefile, cargo to build rust binaries etc.)\n\nIn particular you will most likely only need two wheels for Linux, one for macs\nand soon one for Windows independently of how many Python interpreters you want\nto target.\n\n## What is supported?\n\n* Platforms: Linux, Mac, Windows\n* setuptools commands: `bdist_wheel`, `build`, `build_ext`, `develop`\n* `pip install --editable .`\n* Universal wheels (`PACKAGE-py2.py3-none-PLATFORM.whl`); this can be disabled\n with `milksnake_universal=False` in `setup()` in case the package also contains\n stuff that does link against libpython.\n\n## How?\n\nThis example shows how to build a rust project with it:\n\nThis is what a `setup.py` file looks like:\n\n```python\nfrom setuptools import setup\n\ndef build_native(spec):\n # build an example rust library\n build = spec.add_external_build(\n cmd=['cargo', 'build', '--release'],\n path='./rust'\n )\n\n spec.add_cffi_module(\n module_path='example._native',\n dylib=lambda: build.find_dylib('example', in_path='target/release'),\n header_filename=lambda: build.find_header('example.h', in_path='target'),\n rtld_flags=['NOW', 'NODELETE']\n )\n\nsetup(\n name='example',\n version='0.0.1',\n packages=['example'],\n zip_safe=False,\n platforms='any',\n setup_requires=['milksnake'],\n install_requires=['milksnake'],\n milksnake_tasks=[\n build_native\n ]\n)\n```\n\nYou then need a `rust/` folder that has a Rust library (with a crate type\nof `cdylib`) and a `example/` python package.\n\nExample `example/__init__.py` file:\n\n```python\nfrom example._native import ffi, lib\n\n\ndef test():\n return lib.a_function_from_rust()\n```\n\nAnd a `rust/src/lib.rs`:\n\n```rust\n#[no_mangle]\npub unsafe extern \"C\" fn a_function_from_rust() -> i32 {\n 42\n}\n```\n\nAnd the `rust/Cargo.toml`:\n\n```toml\n[package]\nname = \"example\"\nversion = \"0.1.0\"\nbuild = \"build.rs\"\n\n[lib]\nname = \"example\"\ncrate-type = [\"cdylib\"]\n\n[build-dependencies]\ncbindgen = \"0.4\"\n```\n\nAnd finally the build.rs file:\n\n```rust\nextern crate cbindgen;\n\nuse std::env;\n\nfn main() {\n let crate_dir = env::var(\"CARGO_MANIFEST_DIR\").unwrap();\n let mut config: cbindgen::Config = Default::default();\n config.language = cbindgen::Language::C;\n cbindgen::generate_with_config(&crate_dir, config)\n .unwrap()\n .write_to_file(\"target/example.h\");\n}\n```\n\n\n",
"description_content_type": "",
"docs_url": null,
"download_url": "",
"downloads": {
"last_day": -1,
"last_month": -1,
"last_week": -1
},
"home_page": "",
"keywords": "",
"license": "Apache License 2.0",
"maintainer": "",
"maintainer_email": "",
"name": "milksnake",
"package_url": "https://pypi.org/project/milksnake/",
"platform": "any",
"project_url": "https://pypi.org/project/milksnake/",
"project_urls": null,
"release_url": "https://pypi.org/project/milksnake/0.1.5/",
"requires_dist": [
"cffi (>=1.6.0)"
],
"requires_python": "",
"summary": "A python library that extends setuptools for binary extensions.",
"version": "0.1.5"
},
"last_serial": 3697303,
"releases": {
"0.1.0": [
{
"comment_text": "",
"digests": {
"md5": "798f38423e7de89a2c8e72638b935afe",
"sha256": "885b61e284f1ad983d86fed958b5cd9dee574184df56c7ee71c0008297dac2f7"
},
"downloads": -1,
"filename": "milksnake-0.1.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "798f38423e7de89a2c8e72638b935afe",
"packagetype": "bdist_wheel",
"python_version": "2.7",
"requires_python": null,
"size": 5954,
"upload_time": "2017-10-03T14:59:23",
"url": "https://files.pythonhosted.org/packages/03/50/5ddd840378099ee5a23a95dc203a8fa4130d9a000ceba36d1f5559b14c41/milksnake-0.1.0-py2.py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "e29fd1812198730c6a095379464c34e2",
"sha256": "b07f587397feb24ac2de401be399d046a9a83233dada10f76f31dfececb45ff3"
},
"downloads": -1,
"filename": "milksnake-0.1.0.zip",
"has_sig": false,
"md5_digest": "e29fd1812198730c6a095379464c34e2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 8014,
"upload_time": "2017-10-03T14:59:27",
"url": "https://files.pythonhosted.org/packages/e8/ba/056412bc1edbdfa7664c74846f2939ca029972e12d46ea15bae591023845/milksnake-0.1.0.zip"
}
],
"0.1.1": [
{
"comment_text": "",
"digests": {
"md5": "b77fefad13a0181a788d37f07f617270",
"sha256": "6829026c2a3d116446f7345646bec111f411ce23e39cae208876e41a19b1e98f"
},
"downloads": -1,
"filename": "milksnake-0.1.1-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "b77fefad13a0181a788d37f07f617270",
"packagetype": "bdist_wheel",
"python_version": "2.7",
"requires_python": null,
"size": 6066,
"upload_time": "2017-10-04T00:01:59",
"url": "https://files.pythonhosted.org/packages/53/be/466bcb7bee08acae8915fffb9d818468a656569f04d489ff5c36a31448c3/milksnake-0.1.1-py2.py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "65c8d66c7175f7469737f1dc1fc7de8a",
"sha256": "fe73b6bee763c8eff5c36aeb35629eaa758159f567ea9539c2f1623905f36d89"
},
"downloads": -1,
"filename": "milksnake-0.1.1.zip",
"has_sig": false,
"md5_digest": "65c8d66c7175f7469737f1dc1fc7de8a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 8118,
"upload_time": "2017-10-04T00:02:01",
"url": "https://files.pythonhosted.org/packages/04/12/358c2c7a27f06a71d69e44a4b7f62411524c25e6c7284b5a0f757a9ba068/milksnake-0.1.1.zip"
}
],
"0.1.2": [
{
"comment_text": "",
"digests": {
"md5": "273b4b6ff918ca83b199d7e2fad9b8c4",
"sha256": "3971ae42b3f6b79929c71035bf657ebb194eb7119e522d8d89b4f047b6598eb6"
},
"downloads": -1,
"filename": "milksnake-0.1.2-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "273b4b6ff918ca83b199d7e2fad9b8c4",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 6415,
"upload_time": "2018-02-19T12:58:46",
"url": "https://files.pythonhosted.org/packages/de/cd/78896a5f11ed77313172999e9bdbb7a1ed5a2f3cec49f142412ccfb23ce9/milksnake-0.1.2-py2.py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "cf6b9171663e9365ffd439b1f58e4c99",
"sha256": "200769d4a8fbc3d6beb1b98a976e8371ad6e13cd94b0705aa0fdacec98509d1a"
},
"downloads": -1,
"filename": "milksnake-0.1.2.zip",
"has_sig": false,
"md5_digest": "cf6b9171663e9365ffd439b1f58e4c99",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 8345,
"upload_time": "2018-02-19T12:58:48",
"url": "https://files.pythonhosted.org/packages/f7/16/e2d48221414577007ac0fa7a742d72336a9ba2238f73a80b70d17b208c6b/milksnake-0.1.2.zip"
}
],
"0.1.3": [
{
"comment_text": "",
"digests": {
"md5": "6e457cc60852358e75e2f835b5cd4525",
"sha256": "2b617a9f3962cf346a3e6d2f3949b11bc3a73a07089c4130b636f00d68e0c187"
},
"downloads": -1,
"filename": "milksnake-0.1.3-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "6e457cc60852358e75e2f835b5cd4525",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 9604,
"upload_time": "2018-03-22T20:30:59",
"url": "https://files.pythonhosted.org/packages/a7/d8/22f41cba06cac0067f8f938f2dad697ff2af82eba1dab7ba403a1d6bc812/milksnake-0.1.3-py2.py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "3dc8681a2f2c1b3cc3649861fd3beca3",
"sha256": "0aa13328f4228b72381081c7e02db8637a71137f65a4dd0ced59c2d14f43c02e"
},
"downloads": -1,
"filename": "milksnake-0.1.3.zip",
"has_sig": false,
"md5_digest": "3dc8681a2f2c1b3cc3649861fd3beca3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 11875,
"upload_time": "2018-03-22T20:31:01",
"url": "https://files.pythonhosted.org/packages/1b/a4/e2b711600f69698b258a2e1365cc27dd0ffa2e9df259422aaddb90ad2e52/milksnake-0.1.3.zip"
}
],
"0.1.4": [
{
"comment_text": "",
"digests": {
"md5": "10c4bc250189867433a710f6d7af6492",
"sha256": "6059c44e65958d7db57b26875f291aca514901f43c04cba2aa9295823f79eb0b"
},
"downloads": -1,
"filename": "milksnake-0.1.4-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "10c4bc250189867433a710f6d7af6492",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 9658,
"upload_time": "2018-03-23T00:37:35",
"url": "https://files.pythonhosted.org/packages/d9/90/b56c4b3c2e81cfe9d2fa4ab619d64b866255762abfd2cd3b56b499da266a/milksnake-0.1.4-py2.py3-none-any.whl"
}
],
"0.1.5": [
{
"comment_text": "",
"digests": {
"md5": "62fb2218ce14bd8498b71c5ba06ace7d",
"sha256": "550ca1fc4222724149ee5a933e6bb8347630c0ed023a2a97701ab94fa256f6b4"
},
"downloads": -1,
"filename": "milksnake-0.1.5-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "62fb2218ce14bd8498b71c5ba06ace7d",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 9606,
"upload_time": "2018-03-23T00:41:46",
"url": "https://files.pythonhosted.org/packages/27/be/e10e73f857ac98ef43587fa8db37a3ef6de56e728037a7b9728de26711c7/milksnake-0.1.5-py2.py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "49efe6c7022046a597de6f1496387d16",
"sha256": "dfcd43b78bcf93897a75eea1dadf71c848319f19451cff4f3f3a628a5abe1688"
},
"downloads": -1,
"filename": "milksnake-0.1.5.zip",
"has_sig": false,
"md5_digest": "49efe6c7022046a597de6f1496387d16",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 11888,
"upload_time": "2018-03-23T00:41:47",
"url": "https://files.pythonhosted.org/packages/f9/6d/b55d227c75643445fb5bcd496ab21e543550330ba58a3d791efe973d39c1/milksnake-0.1.5.zip"
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "62fb2218ce14bd8498b71c5ba06ace7d",
"sha256": "550ca1fc4222724149ee5a933e6bb8347630c0ed023a2a97701ab94fa256f6b4"
},
"downloads": -1,
"filename": "milksnake-0.1.5-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "62fb2218ce14bd8498b71c5ba06ace7d",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 9606,
"upload_time": "2018-03-23T00:41:46",
"url": "https://files.pythonhosted.org/packages/27/be/e10e73f857ac98ef43587fa8db37a3ef6de56e728037a7b9728de26711c7/milksnake-0.1.5-py2.py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "49efe6c7022046a597de6f1496387d16",
"sha256": "dfcd43b78bcf93897a75eea1dadf71c848319f19451cff4f3f3a628a5abe1688"
},
"downloads": -1,
"filename": "milksnake-0.1.5.zip",
"has_sig": false,
"md5_digest": "49efe6c7022046a597de6f1496387d16",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 11888,
"upload_time": "2018-03-23T00:41:47",
"url": "https://files.pythonhosted.org/packages/f9/6d/b55d227c75643445fb5bcd496ab21e543550330ba58a3d791efe973d39c1/milksnake-0.1.5.zip"
}
]
}