File: mingw.py

package info (click to toggle)
aap 1.072-1.1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny
  • size: 4,976 kB
  • ctags: 2,160
  • sloc: python: 15,113; makefile: 62; sh: 13
file content (228 lines) | stat: -rw-r--r-- 8,867 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# Part of the A-A-P recipe executive: Setup using MingW

# Copyright (c) 2002-2003 stichting NLnet Labs
# Permission to copy and use this file is specified in the file COPYING.
# If this file is missing you can find it here: http://www.a-a-p.org/COPYING

"""mingw.py

This module sets up variables and actions for using the MingW compiler tools.

The following variables are used to find the tools.

 - MINGPREFIX  - prefix of tool names.  For example, if this is set to 
                 "mingw32-", the tool will look for a C compiler called
                 "mingw32-gcc".  The default is to try various prefixes until
                 the gcc tool is found.
 - MINGCC      - name, or full path, of the MingW C compiler.  The default
                 is $(MINGW_PREFIX)gcc
 - MINGCXX     - name, or full path, of the MingW C++ compiler.  The default
                 is $(MINGW_PREFIX)g++
 - MINGAR      - name, or full path, of the MingW version of ar.  The default
                 is $(MINGW_PREFIX)ar
 - MINGRANLIB  - name, or full path, of the MingW version of ranlib.  The
                 default is $(MINGW_PREFIX)ranlib
 - MINGDLLTOOL - name, or full path, of the MingW version of dlltool.
                 The default is $(MINGW_PREFIX)dlltool
"""

from RecPython import *
import Global
from Action import action_add
from Dictlist import str2dictlist
from RecPos import RecPos

def _guess_prefix():
    """
    Guess the prefix of the tools in the MingW toolchain, by testing for the
    existence of the "gcc" tool at a predefined set of locations.
    If the MINGPREFIX variable is set, simply returns its value.
    If MINGCC is set, tries to guess the prefix from its value.
    If MINGCXX is set, tries to guess the prefix from its value.

    In addition, the following prefixes are tried (in order):

     - "mingw32-" (XXX - where is this used - was in old version of this file)
     - "i586-mingw32msvc-gcc-" (Used for the mingw cross compiler on Debian.)
     - "" (This is tested last, since if mingw is installed as a cross
           compiler, there may well be a non-mingw gcc installed.)

    If the gcc tool cannot be found at any of the prefixes, returns None.
    If the gcc tool is found, returns a list of prefixes at which it is found.
    """
    rd = Global.globals
    prefix = rd.get("MINGPREFIX")
    if prefix:
        # If MINGPREFIX is set, try it (and only it)
        prefixes = [ prefix ]
    else:
        # Standard set of prefixes to try
        # An entry should be added to this list whenever a user complains
        # about mingw not being found on their system.  The list in the
        # documentation about should be kept in sync, and explanations of the
        # situtation the prefix is used in should also be added.
        prefixes = [ "mingw32-", "i586-mingw32msvc-", "" ]

        # If MINGCC is set, try to extract the prefix from that
        path = rd.get("MINGCC")
        if path:
            if path.endswith("gcc"):
                prefixes = [ path[:-3] ] + prefixes

        # If MINGCXX is set, try to extract the prefix from that
        path = rd.get("MINGCXX")
        if path:
            if path.endswith("g++"):
                prefixes = [ path[:-3] ] + prefixes

    # Check if a 'gcc' exists at any of the possible prefixes
    results = []
    for prefix in prefixes:
        name = prefix + 'gcc'
        if program_path(name):
            results.append(prefix)

    # No mingw found
    if len(results) == 0:
        return None
    return results

def exists():
    """
    Return TRUE when the MingW toolchain can be found.
    This will look for the gcc tool at MINGPREFIX if it is set.
    Otherwise, it will try to guess the prefix from the MINGCC and MINGCXX
    variables and also look through predefined set of possible paths.
    If it finds a suitable candidate, it will then check that the tool
    actually is the mingw compiler by running it with the --version argument
    and checking for the existence of the string "mingw" (case insensitively)
    in the output.
    """
    rd = Global.globals
    msg_log(rd, "Checking for MingW")

    # Check if we can find an appropriate prefix
    prefixes = _guess_prefix()
    if prefixes == None:
        msg_log(rd, "No mingw compiler found")
        return None

    for prefix in prefixes:
        msg_log(rd, "Guessing MingW prefix as '%s'" % prefix)

        # See if there is a gcc at the guessed prefix
        path = program_path(prefix + 'gcc')
        if not path:
            continue

        # Add double quotes if the name contains a space.
        if " " in path:
            prog = '"%s"' % path
        else:
            prog = path

        # Run gcc with --version to see if it really is MingW
        ok, out = redir_system(prog + ' --version', 0)
        if not ok:
            msg_log(rd, "%s returned error code" % path)
            continue
        import string, re
        firstline = string.split(out, "\n", 1)[0]
        if not re.search("mingw", firstline, re.IGNORECASE):
            msg_log(rd, "%s doesn't look like MingW compiler" % path)
            msg_log(rd, "version line: %s" % firstline)
            continue

        msg_log(rd, "MingW compiler found at '%s'" % path)

        # Remember the prefix for define_actions
        rd["MINGPREFIX"] = prefix
        return 1

    return None


def define_actions():
    """
    Define the actions that MingW can accomplish.
    """
    rd = Global.globals
    prefix = rd.get("MINGPREFIX")
    if prefix == None:
        # Just in case someone's cleared the variable since :usetool mingw
        prefix = ""
    if not rd.get("MINGCC"):
        rd["MINGCC"] = prefix + "gcc"
    if not rd.get("MINGCXX"):
        rd["MINGCXX"] = prefix + "g++"
    if not rd.get("MINGAR"):
        rd["MINGAR"] = prefix + "ar"
    if not rd.get("MINGRANLIB"):
        rd["MINGRANLIB"] = prefix + "ranlib"
    if not rd.get("MINGDLLTOOL"):
        rd["MINGDLLTOOL"] = prefix + "dlltool"

    # Must set the prefixes to the values used on windows
    rd["OBJSUF"] = ".obj"
    rd["LIBOBJSUF"] = ".obj"
    rd["DLLOBJSUF"] = ".sob"
    rd["EXESUF"] = ".exe"
    rd["LIBPRE"] = ""
    rd["LIBSUF"] = ".lib"
    rd["DLLPRE"] = ""
    rd["DLLSUF"] = ".dll"
    rd["LNKSUF"] = ""

    # dllobjects don't need to be compiled differently with mingw: -fPIC
    # has no effect (other than to display a warning message).
    rpstack = [ RecPos("compile_mingw_c action") ]
    action_add(rpstack, rd, str2dictlist(rpstack, "compile_mingw_c object,libobject,dllobject c"),
            ":buildcheck $OPTIMIZE $?DEBUG\n"
            ":sys $MINGCC $CPPFLAGS $?DEFINE $?INCLUDE `cflags_normal()` "
                "$CFLAGS -o $target -c $source")

    rpstack = [ RecPos("compile_mingw_cxx action") ]
    action_add(rpstack, rd, str2dictlist(rpstack, "compile_mingw_cxx object,libobject,dllobject cpp"),
            ":buildcheck $OPTIMIZE $?DEBUG\n"
            ":sys $MINGCXX $CPPFLAGS $?DEFINE $?INCLUDE `cflags_normal()` "
                "$CXXFLAGS -o $target -c $source")

    rpstack = [ RecPos("build_mingw_c action") ]
    action_add(rpstack, rd, str2dictlist(rpstack, "build_mingw_c object,dllobject,libobject"),
            ":sys $MINGCC $?LDFLAGS `cflags_normal()` -o $target $source $?LIBS")

    rpstack = [ RecPos("build_mingw_cxx action") ]
    action_add(rpstack, rd, str2dictlist(rpstack, "build_mingw_cxx object,dllobject,libobject"),
            ":sys $MINGCXX $?LDFLAGS `cflags_normal()` -o $target $source $?LIBS")

    rpstack = [ RecPos("build_mingw_lib action") ]
    action_add(rpstack, rd, str2dictlist(rpstack, "build_mingw_lib default"),
            ":sys $MINGAR $ARFLAGS $target $source\n"
            ":sys $MINGRANLIB $?RANLIBFLAGS $target")

    # building a .dll also produces a .lib and a _exports.o
    # FIXME - should this be reflected in the dependencies?
    rpstack = [ RecPos("build_mingw_dll action") ]
    action_add(rpstack, rd, str2dictlist(rpstack, "build_mingw_dll default"),
            "dllexports = `sufreplace('', '_exports.o', target)` \n"
            "dlllib = `sufreplace('', '.lib', target)` \n"
            ":sys $MINGDLLTOOL -e $dllexports -l $dlllib $source\n"
            ":sys $MINGCC -shared $?LDFLAGS `cflags_normal()` -o $target $dllexports $source $?LIBS")


def use_actions(scope):
    """
    Setup variables so that the default actions use the MingW actions.
    """
    scope["C_COMPILE_ACTION"] = "compile_mingw_c"
    scope["CXX_COMPILE_ACTION"] = "compile_mingw_cxx"
    scope["C_BUILD_ACTION"] = "build_mingw_c"
    scope["CXX_BUILD_ACTION"] = "build_mingw_cxx"
    scope["BUILDLIB_ACTION"] = "build_mingw_lib"
    scope["BUILDDLL_ACTION"] = "build_mingw_dll"

    # Attempt using gcc for dependency checks.
    scope["HASGCC"] = ""
    scope["HASGCCXX"] = ""

# vim: set sw=4 et sts=4 tw=79 fo+=l: