Command line compiling of C++ in Windows in Python script - python

The idea is to compile a C++ program. It contains a main.cpp, a printer.cpp, a printer.h, a scanner.cpp and scanner.h. These source files have one function print "hello". Now I am trying to create the object files and executables from the command line through a Python script and using cl.exe.
The error I get is LNK2019 so I know the issue is in the linking. I have looked though the options and I am using this for my Python !!
build = subprocess.Popen(['vcvarsall.bat', 'amd64_x86', '&&', 'cl', 'kernel32.lib',...[skipping some files]'uuid.lib','/I' + qtpath,'C:\\Users\\ROY_S\\Desktop\\CppMaker\\main.cpp','/ZI','/Gm','/EHsc','/MDd','/GS','/Fo'+path,'/Fe'+path+'main.exe','/link','/LIBPATH:'+qtlib,'/DEFAULTLIB:'+ qtlib+'QtMainIsar','/DEFAULTLIB:'+ qtlib+'QtCore','/DEFAULTLIB:'+ qtlib+'QtGuiIsar4','/DEFAULTLIB:'+ qtlib+'QtNetwork','/DEFAULTLIB:'+ qtlib+'QtOpenGLIsar4','/DEFAULTLIB:'+ ...[skipping...] qtlib+'QtWebKitIsar4','/INCREMENTAL','/NOLOGO','/TLBID:1','/DYNAMICBASE','/MANIFEST','/NXCOMPAT','/ERRORREPORT:PROMPT','/MACHINE:'+'X86','/OUT:'+path+'main.exe' ] , stdout=subprocess.PIPE)
I removed some libs so that its easier to read. I dont understand how do I link everything even after specifying the lib files in my script.
I can also move on to other solution instead of using cl.exe. Anything that has easy control over the commandline I am okay with it.

In windows I think it's a good idea to use Visual Studio project/solution and build it using MsBuild.
Project/solution file may be created manually or in Visual Studio.
You may also create properties in project/solution and pass them in MsBuild (see MsBuild documentation)

check = subprocess.Popen(['vcvarsall.bat', 'amd64_x86', '&&', 'msbuild',Path,'/p:configuration=%s' % Configuration])
This solves my issue.Instead of playing with the cl.exe , I make a template of a vcxproj file. Then my code adds the sources and header files in the vcxproj file and I compile that using msbuild. I feel its a much easier solution because I dont have o care about the individual libraries to add and can just add a propery sheet to my vcxproj file .
Also see https://msdn.microsoft.com/en-us/library/ms164311.aspx

Visual Studio is the easiest solution although if you REALLY don't like visual studio you can get gcc through https://www.cygwin.com/

Related

Rust and Python on W10: LNK1181

I'm trying to write a Rust module which can be called from Python. I'm following this page:
https://developers.redhat.com/blog/2017/11/16/speed-python-using-rust#edit_src_lib_rs
On cargo build --release I get this error:
= note: LINK : fatal error LNK1181: cannot open input file
'python39.lib'
This has come up before, and this seems the most recent and relevant answer.
I seem to have tried all the possible solutions in that answer, including locating and running vcvars64.bat, as detailed here. No joy.
I have MS Visual Studio (2019) installed, with the C++ and W10 SDK components.
Significantly, this error sometimes does not occur when I don't include the --release switch. Without it, the program (sometimes) compiles and runs OK. Given that one reason for wanting to make a Rust module is performance, however, I'd like to solve this problem. Also I have now found that this successul building of a "debug" build is a) intermittent and b) partial: when it fails, some of the desired output files are created but not others.
And...
According to the page at the first link, it seems that after build, I should then be looking for a file ending .so. In a W10 OS I'm looking for a .dll file.
If it builds completely successfully, under target\debug I have myrustlib.d, myrustlib.dll, myrustlib.dll.exp, myrustlib.dll.lib, myrustlib.pdb, pyext_myrustlib.pdb, pyext_myrustlib.d and pyext_myrustlib.exe. None of these, renamed and/or given an .dll extension as applicable, can be successfully imported as a Python module, at least as documented on that page.
I've also found this more recent page for doing the same thing. I get the same 1181 error.
python39.lib
I found out where this is located in my system, under ... Python\Python39\libs. I modified my PATH env var to specifically include this path (and rebooted). Still the same error.
Workaround:
This page, using PyO3 instead of rust-cpython (actually a fork of the latter), appears to do things successfully, on my machine + OS at least.
NB at the time of writing the second example appears to contain a typo: I believe it should be
fn hashset(_: Python, m: &PyModule) -> PyResult<()> {
rather than
fn hash_set(_: Python, m: &PyModule) -> PyResult<()> {
if you want it to compile OK (author has been notified). I have managed to create a module (hashset.cp39-win_amd64.pyd in a W10 OS) which successfully enables you to import this Rust construct into Python.

Error: 'python35_d.dll is missing' while running C++ code with Python in MS Visual Studio 2015

I am trying to embed Python in my C++ code to use WordNet through nltk. I am new to Python and I am using MS Visual Studio 2015 to do the same but I'm facing problems to use Python on MSVS 15.
So far I've,
installed Python 3.5.1,
included this path: ...\Python\Python35-32\include, which let me include the Python.h library,
added this path: ...\Python\Python35-32\libs to access the lib files, and python35.lib as dependency in Linker\Input setting of MSVS15,
then there an error occurred, demanding python35_d.lib, so I compiled Python's source in Debug mode & copied that file to that ...\libs folder and it solved the problem.
This all happened when I was trying to run this only-
Py_Initialize();
PyRun_SimpleString("print (\"Hello World!\\n\")");
Py_Finalize();
Now I'm trying to run a Python function from a .py file. I'm trying to run this from the Python tutorials but I'm getting this error -
While debugging, I have found that when this macro gets called: Py_DECREF(), this error occurs.
Do I only need to copy python35_d.dll from PCBuild\win32 to C:\Windows\[System|System32|SysWOW64]\ to solve the problem as I don't know if it'll have any side-effects?
Although the file is already present in ...\Python\Python35-32\DLLs\.
Is there a proper setup to be done before running Python in C/C++ using MSVS, like this for Unix-like systems? (I mean by adding other dependencies or folders to the settings)
I've been reading Python documentation continuously and even other stackoverflow questions but I'm still struggling a lot (I don't know why) even to do simple things.
Can somebody guide/enlighten me for something I may be missing because I'm continuously getting errors here & there, please?
Thanks.
copy python35.dll into the folder where .sln file is present

Install docs for python to libdir location

I have a project in which we have some documentation that is generated in Visual Studio which is parsed by the runtime of Python so that our users can do things like help (our.module) in the REPL window and get meaningful data. We are switching to autotools for our build environment in Linux. I must find a means of ensuring that the 2 xml files necessary are installed to $(libdir) by make.
My first attempt was to do something like this in Makefile.am
dist_lib_DATA = file1.xml file2.xml
However, this produced this result:
[afalanga#afalanga4 BuildSystemWork]$ autoreconf
Makefile.am:5: error: 'libdir' is not a legitimate directory for 'DATA'
autoreconf: automake failed with exit status: 1
It was told to me that there is a workaround mentioned somewhere in the autotools manuals. I'm not finding it as yet. The only method I can think of at this time for a "workaround" is to write a special rule in my Makefile.am which would copy the files. Something like this
install_docs : file1.xml file2.xml
cp $^ $(libdir)
Does this look correct or is there a better method of doing this? Another method might be if python has other places where it looks for documentation, I might be able to install there? Is this possible? I'm not that familiar with the internals of python for "in-line" help.

Compiling an IronPython WPF project to exe

What is the best way to pack up an IronPython application for deployment? After scouring the web the best thing I've come up with (and what I'm currently doing) is using clr.CompileModules() to glue together my entire project's .py files into one .dll, and then having a single run.py do this to run the dll:
import clr
clr.AddReference('compiledapp.dll')
import app
This is still suboptimal, though, because it means I have to
distribute 3 files (the .dll, the .xaml, and the run.py launcher)
install IronPython on the host machine
Plus, this feels so... hacky, after the wonderful integration IronPython already has with Visual Studio 2010. I'm completely mystified as to why there is no integrated build system for IPy apps, seeing as it all boils down to IL anyway.
Ideally, I want to be able to have a single .exe with the .xaml merged inside somehow (I read that C# apps compile XAML to BAML and merge them in the executable), and without requiring IronPython to be installed to run. Is this at least halfway possible? (I suppose it's ok if the exe needs some extra .DLLs with it or something. The important part is that it's in .exe form.)
Some edits to clarify: I have tried pyc.py, but it seems to not acknowledge the fact that my project is not just app.py. The size of the exe it produces suggests that it is just 'compiling' app.py without including any of the other files into the exe. So, how do I tell it to compile every file in my project?
To help visualize this, here is a screenshot of my project's solution explorer window.
Edit II: It seems that unfortunately the only way is to use pyc.py and pass every single file to it as a parameter. There are two questions I have for this approach:
How do I possibly process a command line that big? There's a maximum of 256 characters in a command.
How does pyc.py know to preserve the package/folder structure? As shown in my project screenshot above, how will my compiled program know to access modules that are in subfolders, such as accessing DT\Device? Is the hierarchy somehow 'preserved' in the dll?
Edit III: Since passing 70 filenames to pyc.py through the command line will be unwieldy, and in the interest of solving the problem of building IPy projects more elegantly, I've decided to augment pyc.py.
I've added code that reads in a .pyproj file through the /pyproj: parameter, parses the XML, and grabs the list of py files used in the project from there. This has been working pretty well; however, the executable produced seems to be unable to access the python subpackages (subfolders) that are part of my project. My version of pyc.py with my .pyproj reading support patch can be found here: http://pastebin.com/FgXbZY29
When this new pyc.py is run on my project, this is the output:
c:\Projects\GenScheme\GenScheme>"c:\Program Files (x86)\IronPython 2.7\ipy.exe"
pyc.py /pyproj:GenScheme.pyproj /out:App /main:app.py /target:exe
Input Files:
c:\Projects\GenScheme\GenScheme\__init__.py
c:\Projects\GenScheme\GenScheme\Agent.py
c:\Projects\GenScheme\GenScheme\AIDisplay.py
c:\Projects\GenScheme\GenScheme\app.py
c:\Projects\GenScheme\GenScheme\BaseDevice.py
c:\Projects\GenScheme\GenScheme\BaseManager.py
c:\Projects\GenScheme\GenScheme\BaseSubSystem.py
c:\Projects\GenScheme\GenScheme\ControlSchemes.py
c:\Projects\GenScheme\GenScheme\Cu64\__init__.py
c:\Projects\GenScheme\GenScheme\Cu64\agent.py
c:\Projects\GenScheme\GenScheme\Cu64\aidisplays.py
c:\Projects\GenScheme\GenScheme\Cu64\devmapper.py
c:\Projects\GenScheme\GenScheme\Cu64\timedprocess.py
c:\Projects\GenScheme\GenScheme\Cu64\ui.py
c:\Projects\GenScheme\GenScheme\decorators.py
c:\Projects\GenScheme\GenScheme\DeviceMapper.py
c:\Projects\GenScheme\GenScheme\DT\__init__.py
c:\Projects\GenScheme\GenScheme\DT\Device.py
c:\Projects\GenScheme\GenScheme\DT\Manager.py
c:\Projects\GenScheme\GenScheme\DT\SubSystem.py
c:\Projects\GenScheme\GenScheme\excepts.py
c:\Projects\GenScheme\GenScheme\FindName.py
c:\Projects\GenScheme\GenScheme\GenScheme.py
c:\Projects\GenScheme\GenScheme\PMX\__init__.py
c:\Projects\GenScheme\GenScheme\PMX\Device.py
c:\Projects\GenScheme\GenScheme\PMX\Manager.py
c:\Projects\GenScheme\GenScheme\PMX\SubSystem.py
c:\Projects\GenScheme\GenScheme\pyevent.py
c:\Projects\GenScheme\GenScheme\Scheme.py
c:\Projects\GenScheme\GenScheme\Simulated\__init__.py
c:\Projects\GenScheme\GenScheme\Simulated\Device.py
c:\Projects\GenScheme\GenScheme\Simulated\SubSystem.py
c:\Projects\GenScheme\GenScheme\speech.py
c:\Projects\GenScheme\GenScheme\stdoutWriter.py
c:\Projects\GenScheme\GenScheme\Step.py
c:\Projects\GenScheme\GenScheme\TimedProcess.py
c:\Projects\GenScheme\GenScheme\UI.py
c:\Projects\GenScheme\GenScheme\VirtualSubSystem.py
c:\Projects\GenScheme\GenScheme\Waddle.py
Output:
App
Target:
ConsoleApplication
Platform:
ILOnly
Machine:
I386
Compiling...
Saved to App
So it correctly read in the list of files in the .pyproj... Great! But running the exe gives me this:
Unhandled Exception: IronPython.Runtime.Exceptions.ImportException:
No module named Cu64.ui
So even though Cu64\ui.py is obviously included in compilation, the exe, when run, can't find it. This is what I was afraid of in point #2 in the previous edit. How do I preserve the package hierarchy of my project? Perhaps compiling each package seperately may be needed?
I'll extend the bounty for this question. Ultimately my hope is that we can get a working pyc.py that reads in pyproj files and produces working exes in one step. Then maybe it could even be submitted to IronPython's codeplex to be included in the next release... ;]
Use pyc.py to produce app.exe and don't forget to include app.dll and IronPython libraries.
As for XAML - I've created project just for .xaml files that I compile in VS and then use them from IronPython. For example:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/CompiledStyle;component/Style.xaml" />
</ResourceDictionary.MergedDictionaries>
It "boils down to IL", but it isn't compatible with the IL that C# code produces, so it can't be directly compiled to a standalone .exe file.
You'll need to use pyc.py to compile your code to a stub EXE with the DLL that CompileModules creates.
Then distribute those files with IronPython.dll, IronPython.Modules.dll, Microsoft.Dynamic.dll, Microsoft.Scripting.Debugging.dll, Microsoft.Scripting.dll, and of course the XAML file.
To compile other files, just add them as arguments:
ipy.exe pyc.py /main:app.py /target:winexe another.py another2.py additional.py
I posted a Python script which can take an IronPython file, figure out its dependencies and compile the lot into a standalone binary at Ironpython 2.6 .py -> .exe. Hope you find it useful. It ought to work for WPF too as it bundles WPF support.
To create a set of assemblies for your IronPython application so that you can distribute it you can either use pyc.py or SharpDevelop.
To compile using pyc.py:
ipy.exe pyc.py /main:Program.py Form.py File1.py File2.py ... /target:winexe
Given the amount of files in your project you could try using SharpDevelop instead of maintaining a long command line for pyc.py. You will need to create a new IronPython project in SharpDevelop and import your files into the project. You will probably need to import the files one at a time since SharpDevelop lacks a way to import multiple files unless they are in a subfolder.
You can then use SharpDevelop to compile your application into an executable and a dll. All the other required files, such as IronPython.dll, Microsoft.Scripting.dll, will be in the bin/debug or bin/release folder. SharpDevelop uses clr.CompileModules and a custom MSBuild task behind the scenes to generate the binaries.
Any IronPython packages defined in your project should be usable from your application after compilation.
Packaging up the XAML can be done by embedding the xaml as a resource. Then using code similar to the following:
import clr
clr.AddReference('PresentationFramework')
clr.AddReference('System')
from System.IO import FileMode, FileStream, Path
from System.Reflection import Assembly
from System.Windows import Application
from System.Windows.Markup import XamlReader
executingAssemblyFileName = Assembly.GetEntryAssembly().Location
directory = Path.GetDirectoryName(executingAssemblyFileName)
xamlFileName = Path.Combine(directory, "Window1.xaml")
stream = FileStream(xamlFileName, FileMode.Open)
window = XamlReader.Load(stream)
app = Application()
app.Run(window)
SharpDevelop 3.2 does not embed resource files correctly so you will need to use SharpDevelop 4.
If you are using IronPython 2.7 you can use the new clr.LoadComponent method that takes an object and either a XAML filename or stream and wires up that object to the XAML.
Whilst the C# compiler can compile your XAML into a BAML resource doing the same with IronPython has a few problems. If you do not link the XAML to a class via the x:Class attribute then it is possible to compile the XAML into a BAML resource and have that embedded into your assembly. However you will not get any autogenerated code so you will need to create that code yourself. Another problem is that this will not work out of the box with SharpDevelop. You will need to edit the SharpDevelop.Build.Python.targets file and change the from Python to C#. Trying to use the x:Class attribute will not work since the BAML reader cannot access any associated IronPython class. This is because the generated IL in the compiled IronPython application is very different to that in a C# or VB.NET assembly.
I installed Visual Studio 2015 with PTVS (ironpython 2.7). I created a very simple WPF project and wasn't able to compile an exe. I always got the exception "ImportError: No module named wpf".
import clr
clr.AddReferenceToFileAndPath("c:\\path\\to\\IronPython.Wpf.dll")
clr.AddReferenceToFileAndPath('c:\\path\\to\\PresentationCore.dll')
clr.AddReferenceToFileAndPath('c:\\path\\to\\PresentationFramework.dll')
clr.AddReferenceToFileAndPath('c:\\path\\to\\WindowsBase.dll')
from System.Windows import Application, Window
import wpf
class MyWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'RegExTester.xaml')
def OnSearch(self, sender, e):
self.tbOut.Text = "hello world"
if __name__ == '__main__':
Application().Run(MyWindow())
The fault I got was because the clr clause must be before the import wpf. Steps to compile it:
install pip for CPython 2.7 (not ironpython!)
install ipy2asm
python -m pip install ironpycompiler
compile the application like
ipy2asm compile -t winexe -e -s program.py

py2exe fails to generate an executable

I am using python 2.6 on XP. I have just installed py2exe, and I can successfully create a simple hello.exe from a hello.py. However, when I try using py2exe on my real program, py2exe produces a few information messages but fails to generate anything in the dist folder.
My setup.py looks like this:
from distutils.core import setup
import py2exe
setup(console=['ServerManager.py'])
and the py2exe output looks like this:
python setup.py py2exe
running py2exe
creating C:\DevSource\Scripts\ServerManager\build
creating C:\DevSource\Scripts\ServerManager\build\bdist.win32
...
...
creating C:\DevSource\Scripts\ServerManager\dist
*** searching for required modules ***
*** parsing results ***
creating python loader for extension 'wx._misc_' (C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_misc_.pyd -> wx._misc_.pyd)
creating python loader for extension 'lxml.etree' (C:\Python26\lib\site-packages\lxml\etree.pyd -> lxml.etree.pyd)
...
...
creating python loader for extension 'bz2' (C:\Python26\DLLs\bz2.pyd -> bz2.pyd)
*** finding dlls needed ***
py2exe seems to have found all my imports (though I was a bit surprised to see win32 mentioned, as I am not explicitly importing it). Also, my program starts up quite happily with this command:
python ServerManager.py
Clearly I am doing something fundamentally wrong, but in the absence of any error messages from py2exe I have no idea what.
I put this in all my setup.py scripts:
distutils.core.setup(
options = {
"py2exe": {
"dll_excludes": ["MSVCP90.dll"]
}
},
...
)
This keeps py2exe quiet, but you still need to make sure that dll is on the user's machine.
I've discovered that py2exe works just fine if I comment out the part of my program that uses wxPython. Also, when I use py2exe on the 'simple' sample that comes with its download (i.e. in Python26\Lib\site-packages\py2exe\samples\simple), I get this error message:
*** finding dlls needed ***
error: MSVCP90.dll: No such file or directory
So something about wxPython makes py2exe think I need a Visual Studio 2008 DLL. I don't have VS2008, and yet my program works perfectly well as a directory of Python modules. I found a copy of MSVCP90.DLL on the web, installed it in Python26/DLLs, and py2exe now works fine.
I still don't understand where this dependency has come from, since I can run my code perfectly okay without py2exe. It's also annoying that py2exe didn't give me an error message like it did with the test_wx.py sample.
Further update: When I tried to run the output from py2exe on another PC, I discovered that it needed to have MSVCR90.DLL installed; so if your target PC hasn't got Visual C++ 2008 already installed, I recommend you download and install the Microsoft Visual C++ 2008 Redistributable Package.
wxPython has nothing to do with it. Before Python 2.6, Python used Visual Studio 2003 as their Windows compiler. Beginning with 2.6, they switched to Visual Studio 2008, which requires a manifest file in some situations. This has been well documented. See the following links:
http://wiki.wxpython.org/py2exe
http://py2exe.org/index.cgi/Tutorial#Step52
Also, if you're creating a wxPython application with py2exe, then you want to set the windows parameter, NOT the console one. Maybe my tutorial will help you:
http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/
It looks like this is only a dependency for Python 2.6. I wasn't getting this error under 2.5, but after the upgrade I am.
This email thread has some background for why the problem exists and how to fix it:
http://www.nabble.com/py2exe,-Py26,-wxPython-and-dll-td20556399.html
I didn't want to have to install the vcredist. My application currently requires no installation and can be run by non-administrators, which is behavior I don't want to lose. So I followed the suggestions in the links and got the necessary Microsoft.VC90.CRT.manifest and msvcr90.dll by installing Python "for this user only". I also needed msvcp90.dll that I found in the WinSxS folder of an "all users" Python 2.6 install. Since I already had two of the three, I included msvcm90.dll to prevent future errors though I didn't get any immediate errors when I left it out. I put the manifest and the three DLLs in the libs folder used by my frozen application.
The trick I had to perform was including an additional copy of the manifest and msvcr90.dll in the root of my application folder next to by py2exe generated executable. This copy of the DLL is used to bootstrap the application, but then it appears to only look in the libs folder.
Hopefully that discovery helps someone else out.
Also, I had the same problem with having py2exe log a real error message. Then I realized that stderr wasn't getting redirected into my log file. Add "> build.log 2>&1" on the command line where you invoke py2exe.
import sys
sys.path.append('C:\\WINDOWS\\WinSxS\\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2')
On each Windows, you can find the file MSVCP90.dll in some subdirectory in C:\\WINDOWS\\WinSxS\\
In my case, the directory was: x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2.
Go to C:\\WINDOWS\\WinSxS\\ and use windows file search to find MSVCP90.dll.
Just for your info, for me it worked to copy the files
Microsoft.VC90.CRT.manifest
msvcr90.dll
into the directory with the .exe on the user's machine (who has no python or VC redistributable installed).
Thanks for all the hints here!
The output says you're using WX. Try running py2exe with your script specified as a GUI app instead of console. If I'm not mistaken, that tends to cause problems with py2exe.
Try this: http://www.py2exe.org/index.cgi/Tutorial#Step52
It worked for me
There is some info on the wxPython wiki.
Deploy a Python app
py2exe with wxPython and Python 2.6
On my win8.1, I do not find the path
c:/Program Files/Microsoft Visual Studio 9.0/VC/redist/x86/Microsoft.VC90.CRT
On the contrary , the dll is found in
C:/WINDOWS/WinSxS/x86_Microsoft.VC90.CRT_XXXXXXX
The XXX may vary according to your PC
You may search in the path , then add the path in you setup.py
import sys
sys.path.append('C:/WINDOWS/WinSxS/x86_Microsoft.VC90.CRT_XXXXXXX')
import sys
sys.path.append('c:/Program Files/Microsoft Visual Studio 9.0/VC/redist/x86/Microsoft.VC90.CRT')

Categories