From DLL to A file using python

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.

Principle

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.

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!

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :