#!/bin/env /usr/bin/python HELP_STRING="""launch the Microsoft Visual C++ compiler / linker from a cygwin shell using 'cygwin-friendly' arguments. All paths are given as cygwin path. command line options are: --link : link instead of compile --vcdir=path : path to the ${VCINSTALLDIR}/bin folder (that contains the 32-bit cl.exe etc) -m32, -m64 : select 32-bit or 64-bit compilation -Ipath : add an include search path, with a path given as a cygwin path ( /c/path/to/stuff instead of c:\path\to\stuff ) -Lpath : add a path to the library search path -o : specify the output filename -llibname : add the library 'libname' to the link command -shared : build a dll --verbose : print the final command-line any other argument '-foo' or '--foo' is replaced by the '/foo' on the final command line Any .def file is correctly handled. """ import sys import getopt import subprocess import os from sys import stdout, stderr import ctypes # conversion between native windows path and cygwin paths cyg = ctypes.cdll.LoadLibrary("cygwin1.dll"); def cygwin_to_win32_path(path): path = path.strip() if len(path): dest=ctypes.create_string_buffer(4096); cyg.cygwin32_conv_to_win32_path(ctypes.c_char_p(path), dest); return dest.value else: return '' def win32_to_cygwin_path(s): path = s.strip() if len(s): dest=ctypes.create_string_buffer(4096); cyg.cygwin32_conv_to_posix_path(ctypes.c_char_p(path), dest); return dest.value return s def main(argv=None): if argv is None: argv = sys.argv if len(argv) < 2: print >> stderr, "missing arguments" print HELP_STRING return 0 argv = argv[1:] cmd = ['cl.exe'] vcdir = '' if (os.getenv('VCINSTALLDIR')): vcdir = win32_to_cygwin_path(os.getenv('VCINSTALLDIR')) + '/bin/' vcsubdir = '' linking = False verbose = False while len(argv): a = argv.pop(0).strip(); if len(a)==0: continue expect_filename = False a_cl = '' if (a.startswith('--help')): print HELP_STRING return 0 if (a.startswith('--link')): cmd[0] = 'link.exe' a_cl = '-nologo' linking = True elif a == '-m32': pass elif a == '-m64': vcsubdir = 'amd64/' elif (a.startswith('--vcdir=')): vcdir = a[8:] + '/' elif (a.startswith('-I')): a_cl = '/I' a = a[2:] expect_filename = True elif (a.startswith('-L')): a_cl = '/LIBPATH:' a = a[2:] expect_filename = True elif (a.startswith('-o')): if linking: a_cl = '/out:' else: a_cl = '/Fo' a = a[2:] expect_filename = True elif (a.startswith('-l')): a_cl = a[2:] + '.lib' elif (a.startswith('-shared')): a_cl = '/dll' elif (a == '-verbose'): verbose = True elif (a.startswith('--')): a_cl = '/' + a[2:] elif (a.startswith('-')): a_cl = '/' + a[1:] else: ext = os.path.splitext(a)[1] a_cl = cygwin_to_win32_path(a) if ext.lower() == '.def': a_cl = '/def:' + a_cl if expect_filename: fname = a.strip() if len(fname) == 0 and len(argv): fname = argv.pop(0).strip() a_cl += cygwin_to_win32_path(fname) if (len(a_cl)): cmd += [a_cl] cmd[0] = vcdir + vcsubdir + cmd[0] if verbose: print "running: ", ' '.join(cmd) ret=-1 try: ret = subprocess.Popen(cmd).wait() except OSError, e: print 'could not run command: ', cmd print ' error: ', e.strerror if ret: print 'cygmsvc failed, return code: ',ret return ret if __name__ == "__main__": sys.exit(main())