mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 18:02:05 +00:00
Merge branch 'bigbreak' of https://github.com/Araq/Nimrod into bigbreak
This commit is contained in:
@@ -1126,6 +1126,7 @@ proc checkCanEval(c: PCtx; n: PNode) =
|
||||
# we need to ensure that we don't evaluate 'x' here:
|
||||
# proc foo() = var x ...
|
||||
let s = n.sym
|
||||
if {sfCompileTime, sfGlobal} <= s.flags: return
|
||||
if s.kind in {skVar, skTemp, skLet, skParam, skResult} and
|
||||
not s.isOwnedBy(c.prc.sym) and s.owner != c.module:
|
||||
cannotEval(n)
|
||||
|
||||
1
csources
Submodule
1
csources
Submodule
Submodule csources added at b0bcf88e26
2
koch.nim
2
koch.nim
@@ -332,7 +332,7 @@ proc temp(args: string) =
|
||||
|
||||
proc showHelp() =
|
||||
quit(HelpText % [NimVersion & repeatChar(44-len(NimVersion)),
|
||||
CompileDate, CompileTime])
|
||||
CompileDate, CompileTime], QuitSuccess)
|
||||
|
||||
var op = initOptParser()
|
||||
op.next()
|
||||
|
||||
@@ -2382,7 +2382,7 @@ proc hstrerror*(herrnum: cint): cstring {.importc, header: "<netdb.h>".}
|
||||
proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "<sys/select.h>".}
|
||||
proc FD_ISSET*(a1: cint | SocketHandle, a2: var TFdSet): cint {.
|
||||
importc, header: "<sys/select.h>".}
|
||||
proc fdSet*(a1: cint | SocketHandle, a2: var TFdSet) {.
|
||||
proc FD_SET*(a1: cint | SocketHandle, a2: var TFdSet) {.
|
||||
importc: "FD_SET", header: "<sys/select.h>".}
|
||||
proc FD_ZERO*(a1: var TFdSet) {.importc, header: "<sys/select.h>".}
|
||||
|
||||
|
||||
@@ -91,11 +91,11 @@ import sockets, os
|
||||
## getSocket(s).accept(client)
|
||||
|
||||
when defined(windows):
|
||||
from winlean import TimeVal, SocketHandle, fdSet, FD_ZERO, TFdSet,
|
||||
fdSet, FD_ISSET, select
|
||||
from winlean import TimeVal, SocketHandle, FD_SET, FD_ZERO, TFdSet,
|
||||
FD_ISSET, select
|
||||
else:
|
||||
from posix import TimeVal, SocketHandle, fdSet, FD_ZERO, TFdSet,
|
||||
fdSet, FD_ISSET, select
|
||||
from posix import TimeVal, SocketHandle, FD_SET, FD_ZERO, TFdSet,
|
||||
FD_ISSET, select
|
||||
|
||||
type
|
||||
DelegateObj* = object
|
||||
@@ -556,7 +556,7 @@ proc createFdSet(fd: var TFdSet, s: seq[Delegate], m: var int) =
|
||||
FD_ZERO(fd)
|
||||
for i in items(s):
|
||||
m = max(m, int(i.fd))
|
||||
fdSet(i.fd, fd)
|
||||
FD_SET(i.fd, fd)
|
||||
|
||||
proc pruneSocketSet(s: var seq[Delegate], fd: var TFdSet) =
|
||||
var i = 0
|
||||
|
||||
@@ -887,7 +887,7 @@ elif not defined(useNimRtl):
|
||||
FD_ZERO(fd)
|
||||
for i in items(s):
|
||||
m = max(m, int(i.outHandle))
|
||||
fdSet(cint(i.outHandle), fd)
|
||||
FD_SET(cint(i.outHandle), fd)
|
||||
|
||||
proc pruneProcessSet(s: var seq[Process], fd: var TFdSet) =
|
||||
var i = 0
|
||||
|
||||
@@ -372,7 +372,7 @@ proc createFdSet(fd: var TFdSet, s: seq[SocketHandle], m: var int) =
|
||||
FD_ZERO(fd)
|
||||
for i in items(s):
|
||||
m = max(m, int(i))
|
||||
fdSet(i, fd)
|
||||
FD_SET(i, fd)
|
||||
|
||||
proc pruneSocketSet(s: var seq[SocketHandle], fd: var TFdSet) =
|
||||
var i = 0
|
||||
|
||||
@@ -936,7 +936,7 @@ proc createFdSet(fd: var TFdSet, s: seq[Socket], m: var int) =
|
||||
FD_ZERO(fd)
|
||||
for i in items(s):
|
||||
m = max(m, int(i.fd))
|
||||
fdSet(i.fd, fd)
|
||||
FD_SET(i.fd, fd)
|
||||
|
||||
proc pruneSocketSet(s: var seq[Socket], fd: var TFdSet) =
|
||||
var i = 0
|
||||
|
||||
@@ -536,7 +536,7 @@ proc WSAFDIsSet(s: SocketHandle, set: var TFdSet): bool {.
|
||||
proc FD_ISSET*(socket: SocketHandle, set: var TFdSet): cint =
|
||||
result = if WSAFDIsSet(socket, set): 1'i32 else: 0'i32
|
||||
|
||||
proc fdSet*(socket: SocketHandle, s: var TFdSet) =
|
||||
proc FD_SET*(socket: SocketHandle, s: var TFdSet) =
|
||||
if s.fd_count < FD_SETSIZE:
|
||||
s.fd_array[int(s.fd_count)] = socket
|
||||
inc(s.fd_count)
|
||||
|
||||
18
tools/fakedeps.nim
Normal file
18
tools/fakedeps.nim
Normal file
@@ -0,0 +1,18 @@
|
||||
import strutils, os, pegs, strtabs, math, threadpool, times
|
||||
|
||||
proc fakeCppDep(x: ptr float) {.importcpp: "fakeCppDep", header: "<vector>".}
|
||||
proc fakeTimeDep() = echo(times.getDateStr())
|
||||
proc fakedeps() =
|
||||
var x = 0.4
|
||||
{.emit: "#if 0\n".}
|
||||
fakeCppDep(addr x)
|
||||
{.emit: "#endif\n".}
|
||||
|
||||
# this is not true:
|
||||
if math.sin(x) > 0.6:
|
||||
spawn(fakeTimeDep())
|
||||
|
||||
proc main =
|
||||
fakedeps()
|
||||
when isMainModule:
|
||||
main()
|
||||
207
tools/trimcc.nim
207
tools/trimcc.nim
@@ -1,34 +1,17 @@
|
||||
# Trim C compiler installation to a minimum
|
||||
|
||||
import strutils, os, pegs, strtabs, math, threadpool, times
|
||||
# Trim C compiler installation to a minimum
|
||||
|
||||
proc fakeCppDep(x: ptr float) {.importcpp: "fakeCppDep", header: "<vector>".}
|
||||
import strutils, os, pegs, strtabs, math, threadpool, times
|
||||
|
||||
const
|
||||
Essential = """gcc.exe g++.exe gdb.exe ld.exe as.exe c++.exe cpp.exe cc1.exe
|
||||
crtbegin.o crtend.o crt2.o dllcrt2.o
|
||||
libexpat-1.dll libwinpthread-1.dll
|
||||
|
||||
aio.h
|
||||
dlfcn.h
|
||||
fcntl.h fenv.h fmtmsg.h fnmatch.h ftw.h
|
||||
errno.h
|
||||
glob.h gtmath.h
|
||||
if.h in.h ipc.h
|
||||
langinfo.h locale.h
|
||||
math.h mman.h
|
||||
netdb.h nl_types.h
|
||||
poll.h pthread.h pwd.h
|
||||
sched.h select.h semaphore.h signal.h
|
||||
socket.h spawn.h stat.h statvfs.h stdio.h stdlib.h string.h strings.h
|
||||
tcp.h time.h types.h
|
||||
ucontext.h uio.h utsname.h unistd.h
|
||||
wait.h
|
||||
varargs.h
|
||||
windows.h
|
||||
zlib.h
|
||||
crtbegin.o crtend.o crt2.o dllcrt2.o libgcc_s_dw2-1.dll libgcc_s_sjlj-1.dll
|
||||
libgcc_s_seh-1.dll libexpat-1.dll libwinpthread-1.dll aio.h dlfcn.h fcntl.h
|
||||
fenv.h fmtmsg.h fnmatch.h ftw.h errno.h glob.h gtmath.h if.h in.h ipc.h
|
||||
langinfo.h locale.h math.h mman.h netdb.h nl_types.h poll.h pthread.h pwd.h
|
||||
sched.h select.h semaphore.h signal.h socket.h spawn.h stat.h statvfs.h stdio.h
|
||||
stdlib.h string.h strings.h tcp.h time.h types.h ucontext.h uio.h utsname.h
|
||||
unistd.h wait.h varargs.h windows.h zlib.h
|
||||
""".split
|
||||
BucketSize = 40
|
||||
|
||||
proc includes(headerpath, headerfile: string, whitelist: StringTableRef) =
|
||||
whitelist[headerfile] = "processed"
|
||||
@@ -40,88 +23,152 @@ proc includes(headerpath, headerfile: string, whitelist: StringTableRef) =
|
||||
if whitelist[m] != "processed":
|
||||
whitelist[m] = "found"
|
||||
|
||||
proc processIncludes(dir: string, whitelist: StringTableRef) =
|
||||
for kind, path in walkDir(dir):
|
||||
case kind
|
||||
proc processIncludes(dir: string, whitelist: StringTableRef) =
|
||||
for kind, path in walkDir(dir):
|
||||
case kind
|
||||
of pcFile:
|
||||
let name = extractFilename(path)
|
||||
if ('.' notin name and "include" in path) or ("c++" in path):
|
||||
let n = whitelist[name]
|
||||
if n != "processed": whitelist[name] = "found"
|
||||
if n != "processed": whitelist[name] = "found"
|
||||
if name.endswith(".h"):
|
||||
let n = whitelist[name]
|
||||
if n == "found": includes(path, name, whitelist)
|
||||
of pcDir: processIncludes(path, whitelist)
|
||||
of pcDir: processIncludes(path, whitelist)
|
||||
else: discard
|
||||
|
||||
proc gatherFiles(dir: string, whitelist: StringTableRef, result: var seq[string]) =
|
||||
for kind, path in walkDir(dir):
|
||||
case kind
|
||||
proc gatherFiles(dir: string, whitelist: StringTableRef, result: var seq[string]) =
|
||||
for kind, path in walkDir(dir):
|
||||
case kind
|
||||
of pcFile:
|
||||
let name = extractFilename(path)
|
||||
let name = extractFilename(path)
|
||||
if not whitelist.hasKey(name):
|
||||
result.add(path)
|
||||
of pcDir: gatherFiles(path, whitelist, result)
|
||||
else: discard
|
||||
|
||||
proc newName(f: string): string =
|
||||
let (dir, name, ext) = splitFile(f)
|
||||
return dir / "trim_" & name & ext
|
||||
of pcDir:
|
||||
gatherFiles(path, whitelist, result)
|
||||
else:
|
||||
discard
|
||||
|
||||
proc gatherEmptyFolders(dir: string, whitelist: StringTableRef, result: var seq[string]) =
|
||||
var empty = true
|
||||
for kind, path in walkDir(dir):
|
||||
case kind
|
||||
of pcFile:
|
||||
empty = false
|
||||
of pcDir:
|
||||
let (none, name) = splitPath(path)
|
||||
if not whitelist.hasKey(name):
|
||||
gatherEmptyFolders(path, whitelist, result)
|
||||
empty = false
|
||||
else:
|
||||
discard
|
||||
if empty:
|
||||
result.add(dir)
|
||||
|
||||
proc newName(f: string): string =
|
||||
let (dir, name, ext) = splitFile(f)
|
||||
return dir / "trim_" & name & ext
|
||||
|
||||
proc ccStillWorks(): bool =
|
||||
const
|
||||
c1 = r"nim c --force_build koch"
|
||||
c2 = r"nim c --force_build --threads:on --out:temp.exe tools/trimcc"
|
||||
result = execShellCmd(c1) == 0 and execShellCmd(c2) == 0
|
||||
|
||||
proc trialDeletion(files: seq[string], a, b: int) =
|
||||
for i in a .. min(b, files.high):
|
||||
let path = files[i]
|
||||
moveFile(dest=newName(path), source=path)
|
||||
c1 = r"nim c --verbosity:0 --force_build koch"
|
||||
c2 = r"nim c --verbosity:0 --force_build --threads:on --out:tempOne.exe trimcc"
|
||||
c3 = r"nim c --verbosity:0 --force_build --threads:on --out:tempTwo.exe fakeDeps"
|
||||
c4 = r".\koch.exe"
|
||||
c5 = r".\tempOne.exe"
|
||||
c6 = r".\tempTwo.exe"
|
||||
result = execShellCmd(c1) == 0 and execShellCmd(c2) == 0 and
|
||||
execShellCmd(c3) == 0 and execShellCmd(c4) == 0 and
|
||||
execShellCmd(c5) == 0 and execShellCmd(c6) == 0
|
||||
|
||||
proc trialDeletion(files: seq[string], a, b: int, whitelist: StringTableRef): bool =
|
||||
result = true
|
||||
var single = (a == min(b, files.high))
|
||||
for path in files[a .. min(b, files.high)]:
|
||||
try:
|
||||
moveFile(dest=newName(path), source=path)
|
||||
except OSError:
|
||||
return false
|
||||
|
||||
# Test if compilation still works, even with the moved files.
|
||||
if ccStillWorks():
|
||||
for i in a .. min(b, files.high):
|
||||
let path = files[i]
|
||||
echo "Optional: ", path
|
||||
removeFile(newName(path))
|
||||
else:
|
||||
for i in a .. min(b, files.high):
|
||||
let path = files[i]
|
||||
echo "Required: ", path
|
||||
# copy back:
|
||||
for path in files[a .. min(b, files.high)]:
|
||||
try:
|
||||
removeFile(newName(path))
|
||||
echo "Optional: ", path
|
||||
except OSError:
|
||||
echo "Warning, couldn't move ", path
|
||||
moveFile(dest=path, source=newName(path))
|
||||
return false
|
||||
else:
|
||||
for path in files[a .. min(b, files.high)]:
|
||||
echo "Required: ", path
|
||||
moveFile(dest=path, source=newName(path))
|
||||
if single:
|
||||
whitelist[path] = "found"
|
||||
result = false
|
||||
|
||||
proc main(dir: string) =
|
||||
# Construct a whitelist of files to not remove
|
||||
var whitelist = newStringTable(modeCaseInsensitive)
|
||||
for e in Essential:
|
||||
whitelist[e] = "found"
|
||||
while true:
|
||||
let oldLen = whitelist.len
|
||||
processIncludes(dir, whitelist)
|
||||
processIncludes(dir, whitelist)
|
||||
if oldLen == whitelist.len: break
|
||||
var allFiles: seq[string] = @[]
|
||||
gatherFiles(dir, whitelist, allFiles)
|
||||
if oldLen == whitelist.len:
|
||||
break
|
||||
|
||||
# Remove batches of files
|
||||
var nearlyDone = false
|
||||
while true:
|
||||
# Gather files to test
|
||||
var allFiles = newSeq[string]()
|
||||
gatherFiles(dir, whitelist, allFiles)
|
||||
|
||||
# Determine the initial size of groups to check
|
||||
var
|
||||
maxBucketSize = len(allFiles)
|
||||
bucketSize = 1
|
||||
|
||||
# Loop through the list of files, deleting batches
|
||||
var i = 0
|
||||
while i < allFiles.len:
|
||||
while i < allFiles.len:
|
||||
trialDeletion(allFiles, i, i+BucketSize-1)
|
||||
inc i, BucketSize
|
||||
else:
|
||||
var success = trialDeletion(allFiles, i, i+bucketSize-1, whitelist)
|
||||
inc i, bucketSize
|
||||
|
||||
|
||||
# If we aren't on the last pass, adjust the batch size based on success
|
||||
if not nearlyDone:
|
||||
if success:
|
||||
bucketSize = min(bucketSize * 2, maxBucketSize)
|
||||
else:
|
||||
bucketSize = max(bucketSize div 2, 1)
|
||||
echo "Bucket size is now ", bucketSize
|
||||
|
||||
|
||||
proc fakedeps() =
|
||||
var x = 0.4
|
||||
{.emit: "#if 0\n".}
|
||||
fakeCppDep(addr x)
|
||||
# After looping through all the files, check if we need to break.
|
||||
if nearlyDone:
|
||||
break
|
||||
if bucketSize == 1:
|
||||
nearlyDone = true
|
||||
|
||||
while true:
|
||||
var
|
||||
emptyFolders = newSeq[string]()
|
||||
changed = false
|
||||
|
||||
gatherEmptyFolders(dir, whitelist, emptyFolders)
|
||||
for path in emptyFolders:
|
||||
removeDir(path)
|
||||
if not ccStillWorks():
|
||||
createDir(path)
|
||||
whitelist[path] = "found"
|
||||
else:
|
||||
changed = true
|
||||
if not changed:
|
||||
break
|
||||
|
||||
|
||||
# this is not true:
|
||||
if math.sin(x) > 0.6:
|
||||
spawn(fakeTimeDep())
|
||||
if paramCount() == 1:
|
||||
doAssert ccStillWorks()
|
||||
doAssert ccStillWorks()
|
||||
fakedeps()
|
||||
main(paramStr(1))
|
||||
else:
|
||||
main(paramStr(1))
|
||||
else:
|
||||
quit "Usage: trimcc c_compiler_directory", QuitSuccess
|
||||
|
||||
Reference in New Issue
Block a user