Skip to content

Commit

Permalink
latest.
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrejMitrovic committed Nov 23, 2011
1 parent ac0b94b commit 7455e3b
Show file tree
Hide file tree
Showing 4 changed files with 373 additions and 43 deletions.
236 changes: 236 additions & 0 deletions Linker.d
@@ -0,0 +1,236 @@
module xfbuild.Linker;

private
{
import xfbuild.GlobalParams;
import xfbuild.Module;
import xfbuild.Process;
import xfbuild.Misc;

import std.ascii : isAlpha;
import std.array;

//~ import tango.sys.Process;
//~ import tango.io.stream.Lines;
//~ import tango.stdc.ctype : isAlpha;
//~ import tango.text.Util : contains;
//~ import Array = tango.core.Array;

//~ // TODO: better logging
//~ import tango.io.Stdout;
}

/+private {
Regex linkerFileRegex;
}
static this() {
//defend\terrain\Generator.obj(Generator)
//linkerFileRegex = Regex(`([a-zA-Z0-9.:_\-\\/]+)\(.*\)`);
}+/

import std.string;

bool contains(string where, char what)
{
return where.indexOf(what) != -1;
}

bool isValidObjFileName(string f)
{
foreach (c; f)
{
if (!isAlpha(c) && !(`.:_-\/`.contains(c)))
{
return false;
}
}

return true;
}

bool contains(string[] haystack, string needle)
{
foreach (val; haystack)
{
if (val == needle)
return true;
}

return false;
}

bool link(ref Module[string] modules, string[] mainFiles = null)
{
bool retryCompile;

string[] args;
args ~= globalParams.compilerName;
args ~= globalParams.compilerOptions;

foreach (k; mainFiles)
{
foreach (m; modules)
{
if (m.path == k)
{
if (!m.isHeader)
args ~= m.objFile;

break;
}
}
}

foreach (k, m; modules)
{
if (m.isHeader || contains(mainFiles, m.path))
continue;

args ~= m.objFile;
}

args ~= "-of" ~ globalParams.outputFile;

if (!globalParams.recompileOnUndefinedReference)
{
executeCompilerViaResponseFile(
args[0],
args[1..$],
globalParams.linkerAffinityMask
);
}
else
{
//~ this(bool copyEnv, char[][] args...)
// copies environment variables
scope process = new Process(true, args);

// todo: use different execute, this one redirects to tango
execute(process);

string currentFile = null;
Module currentModule = null;

version (Windows)
{
auto procOut = process.stdout;
}
else
{
auto procOut = process.stderr;
}

// todo: this is basically redirect, we read from the process
// to see what it prints out. But we can do the same via
// system.
foreach (line; new Lines!(char)(procOut))
{
line = TextUtil.trim(line);

if (line.length > 0)
{
Stdout.formatln("linker: '{}'", line);
}

try
{
auto arr = line.decomposeString(cast(string)null, "(", null, ")");

//if(linkerFileRegex.test(line))
if (arr && isValidObjFileName(arr[1]))
{
//currentFile = linkerFileRegex[1];
currentFile = arr[1];

foreach (m; modules)
if (m.objFile == currentFile)
currentModule = m;

if (!currentModule && globalParams.verbose)
{
Stdout.formatln("{} doesn't belong to any known module", currentFile);
continue;
}

if (globalParams.verbose)
Stdout.formatln("linker error in file {} (module {})", currentFile, currentModule);
}
else if (/*undefinedReferenceRegex.test(line)*/ line.startsWith("Error 42:") && globalParams.recompileOnUndefinedReference)
{
if (globalParams.verbose)
{
if (!currentFile || !currentModule)
{
Stdout.formatln("no file.. wtf?");

//continue; // as i currently recompile every file anyway...
}

/*Stdout.formatln("undefined reference to {}, will try to recompile {}", undefinedReferenceRegex[1], currentModule);
currentModule.needRecompile = true;
retryCompile = true;*/

Stdout.formatln("undefined reference, will try teh full recompile :F");

foreach (m; modules)
m.needRecompile = true;

retryCompile = true;

break;
}
}
}
catch (Exception e)
{
if (currentFile && currentModule)
{
Stdout.formatln("{}", e);
Stdout.formatln("utf8 exception caught, assuming linker error in file {}", currentModule);

// orly!
foreach (m; modules)
m.needRecompile = true;

retryCompile = true;

break;
}
else
{
throw e;
}
}
}

try
{
// todo: replace with a system call? find one which returns 0,
// it's probably synchronous
checkProcessFail(process);
}
catch (Exception e)
{
version (Windows) {
// I don't know if Windows is affected too?
}
else
{
// DMD somehow puts some linker errors onto stdout :S
Stderr.copy(process.stdout).flush;
}

if (retryCompile && globalParams.verbose)
Stdout.formatln("ignoring linker error, will try to recompile");
else if (!retryCompile)
throw e; // rethrow exception since we're not going to retry what we did

}
}

globalParams.recompileOnUndefinedReference = false; // avoid infinite loop

return retryCompile;
}
105 changes: 105 additions & 0 deletions Linker.d.deps
@@ -0,0 +1,105 @@
binary D:\DMD\dmd2\windows\bin\dmd.exe
version v2.056
config D:\DMD\dmd2\windows\bin\sc.ini
parse Linker
importall Linker
import object (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\object.di)
import xfbuild.GlobalParams (..\xfbuild\GlobalParams.d)
import std.path (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\path.d)
import std.algorithm (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d)
import std.c.string (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\c\string.d)
import core.stdc.string (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\string.di)
import core.stdc.stddef (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\stddef.di)
import std.array (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\array.d)
import core.memory (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\memory.di)
import core.bitop (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\bitop.di)
import std.ascii (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\ascii.d)
import std.range (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\range.d)
import std.conv (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d)
import core.stdc.math (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\math.di)
import core.stdc.config (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\config.di)
import std.exception (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\exception.d)
import std.string (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\string.d)
import core.exception (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\exception.di)
import core.stdc.stdio (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\stdio.di)
import core.stdc.stdarg (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\stdarg.di)
import core.vararg (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\vararg.di)
import core.stdc.stdlib (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\stdlib.di)
import std.format (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d)
import std.bitmanip (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\bitmanip.d)
import std.traits (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\traits.d)
import std.typetuple (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\typetuple.d)
import std.typecons (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\typecons.d)
import std.metastrings (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\metastrings.d)
import std.stdio (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d)
import std.stdiobase (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdiobase.d)
import core.stdc.errno (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\errno.di)
import core.stdc.wchar_ (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\wchar_.di)
import core.stdc.time (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\time.di)
import core.stdc.stdint (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\stdint.di)
import core.stdc.signal (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\signal.di)
import std.file (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\file.d)
import std.datetime (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\datetime.d)
import core.time (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\time.di)
import core.sys.windows.windows (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\sys\windows\windows.di)
import std.functional (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\functional.d)
import std.math (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\math.d)
import std.system (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\system.d)
import std.c.windows.winsock (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\c\windows\winsock.d)
import std.stdint (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdint.d)
import std.c.windows.windows (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\c\windows\windows.d)
import std.windows.registry (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\windows\registry.d)
import std.windows.syserror (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\windows\syserror.d)
import std.windows.charset (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\windows\charset.d)
import std.utf (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\utf.d)
import std.__fileinit (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\__fileinit.d)
import std.internal.windows.advapi32 (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\internal\windows\advapi32.d)
import std.process (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\process.d)
import core.thread (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\thread.di)
import core.sync.mutex (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\sync\mutex.di)
import core.sync.exception (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\sync\exception.di)
import core.sys.windows.threadaux (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\sys\windows\threadaux.di)
import core.atomic (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\atomic.di)
import std.c.process (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\c\process.d)
import std.c.stddef (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\c\stddef.d)
import std.internal.processinit (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\internal\processinit.d)
import std.random (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\random.d)
import std.c.time (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\c\time.d)
import std.numeric (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\numeric.d)
import std.c.stdlib (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\c\stdlib.d)
import std.complex (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\complex.d)
import std.c.stdio (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\c\stdio.d)
import std.regex (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\regex.d)
import std.outbuffer (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\outbuffer.d)
import std.c.stdarg (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\c\stdarg.d)
import std.uni (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\uni.d)
import std.container (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\container.d)
import xfbuild.Module (..\xfbuild\Module.d)
import xfbuild.Misc (..\xfbuild\Misc.d)
import xfbuild.Process (..\xfbuild\Process.d)
import win32.windef (..\WindowsAPI\win32\windef.d)
import win32.winnt (..\WindowsAPI\win32\winnt.d)
import win32.basetsd (..\WindowsAPI\win32\basetsd.d)
import win32.winerror (..\WindowsAPI\win32\winerror.d)
import win32.w32api (..\WindowsAPI\win32\w32api.d)
import win32.basetyps (..\WindowsAPI\win32\basetyps.d)
import win32.winuser (..\WindowsAPI\win32\winuser.d)
import win32.winbase (..\WindowsAPI\win32\winbase.d)
import win32.winver (..\WindowsAPI\win32\winver.d)
import win32.wingdi (..\WindowsAPI\win32\wingdi.d)
import win32.winnls (..\WindowsAPI\win32\winnls.d)
import std.concurrency (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d)
import core.sync.barrier (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\sync\barrier.di)
import core.sync.condition (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\sync\condition.di)
import core.sync.semaphore (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\sync\semaphore.di)
import core.sync.rwmutex (D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\sync\rwmutex.di)
import std.variant (D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\variant.d)
semantic Linker
library advapi32.lib
library shell32.lib
library user32.lib
library kernel32.lib
library gdi32.lib
library kernel32.lib
semantic2 Linker
semantic3 Linker
5 changes: 1 addition & 4 deletions Module.d
Expand Up @@ -130,9 +130,6 @@ class Module
{
auto m = new Module;
m.path = path;
//~ m.timeModified = Path.modified(m.path).ticks;

// todo: not sure if correct
m.timeModified = timeLastModified(m.path).stdTime;

auto file = File(m.path, "r");
Expand All @@ -147,7 +144,7 @@ class Module
//m.name = moduleHeaderRegex[1].dup;
m.name = arr[0];

if (globalParams.verbose)
if (globalParams.verbose)
writefln("module name for file '%s': {}", path, m.name);

break;
Expand Down

0 comments on commit 7455e3b

Please sign in to comment.