When I'm building on Windows with scons-qt4 plugin, my application always opens a console window, even though it has its own windows. With QMake, you could force application to do the same by adding CONFIG += console or something similar, but the default behaviour is to suppress it. QMake can handle it - I'm sure scons can, too.
The only way I see so far to solve this problem would be to use #ifdef around int main():
#ifdef WIN32
int WinMain (int _argc, char **_argv)
#else
int main (int _argc, char **_argv)
#endif
But that's just abominable!
So, it seems, my question was almost already answered here. Now, applied to scons, these two lines did it for me:
if (env ['PLATFORM'] == 'win32'):
env.Append (LINKFLAGS = ['-Wl,-subsystem,windows'])
Also, kind thanks to the folks on the [scons-users] mailing list. In particular, David Van Maren pointed out that:
You might look for whether you are
linking against the qtmain library.
The latest Qt documentation only says
this about it:
--------------- The qtmain Library
qtmain is a helper library that
enables the developer to write a
cross-platform main() function on
Windows and on the Symbian platform.
If you do not use qmake or other build
tools such as CMake, then you need to
link against theqtmain library.
It may not be related, but I think
that once I added it to the link, the
bogus console disappeared for our Qt
gui applications.
This may be another way to solve the problem, for example, when program is compiled with other tools than GCC + MinGW.
Related
I have a main file(main.cpp) and a header file(nodes.hpp). The main file takes N(any positive integer) as input argument and by using the functions of header file it gives output say 'x & y' (both double).
Note:
Both main and header files are written in C++.
Both main and header files instead of using data structues as arrays,vectors, make use of Eigen Library.
I have to write a python wrapper for them, I have working knowledge of python but have never used any wrapper.
Can anybody please refer or give some notes about using python wrpper for such code?
Here are your options:
You can use ctypes, and I consider this the cleanest solution, because you convert your program to a shared library that can be called by any other software, not only Python. You, though, have to write a C-interface for your program yourself.
You can use Python C-Extension, and I consider this the worst solution, because it's very low level, and prone to memory leaks, and costs lots of time to implement one function, and is Python-version dependent. Basically this is good to start a Python interpreter inside your C++. You can create PyObjects (which is the main building block of any Python type) and deal with them insdie C/C++.
You can use SWIG, where it automatically creates the the interface that you have to create with ctypes through an interface file that you define. People say it's very good, but the documentation is not as good.
You can use Boost.Python, which is good, but it has a very ugly build system with bjam. If you can manage to bypass that, then it's even better than ctypes. I'm a big boost fan, but bjam is why I don't use this.
What I do typically is ctypes. I trust it because it emphasizes the single-reponsibility principle. The library has a job that's separate from the interface (the C-interface), which is also separate from your Python script that uses that interface and exposes "the easy functionality" to the user.
Use Boost.Python. Here is my tutorial, previously on SO Docs.
Using Boost.Python
Things are easy when you have to use a C++ library in a Python project. Just you can use Boost.
First of all here is a list of components you need:
A CMakeList.txt file, because you're going to use CMake.
The C++ files of the C++ project.
The python file - this is your python project.
Let's start with a small C++ file. Our C++ project has only one method which returns some string "This is the first try". Call it CppProject.cpp
char const *firstMethod() {
return "This is the first try.";
}
BOOST_PYTHON_MODULE(CppProject) {
boost::python::def("getTryString", firstMethod); // boost::python is the namespace
}
Have a CMakeLists.txt file a below:
cmake_minimum_required(VERSION 2.8.3)
FIND_PACKAGE(PythonInterp)
FIND_PACKAGE(PythonLibs)
FIND_PACKAGE(Boost COMPONENTS python)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
PYTHON_ADD_MODULE(NativeLib CppProject)
FILE(COPY MyProject.py DESTINATION .) # See the whole tutorial to understand this line
By this part of the tutorial everything is so easy. you can import the library and call method in your python project. Call your python project MyProject.py.
import NativeLib
print (NativeLib.getTryString)
In order to run your project follow the instructions below:
Create a directory with the name build.
Enter into that directory.
Give the command cmake -DCMAKE_BUILD_TYPE=Release ..
make
python MyProject.py. Now, you have to see the string which the method in your C++ project returns.
Another tool for C++ wrapper generation is CLIF. Released in 2017, Google uses this for most everything these days. We no longer allow new SWIG wrappers to be written for Python internally.
It is built on top of Clang for the C++ parsing and requires relatively idiomatic modern C++ API use (unsurprisingly following Google's Style Guide) rather than any attempt to allow you to shoot yourself in the foot via SWIG's "support everything poorly" approach.
Try with official documentation:
https://docs.python.org/2/extending/extending.html
this link will provide you simple example of how to include a cpp module and use it from the python interpreter, or if this is possible try with Cython: http://cython.org/
Cython will allow you to write C-like, Python-like code which will be translated to CPP compiled and then will be easily accessible from the Python.
You can use Boost.Python
or go with the Python native interface
I would recommend Boost.Python if you already have Boost set up.
I am attempting to embed Python in an (ultimately multiplatform) C++ app.
It's important that my app contains its own Python implementation (in the same way that blender does), so that it is entirely self-contained. (Else it becomes a configuration minefield).
I have two options:
Attempt to embed Python3 without the standard library (which I have asked here)
Attempt to embed Python3 with the standard library.
What is required for (2)?
With this information I would be able to balance the merits of each approach against the effort required to set it up.
My embedded Python will be for my own use (rather than any userland scripting) -- mainly control flow / game logic. I will need very little from the standard library -- maybe I can whittle that down to 0 by tunnelling back into C++ whenever necessary -- for example if I need a random number, I can create a C++ routine and access that from Python. I have all of that covered.
However, it is starting to look as though even a minimal installation will have to contain some stdlib component(s), which prompts the question: "If I must include some, maybe it is better to include all!"
Since this doesn't really have an answer, I will offer this for posterity. I also do not have access to a Mac, so it may be a little different for you than on Linux. Also, the required dependencies must be installed for this to work, but that is usually easy enough to figure out.
Create a working directory
mkdir ~/embeddedpython
cd ~/embeddedpython
Download the Python source
wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tgz
Create an installation directory for Python
mkdir ./installation
Extract the downloaded source files
tar xvf Python-3.6.1.tgz
Enter the newly created source directory
cd Python-3.6.1
Configure Python to install in our installation directory
./configure --prefix="/home/<username>/embeddedpython/installation"
Make and install Python
make && make install
Go back to your working directory
cd ..
Create a new PYTHONHOME directory where the library will reside
mkdir home && mkdir home/lib
Copy the Python library to our new home directory
cp -r ./installation/lib/python3.6 ./home/lib/
Create a new c++ source file (embeddedpython.cpp) with the following code taken from the python documentation, with the exception of the setenv function call.
#include <Python.h>
#include <cstdlib>
int main(int argc, char *argv[])
{
setenv("PYTHONHOME", "./home", 1);
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
if (Py_FinalizeEx() < 0) {
exit(120);
}
PyMem_RawFree(program);
return 0;
}
Compile and run
g++ embeddedpython.cpp -I ./installation/include/python3.6m/ ./installation/lib/libpython3.6m.a -lpthread -ldl -lutil
./a.out
> Today is Fri Apr 14 16:06:54 2017
From here on it is standard embedded python as usual. With this method, the "home" directory must be included in your deployment, and the environment variable PYTHONHOME must be set to point to it before any python related code is executed.
You are looking for Boost.Python!
It's a C++ library which enables seamless interoperability between C++ and the Python programming language and in my opinion this should suffice your need, unless you are trying to achieve something else.
It also has a mechanism for embedding the python interpreter into C++ code and one can refer to this link (URL isn't release specific) to delve into the possibilities.
P.S. I believe less in reinventing the wheel and more into the re-usability.
I suppose that you have already double check how to Embedding Python in Another Application (here you will see something which cover embedding python2 but will be true for python3 also in my opinion)
There is different types of embedding:
Very High Level Embedding
Beyond Very High Level Embedding
Pure Embedding
Embedding Python in C++
As your question is relative to "Embedding Python in C++" you may read this:
It is also possible to embed Python in a C++ program; precisely how
this is done will depend on the details of the C++ system used; in
general you will need to write the main program in C++, and use the
C++ compiler to compile and link your program. There is no need to
recompile Python itself using C++.
As one hand you said "(ultimately multiplatform) C++ app", and in the other hand you have "precisely how this is done will depend on the details of the C++ system used", so may you explain more details of the C++ system used ?
You may also find some tips here relative to the use of pybind11 module or another old page which treat about how to Embed Python and Import Modules in C/C++ (python2.6 but I hope you may found inspiration with)
To conclude:
You'll obviously need development packages for Python in order to have
the Python include directory
If this question could be worded better/needs to be split into many questions, please alert me
I need to package Python scripts in order to ship them as single-executables (ideally), or single-executables with supporting files (non-ideally).
I have seen py2app and py2exe. They do not fit my requirements, as I am looking for a single method to do this, and in the future may need to have the packaged scripts interact with the executable that they are being run from.
What is the best way to go about this? The scripts which I would be embedding may even require multiple files, which complicates matters I'm sure.
If I wanted to use an interpreter other than CPython (ie: PyPy or Stackless) in the future, would the process be different (other than API calls in the C++ executable)?
Does Python have to be installed on the computers which would be running the package, or does embedding Python mean that it is fully embedded? I saw on the Python Wiki something about Py_SetPythonHome(), which would indicate to me that it needs Python (or at least its libraries) to be installed. Am I correct?
PyInstaller with the --onefile option will put everything inside a single file, though it will take a little more time to startup. I'm afraid it's not compatible with PyPy, but it should not be so tricky to get it working using Stackless.
Good luck!
Are you sure that you need to embed the Python files?
I ask because you mention you want to package the Python files as single executables. Couldn't you install Python on the target machine and since Python scripts are executables on their own, you would only need something to kick them off. A master python script could kick off all the rest of the scripts.
Otherwise you should look in C++ what can run a Python script. Then have the master python script run all the other scripts.
Yes you can!
The easiest is with newest Python3 <OS> <arch> embeddable zip file, which contains .so/.dll and all modules.
Instructions are here: https://docs.python.org/3/extending/embedding.html
#include <Python.h>
int
main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_Finalize();
PyMem_RawFree(program);
return 0;
}
The trickier part is communication between your C++ code and Python code.
If you only have to pass a few strings back and forth, that's trivial, but if you want a very tight integration, then you'll probably need a few of these:
create a Python module in (C++ code, C ABI) and inject it -- that means Python will be able to run import yourmod; yourmod.yourfunc(...) which will run your C++ custom code and/or
resolve and call Python functions from C++ (the inverse) https://stackoverflow.com/a/3310608/705086
Single executable
If you cannot have an installer, and really do not wish to have a bunch of .DLL/.so/etc it's described e.g. here Merge DLL into EXE? and it's ABI-specific, there will be one way for Windows, another Linux, etc, and you may have to override Python's import machinery (so that it doesn't look for dll/so in the file system) -- at this point, you may as well use PyInstaller or extend/merge PyInstaller with your application. Please research https://github.com/pyinstaller/pyinstaller/tree/develop/bootloader/src and evaluate how hard that might be
PyPy
Simple embedding is possisble http://doc.pypy.org/en/latest/embedding.html but single-file embedding is not. You could hack PyPy source and build custom embeddable object, but you'd be the first to do so :)
Stackless
Should be as simple as regular CPythion
I want to build a python program that get as input a path to .c file and then it compile its.
The program will output OK to the screen if the compilation is sucessful, and BAD otherwise.
I'm been trying to google it, but could not find anything. I've been also trying to run cmd within python with an argument of the compiling program but it didn't work.
To clarify - I've already got a very specific compiler in my machine which I want to run. I dont want python to act as a compiler. Just get a code, run my compiler over it, and see what's the answer.
It should work on Linux server with python 2.4.
Thanks
You can compile C code using only the standard library, and it will work on every platform and with every Python version (assuming you actually have a C compiler available). Check out the distutils.ccompiler module which Python uses to compile C extension modules. A simple example:
// main.c
#include <stdio.h>
int main() {
printf("Hello world!\n");
return(0);
}
Compilation script:
# build.py
from distutils.ccompiler import new_compiler
if __name__ == '__main__':
compiler = new_compiler()
compiler.compile(['main.c'])
compiler.link_executable(['main.o'], 'main')
Everything else (include paths, library paths, custom flags or link args or macros) can be passed via various configuration options. Check out the above link to the module documentation for more info.
Sure, why not? Of course, you'd need GCC installed (or llvm) so you have something to compile with. You can just use os.system, or any of the other ways for calling an external program.
Of course, you're probably better off looking at something like SCons, which already exists to solve this problem.
Plus, to answer the question actually asked, there's nothing that would prevent you from writing a compiler/assembler/linker in python, they're just programs like anything else. Performance probably wouldn't be very good though.
The following steps should do the trick:
Get PLY. Python Lex and Yacc. http://www.dabeaz.com/ply/
Find a Yacc/Lex configuration for C. http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
Tweak PLY to use the C language rules you found.
Run. You are "compiling" C code -- checking the syntax.
If I understood you clearly, you just want to run compiler with some arguments from python?
In this case, you can just to use os.system. http://docs.python.org/library/os.html#os.system
Or better way is module "subprocess". http://docs.python.org/library/subprocess.html#module-subprocess
I want to create a GUI application which should work on Windows and Mac. For this I've chosen Python.
The problem is on Mac OS X.
There are 2 tools to generate an ".app" for Mac: py2app and pyinstaller.
py2app is pretty good, but it adds the source code in the package. I
don't want to share the code with the final users.
Pyinstaller generates UNIX executable, so how to run it on Mac? I
created a bundles with this executable, but the resulted ".app" is
not working.
The questions are:
How to configure py2app to include the source code in the
executable, so the final users will not have access to my program?
How to convert UNIX executable to Mac ".app" ?
Is there a way to compile Python code with GCC ?
In Windows it's easy, I created an "exe" file from Python code and
it works. Is it possible to create a single file "app" for Mac ?
P.S. I use two computers (Windows and for Mac), Python 2.7, wxPython, py2exe, py2app and pyinstaller.
Also, I have checked out these sites:
http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html
http://www.pyinstaller.org/export/develop/project/doc/Manual.html?format=raw
http://www.pyinstaller.org/wiki/Features/MacOsCompatibility
http://www.stackoverflow.com/questions/2933/an-executable-python-app
How to configure py2app to include the source code in the executable,
so the final users will not have access to my program?
Unless you very seriously hack the python interpreter (and include the mangled version) there is no really good way to hide the source from a moderately skilled and determined user. I strongly believe this is true on Windows also. Basically, whether you include true source or bytecode, a pretty clean version of the source can be recovered. More importantly, in my opinion, unless you include the actual source code (as opposed to bytecode, you will introduce a possible dependency on the interpreter version).
How to convert UNIX executable to Mac ".app" ?
What do you mean by a UNIX executable? A Darwin (OS X) binary [which isn't actually UNIX]? That can be done using the kinds of tools you already mentioned, but it must be done carefully to avoid library dependencies.
If all you want it a simple wrapper to put a command-line binary into a window, it's pretty easy to accomplish and the free XCode suite has several examples that would serve (depending on what output
you wan to deliver, if any).
Is there a way to compile Python code with GCC ?
GCC does not compile Python. It's a different language (although there tools in the gcc family rthat support multiple language front-ends, but not Python). There are tools that attempt to translate Python into C, and then you can compile that into a true binary, but this only works for programs that avoid certain types of construct, and the process (and restrictions) need to apply your libraries as well.
One project to allow this is Cython. It works well for some types
of code, mostly numerical code, but it is not trivial to install and
exploit, very especially if you want to produce something that runs on multiple
different computers.
In Windows it's easy, I created an "exe" file from Python code and it
works. Is it possible to create a single file "app" for Mac ?
I would have to say I am skeptical -- very skeptical -- about this. Just like the OS X case, the exe almost certainly has the source code trivially accessible within it.
One fairly easy trick is to encrypt the source code and then decrypt it on the fly, but this
seems to me like more trouble than it's worth.
PyInstaller will automatically create bundles under Mac OSX for windowed executables. When running ypinstaller.py, make sure to pass the option "--windowed".
This feature is documented in the website of pyinstaller
If you're not completely committed to wxPython (and for anyone else looking for a cross platform Python GUI framework), I recommend you check out Kivy. It's cross platform, GPU accelerated, and it will do the app packaging for you. It's easy to jump into, has a well thought-out architecture, and gives you an incredible amount of flexibility in terms of the interface. It's the best way I've found to make a cross platform Python GUI app.
cxFreeze was the choice.
I use it pack my python program to a Mac OS X app. Which works like a charm.
Automator was already mentioned as a quick and simple solution for Pythons scripts that are contained in a single file, but since the Automator UI has so many options, and it is not obvious how to actually do it, I'll provide step-by-step instructions (verified to work on Yosemite):
In Automator select File > New and pick Application as document type.
Next, make sure Actions tab is selected on the left, and then in the search box type run. Among other options you'll see Run Shell Script — doubleclick it, and an editor window will appear in the right panel.
From the Shell dropdown menu select /usr/bin/python.
Paste your Python code into the edit window and then pick File > Save.
By default, the app will be saved under $HOME/Applications and will appear in Spotlight.
If you want to be able to set your own icon and have some fancy features, like task bar icons with a menu, log windows etc, then have a look at Platypus — an open-source app for creating MacOS native bundles.
2: You can't "convert" it, but you can move the executable to App.app/Contents/MacOS/something in a .app file, with CFBundleExecutable set to "something". This would not generally be recommended.
A motivated person could probably reconstruct usable source code from the Python bytecode in your app, so you might reconsider your opposition to py2app. If you don't trust your final users, why are you doing business with them?
Having used py2exe for windows users so they wouldn't have to deal with library versions, I've torn apart the compiled programs, they include the python bytecode files. While you can make it a violation of the license to look inside those, the fact is that if a computer can execute them, I can read them. It is possible to compile python programs with gcc, via a C preprocessor (try looking for 2c.py on google), I don't know if any of them support GCC. Again, you don't gain any security through using them, but you can get a significant speed improvement.
I haven't tried it with big Python projects, but for my own scripts, the easiest way I found was to use Automator
You can interactively create an app project with Run Shell Script action, then paste in your script in its editor, select your shell program (/usr/bin/python), finally save the project. And you have yourself a Mac native app.
Automator can also be driven by AppleScript. So you can pipeline this py-2-app conversion process to your build scripts.
I've never tested a GUI program with it so I don't know if you'll be happy with it. But I'd give it a try since you may wonder how well all the cited 3rd-party python modules/applications are maintained, and how long they are gonna last. Coming bundled with OS X, Automator will likely stay, unless Apple got REALLY tired of it.
cxFreeze is best solution available, first create your program or application using python and than make setup file for your application, and than build the app using build command python setup.py build, according to your requirement you need to make some changes.
The only way is py2app. You have no other way. Sorry.
The research you did seems very solid and you did not miss anything.