# 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:
|