I'm trying to make a python c++ extension using setuptools and I'm using glfw in my c++ project.
Here is what my setup.py looks like:
from setuptools import setup, Extension, find_packages
module1 = Extension('nerveblox',
sources = ['main.cpp', 'src/nerveblox_VM.cpp'],
include_dirs=["include", "lib/glfw/include"],
#extra_link_args=[ "-lm", "-lGL", "-lGLU", "-lglfw"],
library_dirs=["lib/glfw"],
libraries=['glfw']
)
setup (
name = 'Nerveblox_python_test',
version = '1.0',
description = 'This is a demo package',
ext_modules = [module1],
install_requires=[
'importlib-metadata; python_version == "3.8"',
],
)
My code works fine as pure c++ using cmake. When I run the above script I get this error:
/usr/bin/ld: cannot find -lglfw: No such file or directory
I've just downlaoded glfw source, extracted it to lib/glfw on my setup.py's directory, then ran cmake . and make inside lib/glfw. It's .so and .a files are inside lib/glfw/src.
Related
I am trying to create a package (on a Mac) which can be installed with pip. This package contains one main executable in the repository named mycode.py which I can run locally as follows:
python mycode.py --help
for example.
Given some documentation on how to create an entry point for an executable I added the following to the setup function in setup.py:
setup(
name="mycode",
author="bbp-ou-nse",
author_email="me#email.ch",
version="0.0.1",
description="Some tool",
long_description="later",
long_description_content_type="text/x-rst",
url="later",
entry_points='''
[console_scripts]
mycode=mycode.py:main
''',
install_requires=[],
packages=find_packages(),
python_requires=">=3.6",
)
and installed it with
pip install .
The installation seem to have worked, but when I now run the following command on the command line
mycode.py --hekp
I get the help of ImageMagick! No joke! The output starts with
Version: ImageMagick 7.0.10-34 Q16 x86_64 2020-10-09 https://imagemagick.org
Copyright: © 1999-2020 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP(3.1)
Delegates (built-in): bzlib freetype gslib heic jng jp2 jpeg lcms lqr ltdl lzma openexr png ps tiff webp xml zlib
Usage: import [options ...] [ file ]
Image Settings:
-adjoin join images into a single multi-image file
-border include window border in the output image
-channel type apply option to select image channels
What am I doing wrong? How to fix it so that I can ideally run
mycode --help
on the command line, and it executed the code mycode.py?
I would do something like this for setup.py file
Then setup.cfg is created with following contents.
[metadata]
name = mycode
version = attr: mycode.__version__
description = mycode desc
long_description = file: README.md
long_description_content_type = text/markdown
author = mycode
[flake8]
exclude = .git,.venv,.env,venv,env,__pycache__,docs/source/conf.py,build,dist
[options.entry_points]
console_scripts =
mycode=mycode.main:main
mycode folder will have a main.py with main function being called at entry this way!
The proper syntax would look like
setup(
# ...
entry_points={'console_scripts': ['mycode=mycode.py:main']}
# ...
)
I figured it out, it seems to be extremely complicated and not documented!
Here is what I have inserted in the setup function in setup.py:
entry_points={
'console_scripts': ['mycode=mycode:foo']},
py_modules=['mycode'],
You not only have to define the entry point with entry_points (see HERE), but you also have to define that py_modules argument (undocumented) pointing to your executable (?).
I am trying to generate aa .exe using py2exe for a python script that generates an excel. Here is just a sample code. I am writing value 100 to a cell and saving the excel to Users Desktop using openpyxl. This works perfectly fine when I run it directly.
import openpyxl
import getpass
wb = openpyxl.Workbook()
ws = wb.create_sheet('test')
ws.cell(row=1, column=1, value=100)
username = getpass.getuser()
wb.save('C:\\Users\\{}\\create_exe\\gen.xlsx'.format(username))
print 'Done'
And when I compile it using py2exe it compiles also just fine.
The problem arises when I run the generated .exe file. I get a return saying
ImportError: No module named jdcal
setup.py file is as follows
import py2exe
from distutils.core import setup
packages = ["openpyxl", "openpyxl.workbook", "xml.etree", "xml"]
excludes = []
setup(console=['test_program.py'],
options={"py2exe": {"excludes": excludes,
"packages": packages}}
)
Thisngs I have already tried
I have searched and few people said Install openpyxl using pip. I
have done that and pip says its alöready installed.
I have also tried to install jdcal using pip and pip says it is installed.
I have uninstalled jdcal and installed it using pip and manually, and
still the same error.
I have included jdcal in the packages and still no change in the outcome.
I hope someone can help me with it.
Thanks in advance
EDIT :
Generated Filed in dist folder are as follows (openpyxl cannot be seen here, I don't know why)
tcl (Folder)
_ctypes.pyd
_elementtree.pyd
_hashlib.pyd
_multiprocessing.pyd
_socket.pyd
_ssl.pyd
_tkinter.pyd
bz2.pyd
pyexpat.pyd
select.pyd
unicodedata.pyd
win32ui.pyd
numpy.core._dummy.pyd
numpy.core.multiarray.pyd
numpy.core.multiarray_tests.pyd
numpy.core.operand_flag_tests.pyd
numpy.core.struct_ufunc_test.pyd
numpy.core.test_rational.pyd
numpy.core.umath.pyd
numpy.core.umath_tests.pyd
numpy.fft.fftpack_lite.pyd
numpy.linalg._umath_linalg.pyd
numpy.linalg.lapack_lite.pyd
numpy.random.mtrand.pyd
_win32sysloader.pyd
win32api.pyd
win32pdh.pyd
win32pipe.pyd
tk85.dll
tcl85.dll
libiomp5md.dll
pywintypes27.dll
python27.dll
w9xpopen.exe
pythoncom27.dll
library.zip
test_program.exe (Executable File)
Try to manually include it in setup.py in packages = ["openpyxl", "openpyxl.workbook", "xml.etree", "xml"]
so it would be:
packages = ["openpyxl", "openpyxl.workbook", "xml.etree", "xml", "jdcal"]
I personally have had good luck letting py2exe detect the modules that are needed. I've never tried to specify every module necessary.
try this:
from distutils.core import setup
import py2exe
setup(console=['test_program.py'])
this should be run from command line as
python setup.py py2exe
py2exe outputs .dll files in the dist directory, these have to be in the directory that you run your .exe file from. if you just want one .exe file and no .dll files try this:
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
setup(
options = {'py2exe': {'bundle_files': 1, 'compressed': True}},
console = [{'script': "test_program.py"}],
zipfile = None,
)
this should be run from command line as
python setup.py
I use cx_freeze and never had any issues.
Here's the setup.py for a cx_freeze file
from cx_Freeze import setup, Executable
build_exe_options = {"excludes": ["html5lib"],"optimize":2}
setup(name = "App Name" ,
version = "1.0.0.0" ,
options = {"build_exe": build_exe_options},
description = "" ,
executables = [Executable("FooBar.py")])
I am using PyCharm to generate a setup.py file for my project. The following file is generated:
from setuptools import setup
setup(
name='untitled',
version='',
packages=['venv.lib.python3.6.site-packages.PyQt5', 'venv.lib.python3.6.site-packages.PyQt5.uic',
'venv.lib.python3.6.site-packages.PyQt5.uic.Loader', 'venv.lib.python3.6.site-packages.PyQt5.uic.port_v2',
'venv.lib.python3.6.site-packages.PyQt5.uic.port_v3',
'venv.lib.python3.6.site-packages.PyQt5.uic.Compiler', 'venv.lib.python3.6.site-packages.py2app',
'venv.lib.python3.6.site-packages.py2app.recipes', 'venv.lib.python3.6.site-packages.py2app.recipes.PIL',
'venv.lib.python3.6.site-packages.py2app.bootstrap', 'venv.lib.python3.6.site-packages.py2app.converters',
'venv.lib.python3.6.site-packages.py2app.apptemplate',
'venv.lib.python3.6.site-packages.py2app.bundletemplate', 'venv.lib.python3.6.site-packages.altgraph',
'venv.lib.python3.6.site-packages.macholib', 'venv.lib.python3.6.site-packages.modulegraph',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip.req',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip.vcs',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip.utils',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip.compat',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip.models',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.distlib',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.distlib._backport',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.colorama',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.html5lib',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.html5lib._trie',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.html5lib.filters',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.html5lib.treewalkers',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.html5lib.treeadapters',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.html5lib.treebuilders',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.lockfile',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.progress',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.requests',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.requests.packages',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.requests.packages.chardet',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.requests.packages.urllib3',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.requests.packages.urllib3.util',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.requests.packages.urllib3.contrib',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.requests.packages.urllib3.packages',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.requests.packages.urllib3.packages.ssl_match_hostname',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.packaging',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.cachecontrol',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.cachecontrol.caches',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.webencodings',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip._vendor.pkg_resources',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip.commands',
'venv.lib.python3.6.site-packages.pip-9.0.1-py3.6.egg.pip.operations'],
url='',
license='',
author='',
author_email='',
description=''
)
The period in python3.6 is causing problems because when I run python setup.py develop I get the following error:
error: package directory 'venv/lib/python3/6/site-packages/PyQt5' does not exist
I'm not sure how to go about fixing this? If I simply change the python3.6 to python36 it just further breaks everything. How do I fix this?
Project view:
Project structure:
I am creating a python package with a c++ extension. I am trying to do this with setuptools as that seems to be the preferred solution. Given that it allows for setup_requires, install_requires, I agree and use it for my python only packages. However, I am unable to get it to work when I have a c++ extension module. Then I resort to distutils.core to get it to work. I would like to know how to get it to work using setuptools. My setup script looks like
from setuptools import setup
import shutil
import os
# folder where .so is being build by cpp compilation
so_src = os.path.join(dir, 'cpp/build/')
# folder where .so should live in python package
so_des = os.path.join(dir, 'package_py/cpp/')
# extension module
lib_files = ['cpp_py.so']
# copy shared lib
for f in lib_files:
shutil.copyfile(so_src + f, so_des + f)
# set-up script
setup(
name=DISTNAME
, version=FULLVERSION
, description= DESCRIPTION
, author= AUTHOR
, author_email= EMAIL
, maintainer= AUTHOR
, maintainer_email= EMAIL
, long_description=LONG_DESCRIPTION
, packages=['package_py',
'package_py.cpp']
, package_dir={'package_py.cpp': 'package_py/cpp'}
, package_data={'package_py.cpp': lib_files}
)
This results in a package_py-0.0.1-py3.6.egg file in my python site-packages. The package only works when used from the installation folder.
Changing the first line to use distutils.core instead of setuptools
from distutils.core import setup # only change, remainder is the same!!
import shutil
import os
# folder where .so is being build by cpp compilation
so_src = os.path.join(dir, 'cpp/build/')
# folder where .so should live in python package
so_des = os.path.join(dir, 'package_py/cpp/')
# extension module
lib_files = ['cpp_py.so']
# copy shared lib
for f in lib_files:
shutil.copyfile(so_src + f, so_des + f)
# set-up script
setup(
name=DISTNAME
, version=FULLVERSION
, description= DESCRIPTION
, author= AUTHOR
, author_email= EMAIL
, maintainer= AUTHOR
, maintainer_email= EMAIL
, long_description=LONG_DESCRIPTION
, packages=['package_py',
'package_py.cpp']
, package_dir={'package_py.cpp': 'package_py/cpp'}
, package_data={'package_py.cpp': lib_files}
)
I get a package_py folder (with .so file) and package_py-0.0.1-py3.6.egg-info in site-packages. Now the module works in all folders.
As I would like to extend the python package to also use setup_requires, instal_requires I want to really use setuptools. How can I get the package to work in all folders using setuptools instead of distutils.core
If you're using a C extension, you should use Extension from either setuptools or distutils as well, it's not a python package, so I'm surprised it's even managing to install. If you plan on distributing the package to others, you shouldn't compile the extension beforehand, but have it compiled during the package installation so that the user's system compiles it appropriately (i.e., an .so file doesn't help a Windows user who needs it compiled into a .dll file, etc).
Try something like this:
from setuptools import setup, Extension
import shutil
import os
# I don't know how you want to build your extension or your file structure,
# so removing the build stuff.
your_modulename=Extension('_extensionname',
sources=['path/to/extension.cpp', 'more/file/paths'],
language='c'
)
# set-up script
setup(
name=DISTNAME
, version=FULLVERSION
, description= DESCRIPTION
, author= AUTHOR
, author_email= EMAIL
, maintainer= AUTHOR
, maintainer_email= EMAIL
, long_description=LONG_DESCRIPTION
, ext_modules=[your_modulename]
, packages=['package_py']
)
Hope this helps or at least gets you on the right track.
This is what i have done, but i failed in Step3, I try my best and can't find how to solve it.
step1: install python-2.7.12.amd64 , Cython-0.24-cp27-cp27m-win_amd64 and vs2015.3.com_enu.(there are some problems,but be soveled.)
step2: do as:http://docs.cython.org/src/quickstart/build.html
.c and .pyd files are generated.
step3: but when i import the model, failed with
"traceback... file'',line 1, in import...
ImportError: DLL load failed: %1 is not a valid Win32 application"
what i should do for this problem? anyone some advances? thanks very much.
As #J.J.Hakala mentioned be sure to use the compiler he linked to or it won't work with your Python version. Also make sure you have all your includes listed in setup.py, i.e.
from Cython.Distutils import build_ext
from setuptools import setup
from setuptools import Extension
module = 'MyModule'
ext_modules = [Extension(module, sources=[module + ".pyx"],
include_dirs=['path1','path2'], # put include paths here
library_dirs=[], # usually need your Windows SDK stuff here
language='c++')]
setup(
name = module,
ext_modules = ext_modules,
cmdclass = {'build_ext': build_ext},
include_dirs = ['path1', 'path2']
)
And while building be sure to specify: python setup.py build_ext --compiler=msvc in case you have multiple compilers on your system. While you're at it they note that you need setuptools version >=6.0 so ensure you are up to date there.