mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-02 19:22:40 +00:00
Merge branch 'master' of github.com:Araq/Nimrod
This commit is contained in:
@@ -122,3 +122,9 @@ flags = "/Q"
|
||||
[C_Compiler]
|
||||
path = r""
|
||||
flags = "-w"
|
||||
|
||||
[deb]
|
||||
buildDepends: "gcc (>= 4:4.3.2)"
|
||||
pkgDepends: "gcc (>= 4:4.3.2)"
|
||||
shortDesc: "The Nimrod Compiler"
|
||||
licenses: "bin/nimrod,gpl2;lib/*,lgpl;"
|
||||
|
||||
@@ -377,4 +377,17 @@ proc getClockStr*(): string {.rtl, extern: "nt$1".} =
|
||||
result = intToStr(ti.hour, 2) & ':' & intToStr(ti.minute, 2) &
|
||||
':' & intToStr(ti.second, 2)
|
||||
|
||||
proc `$`*(day: TWeekDay): string =
|
||||
## stingify operator for ``TWeekDay``.
|
||||
let lookup: array[TWeekDay, string] = ["Monday", "Tuesday", "Wednesday", "Thursday",
|
||||
"Friday", "Saturday", "Sunday"]
|
||||
return lookup[day]
|
||||
|
||||
proc `$`*(m: TMonth): string =
|
||||
## stingify operator for ``TMonth``.
|
||||
let lookup: array[TMonth, string] = ["January", "February", "March", "April",
|
||||
"May", "June", "July", "August", "September", "October", "November",
|
||||
"December"]
|
||||
return lookup[m]
|
||||
|
||||
{.pop.}
|
||||
|
||||
227
tools/niminst/debcreation.nim
Normal file
227
tools/niminst/debcreation.nim
Normal file
@@ -0,0 +1,227 @@
|
||||
import osproc, times, os, strutils
|
||||
|
||||
# http://www.debian.org/doc/manuals/maint-guide/
|
||||
|
||||
# Required files for debhelper.
|
||||
# -- control
|
||||
# -- copyright
|
||||
# -- changelog
|
||||
# -- rules
|
||||
|
||||
type
|
||||
TDebOptions* = object
|
||||
buildDepends*, pkgDepends*, shortDesc*: string
|
||||
licenses*: seq[tuple[files, license: string]]
|
||||
|
||||
template addN(r: string): expr =
|
||||
result.add(r & "\n")
|
||||
|
||||
proc createControl(pkgName, maintainer, shortDesc, desc: string,
|
||||
buildDepends, pkgDepends: string = ""): string =
|
||||
## pkgName: Should be the package name, no spaces.
|
||||
## maintainer: firstName lastName <email>
|
||||
## shortDesc: short description of the application
|
||||
## desc: long description of the application
|
||||
## buildDepends: what the build depends on (compiling from source),
|
||||
## this needs to be in the format deb accepts. For example,
|
||||
## for gcc: ``gcc (>= 4:4.3.2)``
|
||||
## Multiple dependencies should be separated by commas.
|
||||
## pkgDepends: Same as buildDepends except that this specifies the
|
||||
## dependencies that the compiled application depends on.
|
||||
|
||||
|
||||
result = ""
|
||||
|
||||
addN("Source: " & pkgName)
|
||||
addN("Maintainer: " & maintainer)
|
||||
addN("Section: misc")
|
||||
addN("Priority: optional")
|
||||
addN("Standards-Version: 3.9.2")
|
||||
addN("Build-Depends: debhelper (>= 8)" &
|
||||
(if buildDepends != "": ", " & buildDepends else: ""))
|
||||
addN("\n")
|
||||
addN("Package: " & pkgName)
|
||||
addN("Architecture: any")
|
||||
addN("Depends: ${shlibs:Depends}, ${misc:Depends}" &
|
||||
(if pkgDepends != "": ", " & pkgDepends else: ""))
|
||||
|
||||
var formattedDesc = ""
|
||||
for line in splitLines(desc):
|
||||
if line == "":
|
||||
formattedDesc.add(" .\n")
|
||||
else:
|
||||
formattedDesc.add(" " & line & "\n")
|
||||
|
||||
addN("Description: " & shortDesc & "\n" & formattedDesc)
|
||||
|
||||
proc createCopyright(pkgName, mtnName, mtnEmail, version: string,
|
||||
licenses: seq[tuple[files, license: string]]): string =
|
||||
## pkgName: Package name
|
||||
## mtnName: Maintainer name
|
||||
## mtnEmail: Maintainer email
|
||||
## version: package version
|
||||
## licenses: files: This specifies the files that the `license` covers,
|
||||
## for example, it might be ``lib/*`` to cover the whole ``lib`` dir
|
||||
## license: This specifies the license, for example gpl2, or lgpl.
|
||||
|
||||
result = ""
|
||||
addN("Maintainer name: " & mtnName)
|
||||
addN("Email-Address: " & mtnEmail)
|
||||
addN("Date: " & $getTime())
|
||||
addN("Package Name: " & pkgName)
|
||||
addN("Version: " & version)
|
||||
for f, license in items(licenses):
|
||||
addN("Files: " & f)
|
||||
addN("License: " & license)
|
||||
|
||||
proc formatDateTime(t: TTimeInfo, timezone: string): string =
|
||||
var day = ($t.weekday)[0..2] & ", "
|
||||
|
||||
return "$1$2 $3 $4 $5:$6:$7 $8" % [day, intToStr(t.monthday, 2),
|
||||
($t.month)[0..2], $t.year, intToStr(t.hour, 2), intToStr(t.minute, 2),
|
||||
intToStr(t.second, 2), timezone]
|
||||
|
||||
proc createChangelog(pkgName, version, maintainer: string): string =
|
||||
## pkgName: package name
|
||||
## version: package version
|
||||
## maintainer: firstName lastName <email>
|
||||
result = ""
|
||||
addN(pkgName & " (" & version & "-1) unstable; urgency=low")
|
||||
addN("")
|
||||
addN(" * Initial release.")
|
||||
addN("")
|
||||
addN(" -- " & maintainer & " " &
|
||||
formatDateTime(getGmTime(getTime()), "+0000"))
|
||||
|
||||
proc createRules(): string =
|
||||
## Creates a nimrod application-agnostic rules file for building deb packages.
|
||||
## Please note: this assumes the c sources have been built and the
|
||||
## ``build.sh`` and ``install.sh`` files are available.
|
||||
result = ""
|
||||
addN("#!/usr/bin/make -f")
|
||||
addN("%:")
|
||||
addN("\tdh $@\n")
|
||||
addN("dh_install:")
|
||||
addN("\tdh_install --sourcedir=debian/tmp")
|
||||
addN("override_dh_auto_clean:")
|
||||
addN("\tfind . -name *.o -exec rm {} \\;")
|
||||
addN("override_dh_auto_build:")
|
||||
addN("\t./build.sh")
|
||||
addN("override_dh_auto_install:")
|
||||
addN("\t./install.sh debian/tmp")
|
||||
|
||||
proc createIncludeBinaries(binaries: seq[string]): string =
|
||||
return join(binaries, "\n")
|
||||
|
||||
proc createDotInstall(pkgName: string, binaries, config, docs,
|
||||
lib: seq[string]): string =
|
||||
result = ""
|
||||
for b in binaries:
|
||||
addN(pkgName / b & " " & "usr/bin/")
|
||||
for c in config:
|
||||
addN(pkgName / c & " " & "etc/")
|
||||
for d in docs:
|
||||
addN(pkgName / d & " " & "usr/share/doc/nimrod/")
|
||||
for l1 in lib:
|
||||
addN(pkgName / l1 & " " & "usr/lib/nimrod")
|
||||
|
||||
proc makeMtn(name, email: string): string =
|
||||
return name & " <" & email & ">"
|
||||
|
||||
proc assertSuccess(exitCode: int) =
|
||||
doAssert(exitCode == QuitSuccess)
|
||||
|
||||
proc prepDeb*(packName, version, mtnName, mtnEmail, shortDesc, desc: string,
|
||||
licenses: seq[tuple[files, license: string]], binaries,
|
||||
config, docs, lib: seq[string],
|
||||
buildDepends, pkgDepends = "") =
|
||||
## binaries/config/docs/lib: files relative to nimrod's root, that need to
|
||||
## be installed.
|
||||
|
||||
let pkgName = packName.toLower()
|
||||
|
||||
var workingDir = getTempDir() / "niminst" / "deb"
|
||||
var upstreamSource = (pkgName & "-" & version)
|
||||
|
||||
echo("Making sure build.sh and install.sh are +x")
|
||||
assertSuccess execCmd("chmod +x \"" &
|
||||
(workingDir / upstreamSource / "build.sh") & "\"")
|
||||
assertSuccess execCmd("chmod +x \"" &
|
||||
(workingDir / upstreamSource / "install.sh") & "\"")
|
||||
|
||||
var tarCmd = "tar pczf \"" &
|
||||
(pkgName & "_" & version & ".orig.tar.gz") &
|
||||
"\" \"" & upstreamSource & "\""
|
||||
echo(tarCmd)
|
||||
assertSuccess execCmd("cd \"" & workingDir & "\" && " & tarCmd)
|
||||
|
||||
echo("Creating necessary files in debian/")
|
||||
createDir(workingDir / upstreamSource / "debian")
|
||||
|
||||
template writeDebian(f, s: string): expr =
|
||||
writeFile(workingDir / upstreamSource / "debian" / f, s)
|
||||
|
||||
var controlFile = createControl(pkgName, makeMtn(mtnName, mtnEmail),
|
||||
shortDesc, desc, buildDepends, pkgDepends)
|
||||
echo("debian/control")
|
||||
writeDebian("control", controlFile)
|
||||
|
||||
var copyrightFile = createCopyright(pkgName, mtnName, mtnEmail, version,
|
||||
licenses)
|
||||
echo("debian/copyright")
|
||||
writeDebian("copyright", copyrightFile)
|
||||
|
||||
var changelogFile = createChangelog(pkgName, version,
|
||||
makeMtn(mtnName, mtnEmail))
|
||||
echo("debian/changelog")
|
||||
writeDebian("changelog", changelogFile)
|
||||
|
||||
echo("debian/rules")
|
||||
writeDebian("rules", createRules())
|
||||
|
||||
echo("debian/compat")
|
||||
writeDebian("compat", "8")
|
||||
|
||||
echo("debian/" & pkgName & ".install")
|
||||
writeDebian(pkgName & ".install",
|
||||
createDotInstall(pkgName, binaries, config, docs, lib))
|
||||
|
||||
# Other things..
|
||||
createDir(workingDir / upstreamSource / "debian" / "source")
|
||||
echo("debian/source/format")
|
||||
writeDebian("source" / "format",
|
||||
"3.0 (quilt)")
|
||||
echo("debian/source/include-binaries")
|
||||
writeFile(workingDir / upstreamSource / "debian" / "source" / "include-binaries",
|
||||
createIncludeBinaries(binaries))
|
||||
|
||||
echo("All done, you can now build.")
|
||||
echo("Before you do however, make sure the files in " &
|
||||
workingDir / upstreamSource / "debian" & " are correct.")
|
||||
echo("Change your directory to: " & workingDir / upstreamSource)
|
||||
echo("And execute `debuild -us -uc` to build the .deb")
|
||||
|
||||
when isMainModule:
|
||||
#var controlFile = createControl("nimrod", "Dominik Picheta <morfeusz8@gmail.com>",
|
||||
# "The Nimrod compiler", "Compiler for the Nimrod programming language", "gcc (>= 4:4.3.2)", "gcc (>= 4:4.3.2)")
|
||||
|
||||
#echo(controlFile)
|
||||
|
||||
#var copyrightFile = createCopyright("nimrod", "Dominik Picheta", "morfeusz8@a.b", "0.8.14",
|
||||
# @[("bin/nimrod", "gpl2"), ("lib/*", "lgpl")])
|
||||
|
||||
#echo copyrightFile
|
||||
|
||||
#var changelogFile = createChangelog("nimrod", "0.8.14", "Dom P <m@b.c>")
|
||||
#echo(changelogFile)
|
||||
|
||||
#echo(createRules())
|
||||
|
||||
prepDeb("nimrod", "0.8.14", "Dominik Picheta", "morfeusz8@gmail.com",
|
||||
"The Nimrod compiler", "Compiler for the Nimrod programming language",
|
||||
@[("bin/nimrod", "gpl2"), ("lib/*", "lgpl")],
|
||||
@["bin/nimrod"], @["config/*"], @["doc/*"], @["lib/*"],
|
||||
"gcc (>= 4:4.3.2)", "gcc (>= 4:4.3.2)")
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ when haveZipLib:
|
||||
import zipfiles
|
||||
|
||||
import
|
||||
os, strutils, parseopt, parsecfg, strtabs, streams
|
||||
os, strutils, parseopt, parsecfg, strtabs, streams, debcreation
|
||||
|
||||
const
|
||||
maxOS = 20 # max number of OSes
|
||||
@@ -30,7 +30,8 @@ type
|
||||
actionNone, # action not yet known
|
||||
actionCSource # action: create C sources
|
||||
actionInno, # action: create Inno Setup installer
|
||||
actionZip # action: create zip file
|
||||
actionZip, # action: create zip file
|
||||
actionDeb # action: prepare deb package
|
||||
|
||||
TFileCategory = enum
|
||||
fcWinBin, # binaries for Windows
|
||||
@@ -56,6 +57,7 @@ type
|
||||
vars: PStringTable
|
||||
app: TAppType
|
||||
nimrodArgs: string
|
||||
debOpts: TDebOptions
|
||||
|
||||
const
|
||||
unixDirVars: array[fcConfig..fcLib, string] = [
|
||||
@@ -86,6 +88,11 @@ proc initConfigData(c: var TConfigData) =
|
||||
c.uninstallScript = false
|
||||
c.vars = newStringTable(modeStyleInsensitive)
|
||||
|
||||
c.debOpts.buildDepends = ""
|
||||
c.debOpts.pkgDepends = ""
|
||||
c.debOpts.shortDesc = ""
|
||||
c.debOpts.licenses = @[]
|
||||
|
||||
proc firstBinPath(c: TConfigData): string =
|
||||
if c.binPaths.len > 0: result = c.binPaths[0]
|
||||
else: result = ""
|
||||
@@ -121,6 +128,7 @@ Command:
|
||||
csource build C source code for source based installations
|
||||
zip build the ZIP file
|
||||
inno build the Inno Setup installer
|
||||
deb create files for debhelper
|
||||
Options:
|
||||
-o, --output:dir set the output directory
|
||||
--var:name=value set the value of a variable
|
||||
@@ -145,6 +153,7 @@ proc parseCmdLine(c: var TConfigData) =
|
||||
of "csource": incl(c.actions, actionCSource)
|
||||
of "zip": incl(c.actions, actionZip)
|
||||
of "inno": incl(c.actions, actionInno)
|
||||
of "deb": incl(c.actions, actionDeb)
|
||||
else: quit(Usage)
|
||||
else:
|
||||
c.infile = addFileExt(key.string, "ini")
|
||||
@@ -266,6 +275,36 @@ proc parseIniFile(c: var TConfigData) =
|
||||
of "innosetup": pathFlags(p, k.key, v, c.innoSetup)
|
||||
of "ccompiler": pathFlags(p, k.key, v, c.ccompiler)
|
||||
of "linker": pathFlags(p, k.key, v, c.linker)
|
||||
of "deb":
|
||||
case normalize(k.key)
|
||||
of "builddepends":
|
||||
c.debOpts.buildDepends = v
|
||||
of "packagedepends", "pkgdepends":
|
||||
c.debOpts.pkgDepends = v
|
||||
of "shortdesc":
|
||||
c.debOpts.shortDesc = v
|
||||
of "licenses":
|
||||
# file,license;file,license;
|
||||
var i = 0
|
||||
var file = ""
|
||||
var license = ""
|
||||
var afterComma = false
|
||||
while i < v.len():
|
||||
case v[i]
|
||||
of ',':
|
||||
afterComma = true
|
||||
of ';':
|
||||
if file == "" or license == "":
|
||||
quit(errorStr(p, "Invalid `licenses` key."))
|
||||
c.debOpts.licenses.add((file, license))
|
||||
afterComma = false
|
||||
file = ""
|
||||
license = ""
|
||||
else:
|
||||
if afterComma: license.add(v[i])
|
||||
else: file.add(v[i])
|
||||
inc(i)
|
||||
else: quit(errorStr(p, "unknown variable: " & k.key))
|
||||
else: quit(errorStr(p, "invalid section: " & section))
|
||||
|
||||
of cfgOption: quit(errorStr(p, "syntax error"))
|
||||
@@ -415,6 +454,52 @@ when haveZipLib:
|
||||
else:
|
||||
quit("Cannot open for writing: " & n)
|
||||
|
||||
# -- prepare build files for .deb creation
|
||||
|
||||
proc debDist(c: var TConfigData) =
|
||||
if not existsFile("build.sh"): quit("No build.sh found.")
|
||||
if not existsFile("install.sh"): quit("No install.sh found.")
|
||||
|
||||
if c.debOpts.shortDesc == "": quit("shortDesc must be set in the .ini file.")
|
||||
if c.debOpts.licenses.len == 0:
|
||||
echo("[Warning] No licenses specified for .deb creation.")
|
||||
|
||||
# -- Copy files into /tmp/..
|
||||
echo("Copying source to tmp/niminst/deb/")
|
||||
var currentSource = getCurrentDir()
|
||||
var workingDir = getTempDir() / "niminst" / "deb"
|
||||
var upstreamSource = (c.name.toLower() & "-" & c.version)
|
||||
|
||||
createDir(workingDir / upstreamSource)
|
||||
|
||||
template copyNimDist(f, dest: string): stmt =
|
||||
createDir((workingDir / upstreamSource / dest).splitFile.dir)
|
||||
copyFile(currentSource / f, workingDir / upstreamSource / dest)
|
||||
|
||||
# Don't copy all files, only the ones specified in the config:
|
||||
copyNimDist(buildShFile, buildShFile)
|
||||
copyNimDist(installShFile, installShFile)
|
||||
createDir(workingDir / upstreamSource / "build")
|
||||
for f in walkFiles(c.libpath / "lib/*.h"):
|
||||
copyNimDist(f, "build" / extractFilename(f))
|
||||
for osA in 1..c.oses.len:
|
||||
for cpuA in 1..c.cpus.len:
|
||||
var dir = buildDir(osA, cpuA)
|
||||
for k, f in walkDir(dir):
|
||||
if k == pcFile: copyNimDist(f, dir / extractFilename(f))
|
||||
for cat in items({fcConfig..fcOther, fcUnix}):
|
||||
for f in items(c.cat[cat]): copyNimDist(f, f)
|
||||
|
||||
# -- Create necessary build files for debhelper.
|
||||
|
||||
let mtnName = c.vars["mtnname"]
|
||||
let mtnEmail = c.vars["mtnemail"]
|
||||
|
||||
prepDeb(c.name, c.version, mtnName, mtnEmail, c.debOpts.shortDesc,
|
||||
c.description, c.debOpts.licenses, c.cat[fcUnixBin], c.cat[fcConfig],
|
||||
c.cat[fcDoc], c.cat[fcLib], c.debOpts.buildDepends,
|
||||
c.debOpts.pkgDepends)
|
||||
|
||||
# ------------------- main ----------------------------------------------------
|
||||
|
||||
var c: TConfigData
|
||||
@@ -430,3 +515,6 @@ if actionZip in c.actions:
|
||||
zipdist(c)
|
||||
else:
|
||||
quit("libzip is not installed")
|
||||
if actionDeb in c.actions:
|
||||
debDist(c)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user