Merge branch 'bigbreak' of https://github.com/Araq/Nimrod into bigbreak

This commit is contained in:
Araq
2014-11-03 12:01:07 +01:00
7 changed files with 104 additions and 35 deletions

View File

@@ -7,8 +7,10 @@
# distribution, for details about the copyright.
#
# module for calling the different external C compilers
# some things are read in from the configuration file
# Module providing functions for calling the different external C compilers
# Uses some hard-wired facts about each C/C++ compiler, plus options read
# from a configuration file, to provide generalized procedures to compile
# nim files.
import
lists, ropes, os, strutils, osproc, platform, condsyms, options, msgs, crc
@@ -59,6 +61,7 @@ type
template compiler(name: expr, settings: stmt): stmt {.immediate.} =
proc name: TInfoCC {.compileTime.} = settings
# GNU C and C++ Compiler
compiler gcc:
result = (
name: "gcc",
@@ -84,21 +87,24 @@ compiler gcc:
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
hasNakedAttribute})
# LLVM Frontend for GCC/G++
compiler llvmGcc:
result = gcc()
result = gcc() # Uses settings from GCC
result.name = "llvm_gcc"
result.compilerExe = "llvm-gcc"
result.cppCompiler = "llvm-g++"
result.buildLib = "llvm-ar rcs $libfile $objfiles"
# Clang (LLVM) C/C++ Compiler
compiler clang:
result = llvmGcc()
result = llvmGcc() # Uses settings from llvmGcc
result.name = "clang"
result.compilerExe = "clang"
result.cppCompiler = "clang++"
# Microsoft Visual C/C++ Compiler
compiler vcc:
result = (
name: "vcc",
@@ -123,6 +129,7 @@ compiler vcc:
packedPragma: "#pragma pack(1)",
props: {hasCpp, hasAssume, hasNakedDeclspec})
# Intel C/C++ Compiler
compiler icl:
# Intel compilers try to imitate the native ones (gcc and msvc)
when defined(windows):
@@ -134,6 +141,7 @@ compiler icl:
result.compilerExe = "icl"
result.linkerExe = "icl"
# Local C Compiler
compiler lcc:
result = (
name: "lcc",
@@ -158,6 +166,7 @@ compiler lcc:
packedPragma: "", # XXX: not supported yet
props: {})
# Borland C Compiler
compiler bcc:
result = (
name: "bcc",
@@ -182,6 +191,7 @@ compiler bcc:
packedPragma: "", # XXX: not supported yet
props: {hasCpp})
# Digital Mars C Compiler
compiler dmc:
result = (
name: "dmc",
@@ -206,6 +216,7 @@ compiler dmc:
packedPragma: "#pragma pack(1)",
props: {hasCpp})
# Watcom C Compiler
compiler wcc:
result = (
name: "wcc",
@@ -230,6 +241,7 @@ compiler wcc:
packedPragma: "", # XXX: not supported yet
props: {hasCpp})
# Tiny C Compiler
compiler tcc:
result = (
name: "tcc",
@@ -254,6 +266,7 @@ compiler tcc:
packedPragma: "", # XXX: not supported yet
props: {hasSwitchRange, hasComputedGoto})
# Pelles C Compiler
compiler pcc:
# Pelles C
result = (
@@ -279,6 +292,7 @@ compiler pcc:
packedPragma: "", # XXX: not supported yet
props: {})
# Your C Compiler
compiler ucc:
result = (
name: "ucc",
@@ -339,7 +353,9 @@ var
compileOptions: string = ""
ccompilerpath: string = ""
proc nameToCC*(name: string): TSystemCC =
proc nameToCC*(name: string): TSystemCC =
## Returns the kind of compiler referred to by `name`, or ccNone
## if the name doesn't refer to any known compiler.
for i in countup(succ(ccNone), high(TSystemCC)):
if cmpIgnoreStyle(name, CC[i].name) == 0:
return i
@@ -348,17 +364,18 @@ proc nameToCC*(name: string): TSystemCC =
proc getConfigVar(c: TSystemCC, suffix: string): string =
# use ``cpu.os.cc`` for cross compilation, unless ``--compileOnly`` is given
# for niminst support
let fullSuffix = (if gCmd == cmdCompileToCpp: ".cpp" & suffix else: suffix)
if (platform.hostOS != targetOS or platform.hostCPU != targetCPU) and
optCompileOnly notin gGlobalOptions:
let fullCCname = platform.CPU[targetCPU].name & '.' &
platform.OS[targetOS].name & '.' &
CC[c].name & suffix
CC[c].name & fullSuffix
result = getConfigVar(fullCCname)
if result.len == 0:
# not overriden for this cross compilation setting?
result = getConfigVar(CC[c].name & suffix)
result = getConfigVar(CC[c].name & fullSuffix)
else:
result = getConfigVar(CC[c].name & suffix)
result = getConfigVar(CC[c].name & fullSuffix)
proc setCC*(ccname: string) =
cCompiler = nameToCC(ccname)
@@ -412,8 +429,12 @@ proc addFileToLink*(filename: string) =
prependStr(toLink, filename)
# BUGFIX: was ``appendStr``
proc execExternalProgram*(cmd: string) =
if optListCmd in gGlobalOptions or gVerbosity > 0: msgWriteln(cmd)
proc execExternalProgram*(cmd: string, prettyCmd = "") =
if optListCmd in gGlobalOptions or gVerbosity > 0:
if prettyCmd != "":
msgWriteln(prettyCmd)
else:
msgWriteln(cmd)
if execCmd(cmd) != 0: rawMessage(errExecutionOfProgramFailed, "")
proc generateScript(projectFile: string, script: PRope) =
@@ -482,7 +503,7 @@ proc getLinkOptions: string =
proc needsExeExt(): bool {.inline.} =
result = (optGenScript in gGlobalOptions and targetOS == osWindows) or
(platform.hostOS == osWindows)
(platform.hostOS == osWindows)
proc getCompilerExe(compiler: TSystemCC): string =
result = if gCmd == cmdCompileToCpp: CC[compiler].cppCompiler
@@ -539,6 +560,7 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
"lib", quoteShell(libpath)])
proc footprint(filename: string): TCrc32 =
# note, '><' further modifies a crc value with a string.
result = crcFromFile(filename) ><
platform.OS[targetOS].name ><
platform.CPU[targetCPU].name ><
@@ -566,14 +588,16 @@ proc addExternalFileToCompile*(filename: string) =
if optForceFullMake in gGlobalOptions or externalFileChanged(filename):
appendStr(externalToCompile, filename)
proc compileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq,
isExternal: bool) =
proc compileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq,
prettyCmds: var TStringSeq, isExternal: bool) =
var it = PStrEntry(list.head)
while it != nil:
inc(fileCounter) # call the C compiler for the .c file:
var compileCmd = getCompileCFileCmd(it.data, isExternal)
if optCompileOnly notin gGlobalOptions:
add(cmds, compileCmd)
let (dir, name, ext) = splitFile(it.data)
add(prettyCmds, "CC: " & name)
if optGenScript in gGlobalOptions:
app(script, compileCmd)
app(script, tnl)
@@ -589,18 +613,24 @@ proc callCCompiler*(projectfile: string) =
var c = cCompiler
var script: PRope = nil
var cmds: TStringSeq = @[]
compileCFile(toCompile, script, cmds, false)
compileCFile(externalToCompile, script, cmds, true)
var prettyCmds: TStringSeq = @[]
let prettyCb = proc (idx: int) =
echo prettyCmds[idx]
compileCFile(toCompile, script, cmds, prettyCmds, false)
compileCFile(externalToCompile, script, cmds, prettyCmds, true)
if optCompileOnly notin gGlobalOptions:
if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors()
var res = 0
if gNumberOfProcessors <= 1:
for i in countup(0, high(cmds)): res = max(execCmd(cmds[i]), res)
elif optListCmd in gGlobalOptions or gVerbosity > 0:
res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams},
elif optListCmd in gGlobalOptions or gVerbosity > 1:
res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams},
gNumberOfProcessors)
else:
res = execProcesses(cmds, {poUseShell, poParentStreams},
elif gVerbosity == 1:
res = execProcesses(cmds, {poUseShell, poParentStreams},
gNumberOfProcessors, prettyCb)
else:
res = execProcesses(cmds, {poUseShell, poParentStreams},
gNumberOfProcessors)
if res != 0:
if gNumberOfProcessors <= 1:
@@ -622,7 +652,6 @@ proc callCCompiler*(projectfile: string) =
if optGenStaticLib in gGlobalOptions:
linkCmd = CC[c].buildLib % ["libfile", (libNameTmpl() % gProjectName),
"objfiles", objfiles]
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
else:
var linkerExe = getConfigVar(c, ".linkerexe")
if len(linkerExe) == 0: linkerExe = c.getLinkerExe
@@ -654,7 +683,11 @@ proc callCCompiler*(projectfile: string) =
"objfiles", objfiles, "exefile", exefile,
"nimrod", quoteShell(getPrefixDir()),
"lib", quoteShell(libpath)])
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
if optCompileOnly notin gGlobalOptions:
if gVerbosity == 1:
execExternalProgram(linkCmd, "[Linking]")
else:
execExternalProgram(linkCmd)
else:
linkCmd = ""
if optGenScript in gGlobalOptions:

View File

@@ -11,7 +11,7 @@
# This is needed for proper handling of forward declarations.
import
ast, astalgo, msgs, semdata, types, trees
ast, astalgo, msgs, semdata, types, trees, strutils
proc equalGenericParams(procA, procB: PNode): bool =
if sonsLen(procA) != sonsLen(procB): return
@@ -68,11 +68,17 @@ proc searchForProcNew(c: PContext, scope: PScope, fn: PSym): PSym =
ExactConstraints, IgnoreCC}
var it: TIdentIter
result = initIdentIter(it, scope.symbols, fn.name)
while result != nil:
if result.kind in skProcKinds and sameType(result.typ, fn.typ, flags):
case equalParams(result.typ.n, fn.typ.n)
of paramsEqual:
if (sfExported notin result.flags) and (sfExported in fn.flags):
let message = ("public implementation '$1' has non-public " &
"forward declaration in $2") %
[getProcHeader(result), $result.info]
localError(fn.info, errGenerated, message)
return
of paramsIncompatible:
localError(fn.info, errNotOverloadable, fn.name.s)

View File

@@ -71,7 +71,7 @@ hint[LineTooLong]=off
@if not bsd:
# -fopenmp
gcc.options.linker = "-ldl"
gpp.options.linker = "-ldl"
gcc.cpp.options.linker = "-ldl"
clang.options.linker = "-ldl"
tcc.options.linker = "-ldl"
@end
@@ -101,19 +101,19 @@ hint[LineTooLong]=off
cc = clang
tlsEmulation:on
gcc.options.always = "-w -fasm-blocks"
gpp.options.always = "-w -fasm-blocks -fpermissive"
gcc.cpp.options.always = "-w -fasm-blocks -fpermissive"
@else:
gcc.options.always = "-w"
gpp.options.always = "-w -fpermissive"
gcc.options.always = "-w"
gcc.cpp.options.always = "-w -fpermissive"
@end
gcc.options.speed = "-O3 -fno-strict-aliasing"
gcc.options.size = "-Os"
gcc.options.debug = "-g3 -O0"
gpp.options.speed = "-O3 -fno-strict-aliasing"
gpp.options.size = "-Os"
gpp.options.debug = "-g3 -O0"
gcc.cpp.options.speed = "-O3 -fno-strict-aliasing"
gcc.cpp.options.size = "-Os"
gcc.cpp.options.debug = "-g3 -O0"
#passl = "-pg"
# Configuration for the LLVM GCC compiler:

View File

@@ -55,7 +55,7 @@ proc oidToString*(oid: Oid, str: cstring) =
str[24] = '\0'
proc `$`*(oid: Oid): string =
result = newString(25)
result = newString(24)
oidToString(oid, result)
var

View File

@@ -235,11 +235,13 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} =
proc execProcesses*(cmds: openArray[string],
options = {poStdErrToStdOut, poParentStreams},
n = countProcessors()): int {.rtl, extern: "nosp$1",
tags: [ExecIOEffect, TimeEffect, ReadEnvEffect]} =
n = countProcessors(),
beforeRunEvent: proc(idx: int) = nil): int
{.rtl, extern: "nosp$1",
tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} =
## executes the commands `cmds` in parallel. Creates `n` processes
## that execute in parallel. The highest return value of all processes
## is returned.
## is returned. Runs `beforeRunEvent` before running each command.
when defined(posix):
# poParentStreams causes problems on Posix, so we simply disable it:
var options = options - {poParentStreams}
@@ -250,6 +252,8 @@ proc execProcesses*(cmds: openArray[string],
newSeq(q, n)
var m = min(n, cmds.len)
for i in 0..m-1:
if beforeRunEvent != nil:
beforeRunEvent(i)
q[i] = startCmd(cmds[i], options=options)
when defined(noBusyWaiting):
var r = 0
@@ -263,6 +267,8 @@ proc execProcesses*(cmds: openArray[string],
echo(err)
result = max(waitForExit(q[r]), result)
if q[r] != nil: close(q[r])
if beforeRunEvent != nil:
beforeRunEvent(i)
q[r] = startCmd(cmds[i], options=options)
r = (r + 1) mod n
else:
@@ -274,6 +280,8 @@ proc execProcesses*(cmds: openArray[string],
#echo(outputStream(q[r]).readLine())
result = max(waitForExit(q[r]), result)
if q[r] != nil: close(q[r])
if beforeRunEvent != nil:
beforeRunEvent(i)
q[r] = startCmd(cmds[i], options=options)
inc(i)
if i > high(cmds): break
@@ -282,6 +290,8 @@ proc execProcesses*(cmds: openArray[string],
if q[j] != nil: close(q[j])
else:
for i in 0..high(cmds):
if beforeRunEvent != nil:
beforeRunEvent(i)
var p = startCmd(cmds[i], options=options)
result = max(waitForExit(p), result)
close(p)

View File

@@ -0,0 +1,9 @@
discard """
line: 8
errormsg: "public implementation 'tmismatchedvisibility.foo(a: int): int' has non-public forward declaration in tmismatchedvisibility.nim(6,5)"
"""
proc foo(a: int): int
proc foo*(a: int): int =
result = a + a

View File

@@ -20,6 +20,7 @@ REM call the compiler:
ECHO %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
%CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
# linkCmd.add(" " & changeFileExt(f, "o"))
IF ERRORLEVEL 1 (GOTO:END)
# end for
ECHO %LINKER% -o ?{"%BIN_DIR%"\toLower(c.name)}.exe ?linkCmd %LINK_FLAGS%
@@ -27,4 +28,14 @@ ECHO %LINKER% -o ?{"%BIN_DIR%"\toLower(c.name)}.exe ?linkCmd %LINK_FLAGS%
# end block
ECHO SUCCESS
:END
IF ERRORLEVEL 1 (
ECHO FAILURE
ECHO.
ECHO CSource compilation failed. Please check that the gcc compiler is in
ECHO the PATH environment variable, and that you are calling the batch script
ECHO that matches the target architecture of the compiler.
) ELSE (
ECHO SUCCESS
)
exit /b %ERRORLEVEL%