winmakemakefile.py 4.86 KB
Newer Older
1
import sys, os
2

3
# Template used then the program is a GUI program
4 5 6 7 8 9 10 11 12 13
WINMAINTEMPLATE = """
#include <windows.h>

int WINAPI WinMain(
    HINSTANCE hInstance,      // handle to current instance
    HINSTANCE hPrevInstance,  // handle to previous instance
    LPSTR lpCmdLine,          // pointer to command line
    int nCmdShow              // show state of window
    )
{
Guido van Rossum's avatar
Guido van Rossum committed
14
    extern int Py_FrozenMain(int, char **);
15 16
    PyImport_FrozenModules = _PyImport_FrozenModules;
    return Py_FrozenMain(__argc, __argv);
17 18 19
}
"""

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
SERVICETEMPLATE = """
extern int PythonService_main(int, char **);

int main( int argc, char **argv)
{
    PyImport_FrozenModules = _PyImport_FrozenModules;
    return PythonService_main(argc, argv);
}
"""

subsystem_details = {
    # -s flag        : (C entry point template), (is it __main__?), (is it a DLL?)
    'console'        : (None,                    1,                 0),
    'windows'        : (WINMAINTEMPLATE,         1,                 0),
    'service'        : (SERVICETEMPLATE,         0,                 0),
    'com_dll'        : ("",                      0,                 1),
}

def get_custom_entry_point(subsystem):
    try:
        return subsystem_details[subsystem][:2]
    except KeyError:
42
        raise ValueError("The subsystem %s is not known" % subsystem)
43 44


45 46 47 48 49 50 51 52
def makemakefile(outfp, vars, files, target):
    save = sys.stdout
    try:
        sys.stdout = outfp
        realwork(vars, files, target)
    finally:
        sys.stdout = save

53
def realwork(vars, moddefns, target):
54
    version_suffix = "%r%r" % sys.version_info[:2]
Guido van Rossum's avatar
Guido van Rossum committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    print("# Makefile for Microsoft Visual C++ generated by freeze.py script")
    print()
    print('target = %s' % target)
    print('pythonhome = %s' % vars['prefix'])
    print()
    print('DEBUG=0 # Set to 1 to use the _d versions of Python.')
    print('!IF $(DEBUG)')
    print('debug_suffix=_d')
    print('c_debug=/Zi /Od /DDEBUG /D_DEBUG')
    print('l_debug=/DEBUG')
    print('temp_dir=Build\\Debug')
    print('!ELSE')
    print('debug_suffix=')
    print('c_debug=/Ox')
    print('l_debug=')
    print('temp_dir=Build\\Release')
    print('!ENDIF')
    print()

    print('# The following line assumes you have built Python using the standard instructions')
    print('# Otherwise fix the following line to point to the library.')
    print('pythonlib = "$(pythonhome)/pcbuild/python%s$(debug_suffix).lib"' % version_suffix)
    print()
78 79 80 81 82 83 84 85 86 87 88 89

    # We only ever write one "entry point" symbol - either
    # "main" or "WinMain".  Therefore, there is no need to
    # pass a subsystem switch to the linker as it works it
    # out all by itself.  However, the subsystem _does_ determine
    # the file extension and additional linker flags.
    target_link_flags = ""
    target_ext = ".exe"
    if subsystem_details[vars['subsystem']][2]:
        target_link_flags = "-dll"
        target_ext = ".dll"

90

Guido van Rossum's avatar
Guido van Rossum committed
91 92 93 94 95
    print("# As the target uses Python%s.dll, we must use this compiler option!" % version_suffix)
    print("cdl = /MD")
    print()
    print("all: $(target)$(debug_suffix)%s" % (target_ext))
    print()
96

Guido van Rossum's avatar
Guido van Rossum committed
97 98 99
    print('$(temp_dir):')
    print('  if not exist $(temp_dir)\. mkdir $(temp_dir)')
    print()
100 101

    objects = []
102
    libs = ["shell32.lib", "comdlg32.lib", "wsock32.lib", "user32.lib", "oleaut32.lib"]
103
    for moddefn in moddefns:
Guido van Rossum's avatar
Guido van Rossum committed
104
        print("# Module", moddefn.name)
105 106 107 108
        for file in moddefn.sourceFiles:
            base = os.path.basename(file)
            base, ext = os.path.splitext(base)
            objects.append(base + ".obj")
Guido van Rossum's avatar
Guido van Rossum committed
109 110 111 112
            print('$(temp_dir)\%s.obj: "%s"' % (base, file))
            print("\t@$(CC) -c -nologo /Fo$* $(cdl) $(c_debug) /D BUILD_FREEZE", end=' ')
            print('"-I$(pythonhome)/Include"  "-I$(pythonhome)/PC" \\')
            print("\t\t$(cflags) $(cdebug) $(cinclude) \\")
113 114
            extra = moddefn.GetCompilerOptions()
            if extra:
Guido van Rossum's avatar
Guido van Rossum committed
115 116 117
                print("\t\t%s \\" % (' '.join(extra),))
            print('\t\t"%s"' % file)
            print()
118 119 120 121 122 123

        # Add .lib files this module needs
        for modlib in moddefn.GetLinkerLibs():
            if modlib not in libs:
                libs.append(modlib)

Guido van Rossum's avatar
Guido van Rossum committed
124 125 126 127 128 129 130 131 132 133 134 135 136
    print("ADDN_LINK_FILES=", end=' ')
    for addn in vars['addn_link']: print('"%s"' % (addn), end=' ')
    print() ; print()

    print("OBJS=", end=' ')
    for obj in objects: print('"$(temp_dir)\%s"' % (obj), end=' ')
    print() ; print()

    print("LIBS=", end=' ')
    for lib in libs: print('"%s"' % (lib), end=' ')
    print() ; print()

    print("$(target)$(debug_suffix)%s: $(temp_dir) $(OBJS)" % (target_ext))
137 138 139 140 141 142
    print("\tlink -out:$(target)$(debug_suffix)%s %s" %
          (target_ext, target_link_flags), "@<<")
    print("\t$(OBJS)")
    print("\t$(LIBS)")
    print("\t$(ADDN_LINK_FILES)")
    print("\t$(pythonlib) $(lcustom) $(l_debug)")
Guido van Rossum's avatar
Guido van Rossum committed
143
    print("\t$(resources)")
144
    print("<<")
Guido van Rossum's avatar
Guido van Rossum committed
145 146 147 148
    print()
    print("clean:")
    print("\t-rm -f *.obj")
    print("\t-rm -f $(target).exe")