From 055b6e5710e0c2d44d0ee4c5ad7c53454cdf6126 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 21 Feb 2012 16:06:07 +0000 Subject: [PATCH] Fixed issues compiling with MinGW using SCons --- SConstruct | 49 +++++++++++++----- ext/f2c_libs/s_paus.c | 107 --------------------------------------- site_scons/buildutils.py | 46 +++++++++++++++++ src/SConscript | 6 ++- src/python/SConscript | 11 +++- 5 files changed, 95 insertions(+), 124 deletions(-) delete mode 100644 ext/f2c_libs/s_paus.c diff --git a/SConstruct b/SConstruct index 2263b1ed3..46d64e4b8 100644 --- a/SConstruct +++ b/SConstruct @@ -71,24 +71,46 @@ if os.name == 'nt': else: target_arch = 'x86' - opts.AddVariables(('msvc_version', - """Version of Visual Studio to use. The default - is the same version that was used to compile - the installed version of Python.""", - msvc_version), - ('target_arch', - """Target architecture. The default is the same - architecture as the installed version of Python""", - target_arch)) + opts.AddVariables( + ('msvc_version', + """Version of Visual Studio to use. The default + is the same version that was used to compile + the installed version of Python.""", + msvc_version), + ('target_arch', + """Target architecture. The default is the same + architecture as the installed version of Python""", + target_arch), + EnumVariable( + 'toolchain', + """The preferred compiler toolchain.""", + 'msvc', ('msvc', 'mingw', 'intel'))) pickCompilerEnv = Environment() opts.Update(pickCompilerEnv) - if msvc_version: - extraEnvArgs['MSVC_VERSION'] = pickCompilerEnv['msvc_version'] + + if pickCompilerEnv['toolchain'] == 'msvc': + toolchain = ['default'] + if msvc_version: + extraEnvArgs['MSVC_VERSION'] = pickCompilerEnv['msvc_version'] + + elif pickCompilerEnv['toolchain'] == 'mingw': + toolchain = ['mingw'] + extraEnvArgs['F77'] = None + # Next line fixes http://scons.tigris.org/issues/show_bug.cgi?id=2683 + extraEnvArgs['WINDOWS_INSERT_DEF'] = 1 + + elif pickCompilerEnv['toolchain'] == 'intel': + toolchain = ['intelc'] # note: untested + extraEnvArgs['TARGET_ARCH'] = pickCompilerEnv['target_arch'] -env = Environment(tools=['default', 'textfile', 'subst', 'recursiveInstall', 'wix'], +else: + toolchain = ['default'] + +env = Environment(tools=toolchain+['textfile', 'subst', 'recursiveInstall', 'wix'], ENV={'PATH': os.environ['PATH']}, + toolchain=toolchain, **extraEnvArgs) # Fixes a linker error in Windows @@ -860,8 +882,7 @@ sampleTargets = [] env.SConsignFile() -env.Append(CPPPATH=[Dir('build/include/cantera'), - Dir('build/include')], +env.Append(CPPPATH=[], LIBPATH=[Dir('build/lib')], CCFLAGS=[defaults.fPIC], FORTRANFLAGS=[defaults.fPIC], diff --git a/ext/f2c_libs/s_paus.c b/ext/f2c_libs/s_paus.c deleted file mode 100644 index c2217b7b2..000000000 --- a/ext/f2c_libs/s_paus.c +++ /dev/null @@ -1,107 +0,0 @@ -#include "stdio.h" -#include "f2c.h" -#define PAUSESIG 15 - -#include "signal1.h" -#ifdef KR_headers -#define Void /* void */ -#define Int /* int */ -#else -#define Void void -#define Int int -#undef abs -#undef min -#undef max -#include "stdlib.h" -#ifdef __cplusplus -extern "C" { -#endif -#ifdef __cplusplus -extern "C" { -#endif -extern int getpid(void); -#ifndef _WIN32 -extern int isatty(int); -#endif -#ifdef _MSC_VER -#define ISATTY _isatty -#define FILENO _fileno -#else -#define ISATTY isatty -#define FILENO fileno -#endif -extern int pause(void); -#endif - -extern VOID f_exit(Void); - -#ifndef MSDOS - static VOID -waitpause(Sigarg) -{ Use_Sigarg; - return; - } -#endif - - static VOID -#ifdef KR_headers -s_1paus(fin) FILE *fin; -#else -s_1paus(FILE *fin) -#endif -{ - fprintf(stderr, - "To resume execution, type go. Other input will terminate the job.\n"); - fflush(stderr); - if( getc(fin)!='g' || getc(fin)!='o' || getc(fin)!='\n' ) { - fprintf(stderr, "STOP\n"); -#ifdef NO_ONEXIT - f_exit(); -#endif - exit(0); - } - } - - int -#ifdef KR_headers -s_paus(s, n) char *s; ftnlen n; -#else -s_paus(char *s, ftnlen n) -#endif -{ - fprintf(stderr, "PAUSE "); - if(n > 0) - fprintf(stderr, " %.*s", (int)n, s); - fprintf(stderr, " statement executed\n"); - if( ISATTY(FILENO(stdin)) ) - s_1paus(stdin); - else { -#ifdef MSDOS - FILE *fin; - fin = fopen("con", "r"); - if (!fin) { - fprintf(stderr, "s_paus: can't open con!\n"); - fflush(stderr); - exit(1); - } - s_1paus(fin); - fclose(fin); -#else - fprintf(stderr, - "To resume execution, execute a kill -%d %d command\n", - PAUSESIG, getpid() ); - signal1(PAUSESIG, waitpause); - fflush(stderr); - pause(); -#endif - } - fprintf(stderr, "Execution resumes after PAUSE.\n"); - fflush(stderr); - return 0; /* NOT REACHED */ -#ifdef __cplusplus - } -#endif -} -#ifdef __cplusplus -} -#endif diff --git a/site_scons/buildutils.py b/site_scons/buildutils.py index cd6b0d685..1a4d21dcf 100644 --- a/site_scons/buildutils.py +++ b/site_scons/buildutils.py @@ -477,3 +477,49 @@ def ipdb(): ip = ipapi.get() def_colors = ip.colors Pdb(def_colors).set_trace(sys._getframe().f_back) + + +def getSpawn(env): + """ + A replacement for env['SPAWN'] on Windows that can deal with very long + commands, namely those generated when linking. This is only used when + compiling with MinGW, as SCons automatically uses a tempfile for the + MSVC link command. + + Pass the return value of this function as the SPAWN keyword argument to + the Library target, e.g.: + + env.SharedLibrary(..., SPAWN=getSpawn(env)) + + Adapted from http://www.scons.org/wiki/LongCmdLinesOnWin32 + """ + + if sys.platform != 'win32' or env['toolchain'] != 'mingw': + return env['SPAWN'] + + try: + useShowWindow = subprocess.STARTF_USESHOWWINDOW + except AttributeError: + useShowWindow = subprocess._subprocess.STARTF_USESHOWWINDOW + + def ourSpawn(sh, escape, cmd, args, environ): + newargs = ' '.join(args[1:]) + cmdline = cmd + " " + newargs + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= useShowWindow + proc = subprocess.Popen(cmdline, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + startupinfo=startupinfo, + shell=False, + env=environ) + data, err = proc.communicate() + rv = proc.wait() + if rv: + print "=====" + print err + print "=====" + return rv + + return ourSpawn diff --git a/src/SConscript b/src/SConscript index 3721ea2c2..23c9ed671 100644 --- a/src/SConscript +++ b/src/SConscript @@ -49,14 +49,16 @@ for subdir, extensions, setup in libs: # build the Cantera static library localenv = env.Clone() -lib = localenv.StaticLibrary('../lib/cantera', libraryTargets) +lib = localenv.StaticLibrary('../lib/cantera', libraryTargets, + SPAWN=getSpawn(localenv)) localenv.Depends(lib, localenv['config_h_target']) inst = localenv.Install('$inst_libdir', lib) buildTargets.extend(lib) installTargets.extend(inst) # Build the Cantera shared library -lib = localenv.SharedLibrary('../lib/cantera_shared', libraryTargets) +lib = localenv.SharedLibrary('../lib/cantera_shared', libraryTargets, + SPAWN=getSpawn(localenv)) env['cantera_shlib'] = lib localenv.Depends(lib, localenv['config_h_target']) inst = localenv.Install('$inst_libdir', lib) diff --git a/src/python/SConscript b/src/python/SConscript index 6036e8e6e..08d826a85 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -27,9 +27,18 @@ if localenv['python_package'] == 'full': localenv.Append(CPPPATH=['#src', '#include']) cantera_libname = 'cantera_shared' if os.name=='nt' else 'cantera' + pylinklibs = [cantera_libname] + + # On Windows, we need to link against the Python "import" library. + # With MSVC, this is automatically handled by a "#pragma comment + # directive in the Python headers, but for MinGW we need to do + # it manually. + if localenv['toolchain'] == 'mingw': + pylinklibs.append('python%s' % gcv('VERSION')) + pymodule = localenv.SharedLibrary('#interfaces/python/Cantera/_cantera', ['pycantera.cpp'], - LIBS=[cantera_libname], + LIBS=pylinklibs, SHLIBPREFIX='', SHLIBSUFFIX=gcv('SO')) buildTargets.extend(pymodule)