I recently got a trouble using python and MinGW under windows, MinGW was not understanding Python basics, and it was making me crying!!
Lets do a python module to automate python lib export. This is simply a fun stuff, not really needed.
Based on this article the problem is mostly linked to a version problem between python officials libs, and MinGW version.
We skip here most of problems to concentrate on the dll to lib problem, and, globally, how from a compiled module, we extract usable static library (in general, it’s not only related to my python problem).
Extract def file
Before getting the final a file, we need to extract the def file, this can be done using a MinGW tool called pexports, you can found it here. Take the bin version, as we need to run it, not to build it…
Extract the A file
From you def file, and your dll file, extracting the lib file is done using a MinGW command called dlltool. It’s this time directly included into MinGW, so I recommand you to install MinGW and make it available into PATH.
Now you have it, time to code.
The idea is to create a simple tool to automate build chain, even if it’s a simple one, we want to make a quick automation. Python is of course a language of choice for such system.
Time to code!
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys, os, subprocess, argparse try: from subprocess import DEVNULL # py3k except ImportError: import os DEVNULL = open(os.devnull, 'wb') _tmpFile = 'tmp.def' def dllToolExist(): ''' Check DDL Tool exist (from MinGW/GCC) ''' try: subprocess.call(['dlltool', '--version'], stdout=DEVNULL, stderr=DEVNULL) except OSError: print('DLLTool must be installed to run this script, please install GCC/MinGW, and setup path') sys.exit(1) def dllToolRun(input, output): ''' Create the final A file ''' p = subprocess.Popen(['dlltool', '--dllname', input, '--def', _tmpFile, '--output-lib', output], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while True: line = p.stdout.readline() if not line: break sys.stdout.write(line) def pExportsExist(): ''' Check the pExport Tool exist (from MinGW/GCC) ''' try: subprocess.call(['pexports', '-h', 'test'], stdout=DEVNULL, stderr=DEVNULL) except OSError: print('PSExports must be installed to run this script, download and install it please') sys.exit(1) def pExportsRun(input): ''' Create the DLL def file ''' f = open(_tmpFile, 'w') p = subprocess.Popen(['pexports', input], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while True: line = p.stdout.readline() if not line: break f.write(line) f.close() def convert(input, output): ''' Convert DLL file into A file ''' pExportsRun(input) dllToolRun(_tmpFile, output) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Convert a DLL file into A file description.') parser.add_argument('--dll', type=str, help='The DLL to extract data from') parser.add_argument('--output', type=str, help='The final A file name') args = parser.parse_args() if args.dll is None or args.output is None: parser.print_help() # Exiting sys.exit() # Checking programs are installed pExportsExist() dllToolExist() # processing convert(args.dll, args.output) # Deleting tmp file if os.path.isfile(_tmpFile): os.remove(_tmpFile)
The main idea is here to skip the def file, the automation take care of def file for you, directly creating the final lib file. It also provide some basic check to test if needed command exists in the usual PATH.
Also, I wanted to add a little help using argparse to make it more usable.
This time was a quick, but usefull tips! Cheers!