Changeset: ee2118ce3244 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ee2118ce3244 Modified Files: buildtools/autogen/autogen/msc.py buildtools/conf/wincompile.py Branch: default Log Message:
Fix compilation on Windows with the new all-in-one DLL for MonetDB5. When combining the various "NOINST" libraries into one big DLL, we need to actually use the constituent .obj files. We do that by processing the command line at the time of linking using a Python program that we call instead of the compiler. See the comments in the Python program for the exact rules. Also, since the command lines are becoming too large for nmake to handle, we use nmake-style "here" documents. diffs (121 lines): diff -r 711cc7e806c4 -r ee2118ce3244 buildtools/autogen/autogen/msc.py --- a/buildtools/autogen/autogen/msc.py Tue Dec 07 17:38:48 2010 +0100 +++ b/buildtools/autogen/autogen/msc.py Tue Dec 07 17:44:18 2010 +0100 @@ -642,8 +642,8 @@ SCRIPTS.append(target) fd.write(srcs + "\n") fd.write("%s.exe: $(%s_OBJS)\n" % (binname, binname2)) - fd.write('\t$(CC) $(CFLAGS)') - fd.write(" -Fe%s.exe $(%s_OBJS) /link $(%s_LIBS) /subsystem:console /NODEFAULTLIB:LIBC\n" % (binname, binname2, binname2)) + fd.write('\t"$(TOPDIR)\\..\\..\\buildtools\\conf\\wincompile.py" $(CC) $(CFLAGS)') + fd.write(" -Fe%s.exe $(%s_OBJS) /link @<<\n$(%s_LIBS) /subsystem:console /NODEFAULTLIB:LIBC\n<<\n" % (binname, binname2, binname2)) fd.write("\t$(EDITBIN) $@ /HEAP:1048576,1048576 /LARGEADDRESSAWARE\n"); fd.write("\tif exist $...@.manifest $(MT) -manifest $...@.manifest -outputresource:$@;1\n"); if condname: @@ -726,8 +726,8 @@ SCRIPTS.append(target) fd.write(srcs + "\n") fd.write("%s.exe: $(%s_OBJS)\n" % (bin, bin.replace('-','_'))) - fd.write('\t$(CC) $(CFLAGS)') - fd.write(" -Fe%s.exe $(%s_OBJS) /link $(%s_LIBS) /subsystem:console /NODEFAULTLIB:LIBC\n" % (bin, bin.replace('-','_'), bin.replace('-','_'))) + fd.write('\t"$(TOPDIR)\\..\\..\\buildtools\\conf\\wincompile.py" $(CC) $(CFLAGS)') + fd.write(" -Fe%s.exe $(%s_OBJS) /link @<<\n$(%s_LIBS) /subsystem:console /NODEFAULTLIB:LIBC\n<<\n" % (bin, bin.replace('-','_'), bin.replace('-','_'))) fd.write("\tif exist $...@.manifest $(MT) -manifest $...@.manifest -outputresource:$@;1\n\n"); if SCRIPTS: @@ -905,7 +905,7 @@ else: fd.write("%s.lib: %s%s\n" % (ln, ln, dll)) fd.write("%s%s: $(%s_DEPS) \n" % (ln, dll, ln.replace('-','_'))) - fd.write("\t$(CC) $(CFLAGS) -LD -Fe%s%s $(%s_OBJS) /link $(%s_LIBS)%s\n" % (ln, dll, ln.replace('-','_'), ln.replace('-','_'), deffile)) + fd.write('\t"$(TOPDIR)\\..\\..\\buildtools\\conf\\wincompile.py" $(CC) $(CFLAGS) -LD -Fe%s%s $(%s_OBJS) /link @<<\n$(%s_LIBS)%s\n<<\n' % (ln, dll, ln.replace('-','_'), ln.replace('-','_'), deffile)) fd.write("\tif exist $...@.manifest $(MT) -manifest $...@.manifest -outputresource:$@;2\n"); if sep == '_': fd.write('\tif not exist .libs $(MKDIR) .libs\n') @@ -993,7 +993,7 @@ ln = "lib" + sep + libname fd.write(ln + ".lib: " + ln + ".dll\n") fd.write(ln + ".dll: $(" + ln.replace('-','_') + "_DEPS)\n") - fd.write("\t$(CC) $(CFLAGS) -LD -Fe%s.dll $(%s_OBJS) /link $(%s_LIBS)%s\n" % (ln, ln.replace('-','_'), ln.replace('-','_'), deffile)) + fd.write('\t"$(TOPDIR)\\..\\..\\buildtools\\conf\\wincompile.py" $(CC) $(CFLAGS) -LD -Fe%s.dll $(%s_OBJS) /link @<<\n$(%s_LIBS)%s\n<<\n' % (ln, ln.replace('-','_'), ln.replace('-','_'), deffile)) fd.write("\tif exist $...@.manifest $(MT) -manifest $...@.manifest -outputresource:$@;2\n"); if sep == '_': fd.write('\tif not exist .libs $(MKDIR) .libs\n') diff -r 711cc7e806c4 -r ee2118ce3244 buildtools/conf/wincompile.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/buildtools/conf/wincompile.py Tue Dec 07 17:44:18 2010 +0100 @@ -0,0 +1,74 @@ +import sys +import os +import subprocess +import string + +# This script just calls the compiler (first argument) with the given +# arguments (following arguments), except that it replaces references +# to .LIB files that do not refer to shared libraries with a list of +# references to the .OBJ files inside those .LIB files. .LIB files +# are recognized as not referring to shared libraries (.DLL files) if +# 1. the path to the file is not absolute; 2. the .LIB file exists +# (i.e. the compiler wouldn't need some search path to find it); and +# 3. there is no .DLL file in the same location as the .LIB file. +# This trick makes that the NOINST libraries that are specified in +# various Makefile.ag files are included completely, instead of just +# the files from those libraries that contain functions that happen to +# be referenced somewhere. + +# the splitcommand function is a straight copy of the same function in +# ../../testing/src/process.py. +def splitcommand(cmd): + '''Like string.split, except take quotes into account.''' + q = None + w = [] + command = [] + for c in cmd: + if q: + if c == q: + q = None + else: + w.append(c) + elif c in string.whitespace: + if w: + command.append(''.join(w)) + w = [] + elif c == '"' or c == "'": + q = c + else: + w.append(c) + if w: + command.append(''.join(w)) + if len(command) > 1 and command[0] == 'call': + del command[0] + return command + +def process(args, recursive = False): + argv = [] + for arg in args: + if not recursive and arg[:1] == '@': + argv.extend(process(splitcommand(open(arg[1:]).read()), True)) + elif arg[:1] in ('-', '/'): + argv.append(arg) + elif arg.endswith('.lib'): + if os.path.isabs(arg) or not os.path.exists(arg) or os.path.exists(arg[:-4] + '.dll'): + argv.append(arg) + else: + dirname = os.path.dirname(arg) + p = subprocess.Popen(['lib', '/nologo', '/list', arg], + shell = False, + stdout = subprocess.PIPE) + for f in p.stdout: + argv.append(os.path.join(dirname, f.strip())) + p.wait() + else: + argv.append(arg) + return argv + +argv = process(sys.argv[1:]) + +p = subprocess.Popen(argv, shell = False, stdout = subprocess.PIPE, stderr = subprocess.PIPE) +out, err = p.communicate() +sys.stdout.write(out.replace('\r\n', '\n')) +sys.stderr.write(err.replace('\r\n', '\n')) +sys.exit(p.returncode) _______________________________________________ Checkin-list mailing list Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list