separate static and dynamic libraries completely

This commit is contained in:
electronstudio 2021-10-03 21:21:59 +01:00
parent d9ae6515a5
commit 81819a133a
39 changed files with 1601 additions and 86 deletions

View file

@ -187,3 +187,34 @@ jobs:
with:
name: wheel
path: dist/*
dynamic-distro:
runs-on: ubuntu-18.04
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Setup Python
uses: actions/setup-python@v2.2.2
with:
# Version range or exact version of a Python version to use, using SemVer's version range syntax.
python-version: '3.9'
# The target architecture (x86, x64) of the Python interpreter.
architecture: x64
- name: Build raylib-python-cffi-dynamic
run: |
python -m pip install --upgrade pip
pip3 install cffi
pip3 install wheel
cd dynamic
python setup.py sdist
- name: Upload build Artifact wheel
uses: actions/upload-artifact@v2.2.4
with:
name: wheel
path: dynamic/dist/*

View file

@ -1,11 +1,8 @@
include raylib/static/*.so
include raylib/static/*.pyi
include raylib/static/*.pyd
exclude raylib/static/*.a
include raylib/*.so
include raylib/*.pyi
include raylib/*.pyd
exclude raylib/*.a
include raylib/*.h
include raylib/*.pyi
exclude raylib/static/*.c
exclude raylib/static/*.o
include raylib/dynamic/*.dylib
include raylib/dynamic/*.dll
include raylib/dynamic/*.so
exclude raylib/*.c
exclude raylib/*.o

View file

@ -12,7 +12,7 @@
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
from raylib.static import rl, ffi
from raylib import rl, ffi
from inspect import ismethod, getmembers, isbuiltin
import inflection, sys, json

View file

@ -12,7 +12,7 @@
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
from raylib.static import rl, ffi
from raylib import rl, ffi
from inspect import ismethod, getmembers, isbuiltin
import inflection, sys, json

View file

@ -1,28 +1,42 @@
raylib.dynamic
==============
CFFI ABI dynamic bindings exist in order to avoid the need to compile a C extension module.
See https://github.com/electronstudio/raylib-python-cffi/blob/master/test_static.py for how to use.
Currently the github version may include bundled DLLs in ``raylib/dynamic`` but the pypi version requires a system installed Raylib.
You can put your own DLLs in ``raylib/dynamic`` if you prefer.
If your system already has the Raylib library installed, you can set the environment variable ``USE_EXTERNAL_RAYLIB`` and it will
always be used instead of the bundled DLLs.
If you want to build your own wheel with just raylib.dynamic and not even attempt to compile the static libraries,
the command is::
python3 setup_dynamic.py bdist_wheel
CFFI ABI dynamic bindings avoid the need to compile a C extension module. They now been moved to a separate module::
python3 -m pip install raylib_dll
.. warning::
There have been some weird failures with dynamic bindings and ctypes bindings before and often the
failures are silent
so you dont even know. Also the static bindings should be faster. Therefore I personally recommend the static ones.
But the dynamic bindings have the big advantage that you don't need to compile anything to install. You just need a Raylib DLL.
so you dont even know. Also the static bindings are faster. Therefore I personally recommend the static ones.
But the dynamic bindings have the advantage that you don't need to compile anything to install. You just need a Raylib DLL.
API is the same as raylib.static.
API is exactly the same as the static one documented here. (Therefore you can't have both modules installed at once.) The only difference is you can't do::
from raylib import *
Instead you have to do::
from raylib import raylib as rl
Then you access the functions with ``rl.`` prefix. See
See https://github.com/electronstudio/raylib-python-cffi/blob/master/dynamic/test_dynamic.py for an example.
.. important::
If your system already has the Raylib library installed, you can set the environment variable ``USE_EXTERNAL_RAYLIB`` and it will
always be used instead of the bundled DLLs.
.. note::
If you write a program using the ``rl.`` prefix on all the functions and then you decide you want to use
that same program with the static binding instead of the dynamic, you don't have to remove the ``rl``,
you can just do::
import raylib as rl

13
dynamic/MANIFEST.in Normal file
View file

@ -0,0 +1,13 @@
include raylib/*.pyi
include raylib/*.pyd
exclude raylib/*.a
include raylib/*.h
include raylib/*.pyi
exclude raylib/*.c
exclude raylib/*.o
include raylib/*.dylib
include raylib/*.dll
include raylib/*.so
include raylib/32bit/*.dylib
include raylib/32bit/*.dll
include raylib/32bit/*.so

1
dynamic/README.md Normal file
View file

@ -0,0 +1 @@
Dynamically linked version of Raylib Python CFFI

View file

@ -23,7 +23,7 @@ import os
import pathlib
import platform
MODULE = pathlib.Path(__file__).parent.parent
MODULE = pathlib.Path(__file__).parent
def raylib_library_path():
'''Return the full path of the raylib shared library
@ -31,7 +31,7 @@ def raylib_library_path():
then the library will be loaded from the system library paths.
'''
def so_path():
return str(MODULE / 'dynamic') if not 'USE_EXTERNAL_RAYLIB' in os.environ else ''
return str(MODULE) if not 'USE_EXTERNAL_RAYLIB' in os.environ else ''
def so_name():
'''Returns the appropriate for the library on the current platform.'''
lib_filenames = {

40
dynamic/raylib/colors.py Normal file
View file

@ -0,0 +1,40 @@
# Copyright (c) 2021 Richard Smith and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# This Source Code may also be made available under the following Secondary
# licenses when the conditions for such availability set forth in the Eclipse
# Public License, v. 2.0 are satisfied: GNU General Public License, version 2
# with the GNU Classpath Exception which is
# available at https://www.gnu.org/software/classpath/license.html.
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
LIGHTGRAY =( 200, 200, 200, 255 )
GRAY =( 130, 130, 130, 255 )
DARKGRAY =( 80, 80, 80, 255 )
YELLOW =( 253, 249, 0, 255 )
GOLD =( 255, 203, 0, 255 )
ORANGE =( 255, 161, 0, 255 )
PINK =( 255, 109, 194, 255 )
RED =( 230, 41, 55, 255 )
MAROON =( 190, 33, 55, 255 )
GREEN =( 0, 228, 48, 255 )
LIME =( 0, 158, 47, 255 )
DARKGREEN =( 0, 117, 44, 255 )
SKYBLUE =( 102, 191, 255, 255 )
BLUE =( 0, 121, 241, 255 )
DARKBLUE =( 0, 82, 172, 255 )
PURPLE =( 200, 122, 255, 255 )
VIOLET =( 135, 60, 190, 255 )
DARKPURPLE =( 112, 31, 126, 255 )
BEIGE =( 211, 176, 131, 255 )
BROWN =( 127, 106, 79, 255 )
DARKBROWN =( 76, 63, 47, 255 )
WHITE =( 255, 255, 255, 255 )
BLACK =( 0, 0, 0, 255 )
BLANK =( 0, 0, 0, 0 )
MAGENTA =( 255, 0, 255, 255 )
RAYWHITE =( 245, 245, 245, 255 )

File diff suppressed because it is too large Load diff

View file

@ -12,23 +12,26 @@ README = (HERE / "README.md").read_text()
# This call to setup() does all the work
setup(
name="raylib-dynamic",
version="3.7.0.post1",
description="Python CFFI bindings for Raylib",
version="3.7.0.post6",
description="Python CFFI bindings for Raylib DLL version",
long_description=README,
long_description_content_type="text/markdown",
url="https://github.com/electronstudio/raylib-python-cffi",
author="Electron Studio",
author_email="github@electronstudio.co.uk",
license="LGPLv3+",
license="EPL-2.0",
classifiers=[
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
"License :: OSI Approved :: Eclipse Public License 2.0 (EPL-2.0)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
],
packages=["raylib", "raylib.dynamic"],
packages=["raylib"],
include_package_data=True,
install_requires=["cffi>=1.14.5","inflection"],
)

View file

@ -2,7 +2,7 @@
This shows how to use the CFFI dynamic (ABI) binding. Note that is slower and more likely to run into silent errors and segfaults.
But it doesnt require any C compiler to build.
"""
from raylib.dynamic import ffi, raylib as rl
from raylib import ffi, raylib as rl
from raylib.colors import *
rl.InitWindow(800, 450, b"Raylib dynamic binding test")

View file

@ -9,7 +9,7 @@
# *
# ********************************************************************************************/
from raylib.static import *
from raylib import *
# Initialization

View file

@ -9,7 +9,7 @@
# *
# ********************************************************************************************/
from raylib.static import *
from raylib import *
# Initialization
# --------------------------------------------------------------------------------------

View file

@ -9,7 +9,7 @@
# *
# ********************************************************************************************/
from raylib.static import *
from raylib import *
# Initialization

View file

@ -9,7 +9,7 @@
# *
# ********************************************************************************************/
from raylib.static import *
from raylib import *
# Initialization

View file

@ -9,7 +9,7 @@
# *
# ********************************************************************************************/
from raylib.static import *
from raylib import *
# Initialization
#--------------------------------------------------------------------------------------

View file

@ -9,7 +9,7 @@
# *
# ********************************************************************************************/
from raylib.static import *
from raylib import *
# Initialization
#--------------------------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
# just a few functions from raymath
#from raylib.dynamic import raylib as rl, ffi
from raylib.static import rl, ffi
from raylib import rl, ffi
import math
#<<<<<<< HEAD

View file

@ -30,7 +30,7 @@
#<<<<<<< HEAD
#<<<<<<< HEAD
#<<<<<<< HEAD
from raylib.static import rl, ffi
from raylib import rl, ffi
#=======
#from raylib.dynamic import raylib as rl, ffi
#>>>>>>> ffe4403 (complete fog example)

View file

@ -12,7 +12,7 @@ http://bedroomcoders.co.uk/raylib-fog/
#<<<<<<< HEAD
#<<<<<<< HEAD
#<<<<<<< HEAD
from raylib.static import rl, ffi
from raylib import rl, ffi
#=======
#from raylib.dynamic import raylib as rl, ffi
#>>>>>>> ffe4403 (complete fog example)

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python3
from raylib.static import rl, ffi
from raylib import rl, ffi
from raylib.colors import *
import math

View file

@ -9,7 +9,7 @@
# *
# ********************************************************************************************/
from raylib.static import *
from raylib import *
MAX_BUNNIES = 500000
# This is the maximum amount of elements (quads) per batch

View file

@ -1,6 +1,6 @@
# Dont use C data structures when we can avoid it. Makes Pypy slightly faster.
from raylib.static import *
from raylib import *
import random
MAX_BUNNIES = 500000

View file

@ -2,6 +2,6 @@
pip3 install sphinx-autoapi myst_parser sphinx_rtd_theme
python3 create_stub_pyray.py > raylib/pyray.pyi
python3 create_stub_static.py >raylib/static/__init__.pyi
python3 create_stub_static.py >raylib/__init__.pyi
cd docs-src
make clean ; make html ; cp -a _build/html/. ../docs/

View file

@ -1,5 +1,3 @@
__version__ = "3.7.0.post6"
# Copyright (c) 2021 Richard Smith and others
#
# This program and the accompanying materials are made available under the
@ -14,5 +12,11 @@ __version__ = "3.7.0.post6"
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
from raylib.static import *
from raylib.pyray import PyRay
from ._raylib_cffi import ffi, lib as rl
from raylib._raylib_cffi.lib import *
from raylib.colors import *
import cffi
import sys
from raylib.pyray import PyRay
print("RAYLIB STATIC LOADED", file=sys.stderr)

View file

@ -25,9 +25,9 @@ ffibuilder = FFI()
def build_linux():
print("BUILDING FOR LINUX")
ffibuilder.cdef(open("raylib/raylib_modified.h").read().replace('RLAPI ', ''))
ffibuilder.set_source("raylib.static._raylib_cffi",
ffibuilder.set_source("raylib._raylib_cffi",
"""
#include "../../raylib/raylib.h"
#include "../raylib/raylib.h"
""",
extra_link_args=['/usr/local/lib/libraylib.a','-lm', '-lpthread', '-lGLU', '-lGL', '-lrt', '-lm', '-ldl', '-lX11', '-lpthread'],
libraries=['GL','m','pthread', 'dl', 'rt', 'X11']
@ -38,9 +38,9 @@ def build_linux():
def build_windows():
print("BUILDING FOR WINDOWS")
ffibuilder.cdef(open("raylib/raylib_modified.h").read().replace('RLAPI ', '').replace('bool','int'))
ffibuilder.set_source("raylib.static._raylib_cffi",
ffibuilder.set_source("raylib._raylib_cffi",
"""
#include "../../../raylib/raylib.h"
#include "../../raylib/raylib.h"
""",
extra_link_args=['/NODEFAULTLIB:MSVCRTD'],
libraries=['raylib', 'gdi32', 'shell32', 'user32','OpenGL32', 'winmm'],
@ -51,9 +51,9 @@ def build_windows():
def build_mac():
print("BUILDING FOR MAC")
ffibuilder.cdef(open("raylib/raylib_modified.h").read().replace('RLAPI ', ''))
ffibuilder.set_source("raylib.static._raylib_cffi",
ffibuilder.set_source("raylib._raylib_cffi",
"""
#include "../../raylib/raylib.h" // the C header of the library, supplied by us here
#include "../raylib/raylib.h" // the C header of the library, supplied by us here
""",
extra_link_args=['-lraylib', '-framework', 'OpenGL', '-framework', 'Cocoa', '-framework', 'IOKit', '-framework', 'CoreFoundation', '-framework', 'CoreVideo'],
)
@ -65,9 +65,9 @@ def build_mac():
def build_rpi_nox():
print("BUILDING FOR RASPBERRY PI")
ffibuilder.cdef(open("raylib/raylib_modified.h").read().replace('RLAPI ', ''))
ffibuilder.set_source("raylib.static._raylib_cffi",
ffibuilder.set_source("raylib._raylib_cffi",
"""
#include "../../raylib/raylib.h"
#include "../raylib/raylib.h"
""",
extra_link_args=['/usr/local/lib/libraylib.a',
'/opt/vc/lib/libEGL_static.a', '/opt/vc/lib/libGLESv2_static.a',

View file

@ -12,7 +12,7 @@
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
from .static import rl, ffi
from raylib import rl, ffi
from .colors import *
from inspect import ismethod,getmembers,isbuiltin
import inflection

View file

@ -1,21 +0,0 @@
# Copyright (c) 2021 Richard Smith and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# This Source Code may also be made available under the following Secondary
# licenses when the conditions for such availability set forth in the Eclipse
# Public License, v. 2.0 are satisfied: GNU General Public License, version 2
# with the GNU Classpath Exception which is
# available at https://www.gnu.org/software/classpath/license.html.
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
from ._raylib_cffi import ffi, lib as rl
from raylib.static._raylib_cffi.lib import *
from raylib.colors import *
import cffi
import sys
print("RAYLIB STATIC LOADED", file=sys.stderr)

View file

@ -33,9 +33,9 @@ setup(
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
],
packages=["raylib", "raylib.dynamic", "raylib.static"],
packages=["raylib"],
include_package_data=True,
install_requires=["cffi>=1.14.5","inflection"],
distclass=BinaryDistribution,
cffi_modules=["raylib/static/build.py:ffibuilder"]
cffi_modules=["raylib/build.py:ffibuilder"]
)

View file

@ -0,0 +1,34 @@
"""
This shows how to use the CFFI static (API) binding. It should be fast and code be as close as possible to original
C code.
"""
import raylib as rl
from raylib import ffi
from raylib.colors import *
rl.InitWindow(800, 450, b"Raylib dynamic binding test")
rl.SetTargetFPS(60)
camera = ffi.new("struct Camera3D *", [[18.0, 16.0, 18.0], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0], 45.0, 0])
image = rl.LoadImage(b"examples/models/resources/heightmap.png")
texture = rl.LoadTextureFromImage(image)
mesh = rl.GenMeshHeightmap(image, [16, 8, 16])
model = rl.LoadModelFromMesh(mesh)
print(model.materials) # SHOULD BE A pointer to a 'struct Material' but some is NULL pointer to 'Material' ?
model.materials.maps[rl.MATERIAL_MAP_DIFFUSE].texture = texture
rl.UnloadImage(image)
rl.SetCameraMode(camera[0], rl.CAMERA_ORBITAL)
while not rl.WindowShouldClose():
rl.UpdateCamera(camera)
rl.BeginDrawing()
rl.ClearBackground(RAYWHITE)
rl.BeginMode3D(camera[0])
rl.DrawModel(model, (-8.0, 0.0, -8.0), 1.0, RED)
rl.DrawGrid(20, 1.0)
rl.EndMode3D()
rl.DrawText(b"This mesh should be textured", 190, 200, 20, VIOLET)
rl.EndDrawing()
rl.CloseWindow()