Python setuptools help on windows. Dll dependencies not identified - dll

I wrote a pybind11 wrapper over a shared c++ library (.dll) on Windows.
I wanted to make a distributable package using setuptools.
I wrote a setup.py file and it generated the pyd file for the wrapper.
But when I try to run a script which imports the wrapper package python crashes.
It only succeeds only if I place all the dll dependencies in the script folder.

I found a temporary solution to the above problem.
I created an init.py file which adds the DLL directory in the beginning of the environment path variable.

Related

How do I tell ReadTheDocs to build my project packages from a sub-directory?

I have a repository that contains three python packages: a main package, and two addon packages, with shared documentation. Each project is in its own directory, with its own setup.py, as so:
Repository
Main Project
setup.py
Addon One
setup.py
Addon Two
setup.py
Documentation
RST files, RTD conf, etc.
Previously, I was using setuptools.find_packages() to build my packages, but was having issues with the contents of the packages bleeding together, as they shared namespaces. So I switched to specifying the packages I wanted to build, such as
packages=["Main Package"]
However, this broke my ReadTheDocs auto-build, where I had specified
- method: setuptools
path: Main Project
in .readthedocs.yml, with RTD now complaining my package (inside the Main Project directory) doesn't exist, as it attempts to build it.
In my project, I use a script to build the packages, where I move into each directory, run its setup, then move out. Works fine, my packages and documentation all build locally. However, it looks like RTD is only using the defined path to prepend my setup.py script, and therefore not finding the source package as the working directory is the parent directory (but I could be wrong!).
I've read through the documentation, including https://github.com/readthedocs/readthedocs.org/issues/4354 where the feature was originally added, but I have not been able to find a solution myself yet.
How can I tell RTD to change directory before building the packages, or is there an alternative approach that will support my repo structure?
Repository in question is here.
I found a solution:
I changed my local build script to use the root project directory, as per-RTD. I then added the directive package_dir={"": "[directory]"} to the setuptools.setup() calls in each project's setup.py.

VS2019 project loads a dll at runtime istead of using the static library

I have setup my project with precompiled static libraries.
Yet when I run the project it'll try to load a dll:
'Project1.exe' (Win32) : Chargé 'D:\Projects\VisualStudio\Dll1\Debug\MinHook.x86.dll'.
I can't find any reference to this dll from the project's settings or inside the .sln and .vcxproj files, yet loading my dll without MinHook.x86.dll will fail. Any idea where that could come from?
Thank you for your help.
MinHook.x86.lib is 'import library' used by MSVC to load DLL. To link statically you should use libMinHook-x86-v141-mt.lib static library.

Changing the version information of ironpython .dll assembly

I compiled a .dll file in ironpython, by using the following code:
import clr
clr.CompileModules('C:/example.dll', 'C:/example.py')
It essentially compiles the .py file to .dll.
The only problem with this is that it creates a file with no information about the Company, Language, File Version etc. In fact the File Version is always: 0.0.0.0.
I was wondering if there is a way to at least alter the File Version (change it to something other than 0.0.0.0). I googled and found a similar topic in here on stackoverflow.
I tried three methods:
1) One with Visual Studio (File->Open-> find .dll, Edit->Add Resource->Version click New. In the new Version tab, change FILEVERSION and PRODUCTVERSION)
2) Another one by using the Change version 2012 application
3) And third one by using: Simple Version Resource Tool for Windows 1.0.10
None of them worked.
For some reason looks like the structure of the .dll assembly created with ironpython is different than the .NET one created with VB or C#.
Does anyone know how to change the File Version from 0.0.0.0 to something else?
Thank you.
You can use the pyc.py file packaged into IronPython to compile your file into a .dll file. The file is located in the directory IronPython 2.7\Tools\Scripts.
If we open pyc.py for editing, you'll see the different things it can do.
pyc: The Command-Line Python Compiler
Usage: ipy.exe pyc.py [options] file [file ...]
Options:
/out:output_file Output file name (default is main_file.<extenstion>)
/target:dll Compile only into dll. Default
/target:exe Generate console executable stub for startup in addition to dll.
/target:winexe Generate windows executable stub for startup in addition to dll.
#<file> Specifies a response file to be parsed for input files and command line options (one per line)
/file_version:<version> Set the file/assembly version
/? /h This message
EXE/WinEXE specific options:
/main:main_file.py Main file of the project (module to be executed first)
/platform:x86 Compile for x86 only
/platform:x64 Compile for x64 only
/embed Embeds the generated DLL as a resource into the executable which is loaded at runtime
/standalone Embeds the IronPython assemblies into the stub executable.
/mta Set MTAThreadAttribute on Main instead of STAThreadAttribute, only valid for /target:winexe
/file_info_product:<name> Set product name in executable meta information
/file_info_product_version:<version> Set product version in executable meta information
/file_info_company:<name> Set company name in executable meta information
/file_info_copyright:<info> Set copyright information in executable meta information
/file_info_trademark:<info> Set trademark information in executable meta information
Example:
ipy.exe pyc.py /main:Program.py Form.py /target:winexe
One thing that I personally like to do is move pyc.py from the Scripts folder to the IronPython folder along with my python file as well.
Assuming you also do this, you would open command prompt as administrator and navigate to the IronPython folder.
cd "Program Files (x86)\IronPython 2.7"
Then you would want to compile your python file as a .dll and set the file version using pyc.py. To do that, you're going to want to type in:
ipy.exe pyc.py /main:example.py /target:dll /file_version:0.0.0.1
If you want to add a company name, and other items as well, you simply have to pass those option to the pyc.py script.
ipy.exe pyc.py /main:Program.py Form.py /target:winexe /file_info_company:Company

Cannot get dependency to run in Intellij: UnsatisfiedLinkError

I have a Play framework application in Intellij to which I am trying to add Gurobi (an ILP optimizer) and have been running into some problems. I have followed all of the instructions for installing Gurobi from their website.
In Intellij, I have added Gurobi to a /lib folder in the project, and it resolves all the symbols in the code OK, the code compiles, and I can run the application. I added Gurobi to the java library path by adding this to the JVM arguments to the run configuration:
-Djava.library.path=/opt/gurobi605/linux64/lib
I have also added 4 environment variables to the run configuration:
GUROBI_HOME="/opt/gurobi605/linux64"
PATH="${PATH}:${GUROBI_HOME}/bin"
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib"
GUROBI_LICENCE="/home/mcmellawat/gurobi.lic"
I have also added these environment variables to the .bashrc file per Gurobi instructions, though I'm not sure it matters.
Despite all this, I am getting the following error when trying to instantiate the first Gurobi object (GRBEnv to be specific) in my code:
java.lang.UnsatisfiedLinkError: /opt/gurobi605/linux64/lib/libGurobiJni60.so: libgurobi60.so: cannot open shared object file: No such file or directory
I have verified that this file does indeed exist in /opt/gurobi605/linux64/lib (it is actually a link to another file). What could be causing it to not be found?
The Gurobi FAQ (41) contains instructions how to use the Java interface from a development environment (e.g. Eclipse):
http://www.gurobi.com/support/faqs
1) You need to include gurobi.jar in your project (e.g. in your Build Path)
2) Make sure that the environment variable PATH (Windows) or LD_LIBRARY_PATH (Linux) contains the correct library folder.
On Windows this is by default the bin folder of the Gurobi installation (e.g. gurobi60.dll and gurobi65.dll)
On Linux this is by default the lib folder of the Gurobi installation (e.g. libgurobi60.so and libGurobiJni60.so)

Packaging a Jython program in an executable jar

I am trying to package a jython program into an executable jar which the user can simply double-click to run without installing jython ahead of time. Ultimately, I would like to include an additional library which I wrote with the jar, but at the moment I am just trying to package a simple program and have it run from the jar.
I have tried following the jar instructions in the "Using the Jar Method" section here: Jython FAQ: Using the Jar Method
I have also looked at slides 25-28 here: Jython Update 2012 slides
And finally here:
stackoverflow Question: Distributing My Python Scripts as Jars with Jython
I have installed jython 2.5.3, jvm 1.6, and python 2.7.3 on my mac which is running OS X 10.8.3.
These are the steps I go through to create the jar and run it:
Create a copy of jython.jar from my jython installation directory.
zip -r jython_copy.jar Lib (where Lib is the folder in the jython installation directory)
cp myJythonProgram.py __run__.py (myJythonProgram.py does not include an 'if name == main' line)
zip jython_copy.jar __run__.py
export CLASSPATH=/path/to/my/app/jython_copy.jar:$CLASSPATH
I have tried running the jar using all three of these methods:
java org.python.util.jython -jar myapp.jar
java -cp myapp.jar org.python.util.jython -jar myapp.jar
java -jar myapp.jar -jar myapp.jar
This works if my program doesn't use any import statements.
However I am running into an issue where some python packages are not able to be found when I run the jar. For instance, I get the error "ImportError: No module named random" when I include the line from random import random in my program. No errors occur on lines in the program when I import from javax.swing, java.awt, time, or math.
Additionally, I tried to package a jar with my library and a jython program which imports my library using the previous steps as well as the following additional steps:
zip jython_copy.jar myLibrary.jar
jar ufm jython_copy.jar othermanifest.mf
othermanifest.mf only contains the line Class-Path: ./myLibrary.jar.
This too gives the error "ImportError: No module named myLibrary"
I would appreciate any insight into what I am doing incorrectly or other steps I should take.
Thanks!
I realized what the problem was and I wanted to document it in case anyone else has the same problems.
I was using the jython.jar file that came in the standard installation of Jython, and NOT the standalone jython.jar (the instructions at Using the Jar Method mentions this, but the instructions at Building Jars do not). I am still unsure why copying the Lib/ folder of the standard installation into the jython.jar that came with that installation didn't work on my system. However, once I used the standalone jar, things started to work more smoothly.
Additionally, I was able to get my library to work with the packaged file by doing three things in addition to the steps I laid out in my question:
Exploding the standalone jython.jar and copying the folder with all of my library files into Lib, then create a new jar. This seemed to be the easiest way to include my library and allows me to package everything into a single jar.
I discovered after reading Frank Wierzbicki's answer in Why does Jython refuse to find my Java package? that because I am now using the standalone jar, I could no longer use imports of the style from java.awt import *, instead I needed to fully specify each thing I was importing, for example from java.awt.Font import PLAIN, BOLD, ITALIC. So I went through the library's imports and fixed the few that were of the wrong style.
Now that I am adding my Library directly to the Jar's Lib folder, instead of writing Class-Path: ./myLibrary.jar in othermanifest.mf, I put Main-Class: org.python.util.JarRunner as per Frank Wierzbicki's answer in the post I mentioned in my question: Distributing my Python scripts as JAR files with Jython?
This allowed me to create a double-clickable executable jar containing my library and jython file that I wanted to run.
There are two solutions. They both work, but one better than the other.
I believe you can rename your python script as __run__.py, place that file inside the .jar file, and pass the .jar file through a python interpreter. See https://wiki.python.org/jython/UserGuide#invoking-the-jython-interpreter for more.
Multiple methods to run Jython from the java code while running through JVM are described here, at the Jython documentation.
EDIT:
You can execute a command line code that runs the python file you want.
Link to an example of running command line code from java here.