diff options
Diffstat (limited to 'compiler/extccomp.nim')
-rw-r--r-- | compiler/extccomp.nim | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index f3f74ece8..2fe151a1c 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -763,6 +763,32 @@ proc execCmdsInParallel(conf: ConfigRef; cmds: seq[string]; prettyCb: proc (idx: rawMessage(conf, errGenerated, "execution of an external program failed: '$1'" % cmds.join()) +proc linkViaResponseFile(conf: ConfigRef; cmd: string) = + # Extracting the linker.exe here is a bit hacky but the best solution + # given ``buildLib``'s design. + var i = 0 + var last = 0 + if cmd.len > 0 and cmd[0] == '"': + inc i + while i < cmd.len and cmd[i] != '"': inc i + last = i + inc i + else: + while i < cmd.len and cmd[i] != ' ': inc i + last = i + while i < cmd.len and cmd[i] == ' ': inc i + let linkerArgs = conf.projectName & "_" & "linkerArgs.txt" + let args = cmd.substr(i) + # GCC's response files don't support backslashes. Junk. + if conf.cCompiler == ccGcc: + writeFile(linkerArgs, args.replace('\\', '/')) + else: + writeFile(linkerArgs, args) + try: + execLinkCmd(conf, cmd.substr(0, last) & " @" & linkerArgs) + finally: + removeFile(linkerArgs) + proc callCCompiler*(conf: ConfigRef; projectfile: AbsoluteFile) = var linkCmd: string @@ -795,7 +821,13 @@ proc callCCompiler*(conf: ConfigRef; projectfile: AbsoluteFile) = linkCmd = getLinkCmd(conf, projectfile, objfiles) if optCompileOnly notin conf.globalOptions: - execLinkCmd(conf, linkCmd) + if defined(windows) and linkCmd.len > 8_000: + # Windows's command line limit is about 8K (don't laugh...) so C compilers on + # Windows support a feature where the command line can be passed via ``@linkcmd`` + # to them. + linkViaResponseFile(conf, linkCmd) + else: + execLinkCmd(conf, linkCmd) else: linkCmd = "" if optGenScript in conf.globalOptions: |