I am trying to get KDDockWidgets 2.0 into my PySide2 Python 3.10 application. I have followed the Python bindings guide they provide (with great confusion on a Windows machine) and now am able to build KDDockWidgets with CMake, however, it is absolutely unclear what I do from here to actually be able to use the bindings in my QML code. I see in one of their examples what would be imported in QML, but how would PySide2 know where to look for it?
The guide gives me the impression that it would generate a Python module in my virtual environment's site-packages, but there is no evidence of it doing that, nor do I see any errors at all.
My build script:
setlocal
set VS_YEAR="2022"
set KDDW_REPO="KDDW"
set PY_ENV_NAME="env"
set PY_SITE_PKG="F:\Projects\Code\Python\boslin\env\Lib\site-packages\"
call "C:\Program Files\Microsoft Visual Studio\%VS_YEAR%\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
cd %KDDW_REPO%
cmake . -DCMAKE_BUILD_TYPE=Release -DKDDockWidgets_PYTHON_BINDINGS=True -DKDDockWidgets_PYTHON_BINDINGS_INSTALL_PREFIX=%PY_SITE_PKG%
endlocal
Related
TL;DR: how to use Cython as a distribution method instead of Py2exe, cx_freeze, pyinstaller, etc.
Following Making an executable in Cython, I'd like to see how it could be possible to distribute a Python program to any Windows user (who doesn't have Python already installed on his machine) by compiling it first with Cython --embed.
Let's use a test.py:
import json
print(json.dumps({'key': 'hello world'}))
and compile it:
cython test.py --embed
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
cl test.c /I C:\Python37\include /link C:\Python37\libs\python37.lib
It works and produces a 140KB test.exe executable.
Running test.exe on another machine doesn't work out-of-the-box, it requires:
python37.dll in the same folder
to install the usual vc_redist.x64.exe file
Even with this, it still does not work (screenshot below instead of copy/paste because I didn't manage the copy/paste in the VM - off topic here):
ModuleNotFoundError: No module named 'encodings'
Question: what is the minimal set of files required to distribute an --embed-Cython-compiled code and make it work on any machine (without Python previously installed on it)?
After further research (I tried in an empty Win 7 x64 bit VM, without any VCredist previously installed), it seems that these files are enough:
the program itself, test.exe (produced by cython --embed and compilation with cl.exe)
python37.dll
python37.zip coming from packages named "Windows x86-64 embeddable zip file" in https://www.python.org/downloads/windows/
vcruntime140.dll, as mentioned in Can I bundle the Visual Studio 2015 C++ Redistributable DLL's with my application? or ask the user to install vc_redist.x64.exe before
ucrtbase.dll
more than 30 files api-ms-win-*.dll were required too; if not you will have the following error:
... api-ms-win-crt-runtime-l1-1-0.dll is missing ...
Notes:
if you require another library, like pygame, just copy/paste the folder from C:\Python37\Lib\site-packages\pygame seems to work
for me, concrt140.dll, msvcp140.dll, vccorlib140.dll did not seem necessary
Useful to test all this: Prevent a Python-embedded to look in my default path C:\Python38 for modules.
I'm developing a Python binding for a C++ library using Boost Python, for Linux and Windows (Visual Studio).
In Windows, the static Boost Python library has a dependency against Python (this is motive for another thread, here), so, in my CMake config I need to do:
if((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") OR APPLE)
target_link_libraries(my_python_module ${Boost_LIBRARIES})
elseif(WIN32 AND MSVC)
add_definitions(/DBOOST_PYTHON_STATIC_LIB)
target_link_libraries(my_python_module ${Boost_LIBRARIES}) #This includes the Boost Python library
# Even though Boost Python library is included statically, in Windows it has a dependency to the Python library.
target_link_libraries(my_python_module ${Python_LIBRARIES})
endif()
This works fine in Linux, but in Windows, it only works in Release mode, not in Debug, in which case I always get a:
LINK : fatal error LNK1104: Can't open file 'python37.lib'
After some hair pulling I noticed the issue was caused by CMake instructing Visual Studio to link against 'python37_d.lib' instead of 'python37.lib' in the Debug mode.
However, as I described in the linked issue, the officially provided Boost Python debug library is linked against the Python release library, not the debug one. So, the solution would be to force the link against the Python release library, regardless of the build type. Unfortunately, ${Python_LIBRARIES} sets the library automatically depending on the mode, and I wouldn't like to explicitly specify python37.lib in my code (since I can upgrade Python and I don't want to have to change my CMake scripts because of that).
I found some similar issues here and here, but that doesn't reflect the exact situation I'm facing. Based on those, I tried setting:
target_link_libraries(my_python_module optimized ${Python_LIBRARIES})
But that didn't work either. So, the question is:
Is there a way to force the usage of the Python release library in Debug mode WITHOUT having to set it explicitly and leaving the Python CMake package to do it automatically instead. By explicit I mean doing:
target_link_libraries(my_python_module python37)
Thanks a lot for your help.
It seems that set(Python_FIND_ABI "OFF" "ANY" "ANY") as suggested in the comments by kanstar would be the correct way to do this. However, while Python_FIND_ABI is in CMake master, it hasn't been released yet in the latest version (v3.15.2 as of this writing).
In the meantime, there are solutions dependent on the CMake version.
CMake 3.12 and above
It's possible to link against FindPython's Python_LIBRARY_RELEASE, which isn't meant to be part of the module's public interface, but the variable is set correctly nonetheless.
cmake_minimum_required (VERSION 3.12)
find_package(Python ..<choose your COMPONENTS; refer to FindPython docs>..)
if(WIN32 AND MSVC)
target_link_libraries(my_python_module ${Python_LIBRARY_RELEASE})
endif()
CMake 3.0.4 to 3.11
Thanks to a comment by #Phil, we can expand the answer to include earlier CMake versions which had the FindPythonLibs module that sets the PYTHON_LIBRARY_RELEASE variable instead.
cmake_minimum_required (VERSION 3.0)
find_package(PythonLibs ..<refer to FindPythonLibs docs>..)
if(WIN32 AND MSVC)
target_link_libraries(my_python_module ${PYTHON_LIBRARY_RELEASE})
endif()
I try to compile PJSUA2 for Python. I could manage to compile the source with Visual Studio 2015 Community edition.
My question is, how can I install the Python module now?
The guide suggests to use make and make install. I tried to install also minwg, but it is not working as the project was compiled with VS.
I have also tried to compile with minwg, but I never could succeed due to undefined requirements. Also official PJSUA guide recommend to use VS for Windows.
Following settings have been applied to build from source:
Swig location has been added to path
JAVA_home system variable has been added
Java location has been added to path
Empty pjlib/include/pj/config_site.h has been created
Opened source in VS 2015 Community (all suggested VS package and module has been installed)
Set following project to do not compile:
pjsua_cli_uwp_comp
pjsua_cli_wp8
pjsua_cli_wp8_comp
Set swig_java_pjsua2 to build.
Add following folders to swig_java_pjsua2 VC++ include directories
c:\Program Files\Java\jdk-11.0.2\include
c:\Program Files\Java\jdk-11.0.2\include\win32
Build solution
I could make a workaround to compile pjsua2 for Python 3.7. If you have a better solution or just suggestion to this workaround, let me know
Preconditions:
List item
Download and extract swig (swigwin 4.0.0)
Download and install JDK
Download and install Python (Python 3.7.3 x64) and set at custom installation:
tick "Add Python to environment variables"
tick "Precompile standard library"
tick "Download debugging symbols"
tick "Download debug binaries (requires VS 2015 or later)"
set custom path if you want
add swigwin location to system path
add Python location to system path
add JAVA_HOME system variable
add %JAVA_HOME%\bin to system path
Install Visual Studio 2015 Community edition
Steps:
Download and extract pjsip 2.8
Create empty config_site.h under pjlib/inlclude/pj/ folder
Open pjproject-vs14.sln in VS
There will be an unsupported warning window, press OK
At the "Install Missing Features" windows, press install
VS installer will be started, and VS has to be closed to complete installation.
I have also added "Windows 10 SDK (10.0.10586)" to the installation.
I have also enabled developer mode on my Windows 10, but this could be optional
Open project again in VS
Set project to Release and x64 on the top dropdown
Right click on the solution, and go to Configuration Properties> Configuration
Remove all uwp and wp8 related projects from selection, like pjsua_cli_uwp_comp, pjsua_cli_wp8_comp
press OK, and build solution
I have had 34 succeeded and 0 failed solution after build.
Add following lines to pjsua2.i in pjsip-apps/src/swig folder
%inline %{
pj_ssize_t new_pj_ssize_t(int s) {
return (pj_ssize_t) s;
}
%}
this extra inline swig function provides workaround for create recorder issue
Open a command line (powershell did not work for this)
go to pjsip-apps/src/swig/python
Execute following command:
swig -I../../../../pjlib/include -I../../../../pjlib-util/include -I../../../../pjmedia/include -I../../../../pjsip/include -I../../../../pjnath/include -py3 -c++ -python -threads ../pjsua2.i
Add new "Empty Project" (Visual C++) to solution with swig_python_pjsua2 name
Add libpjproject and pjsua2_lib as reference to this new project
Right click on the Header Files>Add>Existing Item...
Add pjsip-apps\src\swig\pjsua2_wrapp.h
Add a "new filter" to the project with name "Generated Code"
Right click on "Generated code" and add new existing item.
Add pjsip-apps\src\swig\pjsua2_wrapp.cxx
Right click on the project and Linker>Input
Add "Ws2_32.Lib" to "Additional Dependencies"
Go to "VC++ Directories"
Add following folder to include path(I have used full path!):
c:\python37\include
pjnath\include
pjsip\include
pjmedia\include
pjlib-util\include
pjlib\include
Add following folder to Library Directories:
C:\Python36\libs
Set at General:
Target Name: _$(ProjectName)
Target Extension: .pyd
Configuration Type: Dynamic Library (.dll)
Go to properties of the solution, and select swig_python_pjsua2 to build
Right click on swig_python_pjsua2 and build
Build should complete successfully
You will need to file to use pjsua2 library in python.
pjsua.py located under pjsip-apps/src/swig/python
x64/Release/_swig_python_pjsua2.pyd (rename this to _pjsua2.pyd)
To test, copy those to file into a folder, start python from same folder and type:
import pjsua2
Thank You very much Krisz for this awesome work!
I just got it working for Python 2.7 / 32bit and some things are slightly different, so I will add them here:
Environment:
Windows 10
SWIG 4.0.1
PJSIP 2.9
Python 2.7.14 (32bit)
Visual Studio Express 2015 (V 14.0.25431.01 Update 3)
Whaddado:
Important: Check if your Python-interpreter is really x64 or win32 like the following:
start a python session and enter:
import platform
platform.architecture()
If you have 32bit, consider this in your choice for target platform in VS.
when you add this %inline%-Snippet to pjsip-apps/src/swig/pjsua2.i, add it at the end of the file!
when starting the swig-command, omit the "-py3"-parameter, if you use Python 2.x
there is a little typo in Krisz' description, at "pjsua.py located under pjsip-apps/src/swig/python" -> of course pjsua2.py is meant. Do not use the pjsua.py.
finally copy _pjsua2.lib and pjsua2.py into \Lib\site-packages\ and the _pjsua2.pyd into \DLLs\ to make them available everywhere.
I'm trying to install PySide v0.3.1 in Mac OS X, for Qt development in python.
As a pre-requisite, I have installed CMake and the Qt SDK.
I have gone through the documentation and come up with the following installation script:
export PYSIDE_BASE_DIR="<my_dir>"
export APIEXTRACTOR_DIR="$PYSIDE_BASE_DIR/apiextractor-0.5.1"
export GENERATORRUNNER_DIR="$PYSIDE_BASE_DIR/generatorrunner-0.4.2"
export SHIBOKEN_DIR="$PYSIDE_BASE_DIR/shiboken-0.3.1"
export PYSIDE_DIR="$PYSIDE_BASE_DIR/pyside-qt4.6+0.3.1"
export PYSIDE_TOOLS_DIR="$PYSIDE_BASE_DIR/pyside-tools-0.1.3"
pushd .
cd $APIEXTRACTOR_DIR
cmake .
cd $GENERATORRUNNER_DIR
cmake -DApiExtractor_DIR=$APIEXTRACTOR_DIR .
cd $SHIBOKEN_DIR
cmake -DApiExtractor_DIR=$APIEXTRACTOR_DIR -DGeneratorRunner_DIR=$GENERATORRUNNER_DIR .
cd $PYSIDE_DIR
cmake -DShiboken_DIR=$SHIBOKEN_DIR/libshiboken -DGENERATOR=$GENERATORRUNNER_DIR .
cd $PYSIDE_TOOLS_DIR
cmake .
popd
Now, I don't know if this installation script is ok, but apparently everything works fine. Each component (apiextractor, generatorrunner, shiboken, pyside-qt and pyside-tools) gets compiled into its own directory.
The problem is that I don't quite understand how PySide gets into the system's python environment. In fact, when I start a python shell, I cannot import PySide:
>>> import PySide
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named PySide
Note: I am aware of the Installing PySide - OSX question, but that question is not relevant anymore, because it is about a specific a dependency on the Boost libraries, but with version 0.3.0 PySide moved from a Boost based source code to a CPython one.
I don't have any MacOS experience but assuming it's similar to any *nix, let's go:
About the script: Isn't it missing some "make, make install" commands? The version you posted just run cmake to configure the build. Also for testing, I set -DCMAKE_INSTALL_PREFIX= for all modules. That way everything is installed in the same place and CMake takes care of finding them for me, as long as I used the same install prefix for each one. The directory layout in your script is quite complicated and mixes build and source directories.
About finding PySide: once everything is properly compiled and installed, the directory where the "PySide" directory was installed must be available in the PYTHONPATH variable. In the example below,
Here's a simple version of a build script(works on Ubuntu):
#!/bin/bash
BUILD_ROOT=/tmp/pyside-build
INSTALL_PREFIX=/tmp/sandbox
function build_module {
cd $BUILD_ROOT
echo Cloning project $1 from url $2
git clone --depth 1 $2 $BUILD_ROOT/$1
BUILD_DIR=$BUILD_ROOT/$1/build
mkdir -p $BUILD_DIR
cd $BUILD_DIR
echo Configuring $1 build.
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX ..
echo Configured $1. Starting build.
make LD_LIBRARY_PATH=$INSTALL_PREFIX/lib
echo Built $1. Installing.
make install
echo Successfully built and installed $1
}
rm -rf $BUILD_ROOT
mkdir -p $BUILD_ROOT
build_module apiextractor git://gitorious.org/pyside/apiextractor.git
build_module generatorrunner git://gitorious.org/pyside/generatorrunner.git
build_module shiboken git://gitorious.org/pyside/shiboken.git
build_module pyside-shiboken git://gitorious.org/pyside/pyside-shiboken.git
Run it and wait a while (Qt is quite big). :)
This script will download all packages into /tmp/pyside-build, build each one in its own "build" directory and install everything into /tmp/sandbox. Then, I just had to set PYTHONPATH to /tmp/sandbox/lib/python2.6/site-packages and PySide worked fine.
In answer to the original post...
What your script would have done is generate the necessary build files to build the pyside bindings, but it wouldn't have done the build itself. To do the build itself you'd need to execute a 'make', then a 'make install' in each of the build directories.
I've gotten most of the way through getting pyside 0.3.1 up and running on the Mac (SnowLeopard 10.6.3), but am hung up on the final compile step. My script is a bit less straightforward than yours, but in essence similar.
I have run into and worked around a number of problems to get to the final compile, and am hoping that I can help some folks along with the solutions/workarounds I've devised. Also, maybe collectively we can figure out how to get through the final step.
I'm going to include the build script that I'm using, and the log of the changes I had to make in the distro to get it running. But first, the step that I'm stuck on... mainly, I don't understand the error message, and the requested file doesn't seem to exist...
I hope this will help move support for the mac along...
I can't post this directly on stack overflow since its too long, so here is the link to the post on the mailing list over at pyside.
http://lists.openbossa.org/pipermail/pyside/2010-June/000812.html
While it's a been couple months since this question originally was asked I ran across the official PySide build script repo at:
http://qt.gitorious.org/pyside/buildscripts
The README covers the build process:
http://qt.gitorious.org/pyside/buildscripts/blobs/master/README
It seems to be fairly automatic with my only caveat so far being that it pulls down libxslt via brew - I can't say authoritatively if libxslt shipped with Snow Leopard or not - but it's definitely in Lion by default.
Seemingly the only manual install step is putting cmake on your system.
It is PythonQt : pythonqt.sourceforge.net. I am using PythonQt-1.1 . Qt version 4.6.2 and Python 2.6.4.10 . Visual studio 2008
From instruction:
cd PythonQtRoot
vcvars32
qmake
nmake
after I typed qmake, it generated makefile, then I entered nmake but it said "makefile(22) :fatal error U1000: syntax error: ')' missing in macro invocation Stop." What did I do wrong here?
Thanks in advance....
I remember running into similar problems when building other packages with recent releases of Qt on Win32. I'm running under cygwin, by the way. After a fair amount of debugging, I discovered that 'qmake' was using the wrong 'mkspec'. One thing that helped this situation was to force the use of the correct mkspec, like so:
export QMAKESPEC=win32-msvc2008
or
export QMAKESPEC=win32-msvc
To find the list of all valid mkspecs, I looked in the directory:
c:\Qt\4.6.0\mkspecs
or
c:\Qt\2010.01\qt\mkspecs
For one particular package, I had some conflicts with other tools installed on my system and had to edit the actual mkspec file to point to the correct tool using an absolute path, but it sounds like that is not your problem here. It sounds like yours is generating a gmake-compatible Makefile instead of an nmake-compatible Makefile, so this fix should work.
-- Glenn
My suggestion is to include the PythonQt project as part of your very same project with CMake.
You then simply have to build it as part of your project statically (remove the SHARED from the add_library in the base CMakeLists.txt, by remembering that if you want it to be so, you have to remove the project(PythonQt) from its base CMakeLists.txt and then adding to your proper CMakeLists.txt base file the following:
if( PYTHON_QT_SUPPORT )
message(STATUS ":::: Including support for PythonQT Shell ::::")
# Include Python directories
find_package(PythonLibs REQUIRED)
include_directories("${PYTHON_INCLUDE_DIR}")
# Include PythonQt
include_directories(YOURPATHTOPYTHONQT/pythonqt/src)
add_subdirectory(YOURPATHTOPYTHONQT/pythonqt)
endif(PYTHON_QT_SUPPORT)
Have you made sure to update the Python/Qt versions in the build folder, and include everything you need in your environment?
In build\python.prf:
update python version
Use a Visual Studio Command Prompt and skip the vcvars32.
set your environment paths:
set PATH=E:\toolkits\Trolltech\Qt-4.8.6\Win_x64_6.1_v12_debug\lib;%PATH%
set PATH=E:\toolkits\Trolltech\Qt-4.8.6\Win_x64_6.1_v12_debug\bin;%PATH%
set PYTHON_PATH=E:\toolkits\Python\2.7.9\Win_x64_6.1_v12
set PYTHON_LIB=E:\toolkits\Python\2.7.9\Win_x64_6.1_v12\libs
In those paths, you should have available:
all qt libraries (QtCore4.dll, etc.)
all qt executables (uic, moc, etc)
python26.dll, python.exe
I've also had to update the other .prf files to make sure the debug extensions are properly done when i'm binding on debug dlls.