nandi/cosmicnimpublic Fork 0
0b02cea
Commits
Clone
git clone https://git.rickub.com/nandi/cosmicnim.git
git clone ssh://git@rickub.com/nandi/cosmicnim.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Make this a nimble package, and grow the example into a gallery

The example now switches between four pages, which is the thing the old
fixed contract could not express at all: each page is a different tree
built from Nim state, not a widget shown or hidden. It exercises every
text and button style, disabled buttons, nesting, padding, and the theme
spacing scale.

On packaging: cosmicnim.nimble owns fetching now, and `just fetch` is a
wrapper over `nimble fetchLib`, so the fetch works for someone who
installed the package without just. The tag comes from the package
version rather than the newest tag on the remote — cosmicnim 0.2.0 speaks
to the v0.2.0 ABI and nothing else, which is what stops a stale library
loading against new bindings.

The binding resolves the .so by absolute path at compile time, so an
installed package finds it in the nimble store; the app.nims rpath hack
is gone. cosmic.nim is renamed cosmicnim.nim to match the package, and
the example moved out of srcDir so it is not installed alongside it.

Verified: a program compiled outside the repo against the installed
package loads the cdylib from the nimble store.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandithebull committed 2026-09-20T10:38:49-07:00 Browse files
0b02cea parent: 2bd2bc6
modified .gitignore +1 -1
@@ -1,5 +1,5 @@
11 target/
2-nim/app
2+examples/gallery
33 nimcache/
44 *.so
55 run.log
@@ -1,5 +1,5 @@
1 target/1 target/
2-nim/app2+examples/gallery
3 nimcache/3 nimcache/
4 *.so4 *.so
5 run.log5 run.log
modified README.md +21 -5
@@ -8,9 +8,11 @@ therefore *defines* the C surface: it depends on libcosmic as a normal Rust
88 crate and exports a handful of functions.
99
1010 ```
11-cosmic_ffi/ Rust cdylib -> libcosmic_ffi.so + cosmic_ffi.h
12-nim/ Nim bindings (cosmic.nim) and the demo app (app.nim)
13-justfile build / run / fetch tasks
11+cosmic_ffi/ Rust cdylib -> libcosmic_ffi.so + cosmic_ffi.h
12+nim/ the Nim binding (cosmicnim.nim), and where the .so lands
13+examples/ gallery.nim, a demo of what the builder can express
14+cosmicnim.nimble package metadata and the fetchLib task
15+justfile build / run / fetch tasks
1416 ```
1517
1618 ## The contract
@@ -61,11 +63,25 @@ proc onView(ctx: pointer; b: Builder) {.cdecl.} =
6163 The demo needs `nim/libcosmic_ffi.so`. Take it from a release:
6264
6365 ```bash
64-just fetch # newest v* tag on the remote
65-just fetch v0.1.2 # or a specific one
66+just fetch # or: nimble fetchLib
6667 just run
6768 ```
6869
70+The package version *is* the ABI version: cosmicnim 0.2.0 fetches the
71+v0.2.0 release and no other, so a stale library cannot load against newer
72+bindings. `just fetch v0.1.2` (or `COSMICNIM_TAG=v0.1.2 nimble fetchLib`)
73+overrides that when you want it.
74+
75+## As a dependency
76+
77+```bash
78+nimble install # fetches the cdylib too, and ships it with the package
79+```
80+
81+The binding resolves the library by absolute path at compile time, so an
82+installed package finds its `.so` in the nimble store without any rpath or
83+`LD_LIBRARY_PATH` fiddling. Override with `-d:libCosmicFfi=/some/path.so`.
84+
6985 or build it yourself — the cold build is long, which is what the release CI is
7086 for:
7187
@@ -8,9 +8,11 @@ therefore *defines* the C surface: it depends on libcosmic as a normal Rust
8 crate and exports a handful of functions.8 crate and exports a handful of functions.
9 9
10 ```10 ```
11-cosmic_ffi/ Rust cdylib -> libcosmic_ffi.so + cosmic_ffi.h11+cosmic_ffi/ Rust cdylib -> libcosmic_ffi.so + cosmic_ffi.h
12-nim/ Nim bindings (cosmic.nim) and the demo app (app.nim)12+nim/ the Nim binding (cosmicnim.nim), and where the .so lands
13-justfile build / run / fetch tasks13+examples/ gallery.nim, a demo of what the builder can express
14+cosmicnim.nimble package metadata and the fetchLib task
15+justfile build / run / fetch tasks
14 ```16 ```
15 17
16 ## The contract18 ## The contract
@@ -61,11 +63,25 @@ proc onView(ctx: pointer; b: Builder) {.cdecl.} =
61 The demo needs `nim/libcosmic_ffi.so`. Take it from a release:63 The demo needs `nim/libcosmic_ffi.so`. Take it from a release:
62 64
63 ```bash65 ```bash
64-just fetch # newest v* tag on the remote66+just fetch # or: nimble fetchLib
65-just fetch v0.1.2 # or a specific one
66 just run67 just run
67 ```68 ```
68 69
70+The package version *is* the ABI version: cosmicnim 0.2.0 fetches the
71+v0.2.0 release and no other, so a stale library cannot load against newer
72+bindings. `just fetch v0.1.2` (or `COSMICNIM_TAG=v0.1.2 nimble fetchLib`)
73+overrides that when you want it.
74+
75+## As a dependency
76+
77+```bash
78+nimble install # fetches the cdylib too, and ships it with the package
79+```
80+
81+The binding resolves the library by absolute path at compile time, so an
82+installed package finds its `.so` in the nimble store without any rpath or
83+`LD_LIBRARY_PATH` fiddling. Override with `-d:libCosmicFfi=/some/path.so`.
84+
69 or build it yourself — the cold build is long, which is what the release CI is85 or build it yourself — the cold build is long, which is what the release CI is
70 for:86 for:
71 87
added cosmicnim.nimble +47 -0
new file mode 100644
@@ -0,0 +1,47 @@
1+version = "0.2.0"
2+author = "nandi"
3+description = "libcosmic behind a C ABI, driven from Nim"
4+license = "MIT"
5+srcDir = "nim"
6+installExt = @["nim", "so"] # the module, plus the cdylib beside it
7+
8+requires "nim >= 2.0.0"
9+
10+# The package version and the cdylib's ABI are the same thing: cosmicnim
11+# 0.2.0 speaks to the v0.2.0 release and no other. Resolving the tag from
12+# `version` is what keeps a stale library from loading against new bindings.
13+const
14+ BaseUrl = "https://rickub.com/nandi/cosmicnim"
15+ Target = "x86_64-unknown-linux-gnu"
16+ LibName = "libcosmic_ffi.so"
17+
18+proc fetchLibInto(dir: string) =
19+ # NimScript has no `/` path operator, hence the plain concatenation.
20+ let
21+ tag = getEnv("COSMICNIM_TAG", "v" & version)
22+ url = BaseUrl & "/releases/download/" & tag &
23+ "/cosmic_ffi-" & tag & "-" & Target & ".tar.gz"
24+ tmp = dir & "/.cosmicnim-fetch"
25+
26+ echo "fetching ", tag, " from ", BaseUrl
27+ rmDir tmp
28+ mkDir tmp
29+ exec "curl -fsSL -o '" & tmp & "/asset.tar.gz' '" & url & "'"
30+ # The workflow publishes a checksum beside every tarball.
31+ if gorgeEx("curl -fsSL -o '" & tmp & "/asset.sha256' '" &
32+ url & ".sha256'").exitCode == 0:
33+ exec "cd '" & tmp & "' && sed 's| .*| asset.tar.gz|' asset.sha256 | sha256sum -c -"
34+ else:
35+ echo "no .sha256 published alongside the asset; skipping checksum"
36+ exec "tar xzf '" & tmp & "/asset.tar.gz' -C '" & tmp & "'"
37+ exec "cp '" & tmp & "'/cosmic_ffi-*/" & LibName & " '" & dir & "/" & LibName & "'"
38+ rmDir tmp
39+ echo "installed ", dir & "/" & LibName
40+
41+task fetchLib, "Download the prebuilt cdylib matching this package version":
42+ fetchLibInto(srcDir)
43+
44+before install:
45+ # Ship the cdylib with the package, fetching it if it is not here yet.
46+ if not fileExists(srcDir & "/" & LibName):
47+ fetchLibInto(srcDir)
new file mode 100644
@@ -0,0 +1,47 @@
1+version = "0.2.0"
2+author = "nandi"
3+description = "libcosmic behind a C ABI, driven from Nim"
4+license = "MIT"
5+srcDir = "nim"
6+installExt = @["nim", "so"] # the module, plus the cdylib beside it
7+
8+requires "nim >= 2.0.0"
9+
10+# The package version and the cdylib's ABI are the same thing: cosmicnim
11+# 0.2.0 speaks to the v0.2.0 release and no other. Resolving the tag from
12+# `version` is what keeps a stale library from loading against new bindings.
13+const
14+ BaseUrl = "https://rickub.com/nandi/cosmicnim"
15+ Target = "x86_64-unknown-linux-gnu"
16+ LibName = "libcosmic_ffi.so"
17+
18+proc fetchLibInto(dir: string) =
19+ # NimScript has no `/` path operator, hence the plain concatenation.
20+ let
21+ tag = getEnv("COSMICNIM_TAG", "v" & version)
22+ url = BaseUrl & "/releases/download/" & tag &
23+ "/cosmic_ffi-" & tag & "-" & Target & ".tar.gz"
24+ tmp = dir & "/.cosmicnim-fetch"
25+
26+ echo "fetching ", tag, " from ", BaseUrl
27+ rmDir tmp
28+ mkDir tmp
29+ exec "curl -fsSL -o '" & tmp & "/asset.tar.gz' '" & url & "'"
30+ # The workflow publishes a checksum beside every tarball.
31+ if gorgeEx("curl -fsSL -o '" & tmp & "/asset.sha256' '" &
32+ url & ".sha256'").exitCode == 0:
33+ exec "cd '" & tmp & "' && sed 's| .*| asset.tar.gz|' asset.sha256 | sha256sum -c -"
34+ else:
35+ echo "no .sha256 published alongside the asset; skipping checksum"
36+ exec "tar xzf '" & tmp & "/asset.tar.gz' -C '" & tmp & "'"
37+ exec "cp '" & tmp & "'/cosmic_ffi-*/" & LibName & " '" & dir & "/" & LibName & "'"
38+ rmDir tmp
39+ echo "installed ", dir & "/" & LibName
40+
41+task fetchLib, "Download the prebuilt cdylib matching this package version":
42+ fetchLibInto(srcDir)
43+
44+before install:
45+ # Ship the cdylib with the package, fetching it if it is not here yet.
46+ if not fileExists(srcDir & "/" & LibName):
47+ fetchLibInto(srcDir)
modified justfile +11 -32
@@ -2,18 +2,16 @@
22
33 so := "nim/libcosmic_ffi.so"
44 export REMOTE := "rickub"
5-export BASE_URL := "https://rickub.com/nandi/cosmicnim"
6-export TARGET := "x86_64-unknown-linux-gnu"
75
86 default: run
97
10-# Run the Nim demo. Needs nim/libcosmic_ffi.so (see `fetch` or `build`).
8+# Run the demo gallery. Needs nim/libcosmic_ffi.so (see `fetch` or `build`).
119 run: _have-so
12- cd nim && nim c -r app.nim
10+ nim c -r --path:nim examples/gallery.nim
1311
1412 # Type-check the Nim side. Needs no .so: the binding loads it lazily.
1513 check:
16- cd nim && nim check app.nim
14+ nim check --path:nim examples/gallery.nim
1715
1816 # Build the cdylib from source into nim/ (cold builds are slow; CI is faster)
1917 build:
@@ -27,36 +25,17 @@ rust-check:
2725 fmt:
2826 cd cosmic_ffi && cargo fmt
2927
30-# Install the .so from a release. No tag means the newest v* tag on the remote.
28+# Download the cdylib. No tag means the one matching cosmicnim.nimble.
3129 fetch tag="":
3230 #!/usr/bin/env bash
3331 set -euo pipefail
34- tag="{{tag}}"
35- if [ -z "$tag" ]; then
36- # The remote is the source of truth; local tags may be stale or absent.
37- tag=$(git ls-remote --tags --refs "$REMOTE" 'v*' \
38- | awk -F/ '{print $NF}' | sort -V | tail -1)
39- [ -n "$tag" ] || { echo "no v* tags on $REMOTE" >&2; exit 1; }
40- echo "latest release is $tag"
41- fi
42- just fetch-url "$BASE_URL/releases/download/$tag/cosmic_ffi-$tag-$TARGET.tar.gz"
32+ # Only export when non-empty: an empty COSMICNIM_TAG would beat the default.
33+ [ -z "{{tag}}" ] || export COSMICNIM_TAG="{{tag}}"
34+ nimble fetchLib
4335
44-# Install the .so from an explicit asset URL.
45-fetch-url url:
46- #!/usr/bin/env bash
47- set -euo pipefail
48- tmp=$(mktemp -d)
49- trap 'rm -rf "$tmp"' EXIT
50- curl -fsSL -o "$tmp/asset.tar.gz" "{{url}}"
51- # The workflow publishes a checksum beside every tarball; use it if it is there.
52- if curl -fsSL -o "$tmp/asset.sha256" "{{url}}.sha256" 2>/dev/null; then
53- (cd "$tmp" && sed "s| .*| asset.tar.gz|" asset.sha256 | sha256sum -c -)
54- else
55- echo "no .sha256 alongside the asset; skipping checksum" >&2
56- fi
57- tar xzf "$tmp/asset.tar.gz" -C "$tmp"
58- cp "$tmp"/cosmic_ffi-*/libcosmic_ffi.so {{so}}
59- echo "installed {{so}}"
36+# Install the package (and its cdylib) into the local nimble store.
37+install:
38+ nimble install --verbose
6039
6140 # Cut a release by pushing a tag with git (an API-made tag triggers no CI)
6241 tag version:
@@ -64,7 +43,7 @@ tag version:
6443 git push "$REMOTE" "{{version}}"
6544
6645 clean:
67- rm -rf cosmic_ffi/target nim/nimcache nim/app
46+ rm -rf cosmic_ffi/target examples/nimcache examples/gallery
6847
6948 _have-so:
7049 @test -f {{so}} || { echo "missing {{so}} -- run 'just build' or 'just fetch <url>'" >&2; exit 1; }
@@ -2,18 +2,16 @@
2 2
3 so := "nim/libcosmic_ffi.so"3 so := "nim/libcosmic_ffi.so"
4 export REMOTE := "rickub"4 export REMOTE := "rickub"
5-export BASE_URL := "https://rickub.com/nandi/cosmicnim"
6-export TARGET := "x86_64-unknown-linux-gnu"
7 5
8 default: run6 default: run
9 7
10-# Run the Nim demo. Needs nim/libcosmic_ffi.so (see `fetch` or `build`).8+# Run the demo gallery. Needs nim/libcosmic_ffi.so (see `fetch` or `build`).
11 run: _have-so9 run: _have-so
12- cd nim && nim c -r app.nim10+ nim c -r --path:nim examples/gallery.nim
13 11
14 # Type-check the Nim side. Needs no .so: the binding loads it lazily.12 # Type-check the Nim side. Needs no .so: the binding loads it lazily.
15 check:13 check:
16- cd nim && nim check app.nim14+ nim check --path:nim examples/gallery.nim
17 15
18 # Build the cdylib from source into nim/ (cold builds are slow; CI is faster)16 # Build the cdylib from source into nim/ (cold builds are slow; CI is faster)
19 build:17 build:
@@ -27,36 +25,17 @@ rust-check:
27 fmt:25 fmt:
28 cd cosmic_ffi && cargo fmt26 cd cosmic_ffi && cargo fmt
29 27
30-# Install the .so from a release. No tag means the newest v* tag on the remote.28+# Download the cdylib. No tag means the one matching cosmicnim.nimble.
31 fetch tag="":29 fetch tag="":
32 #!/usr/bin/env bash30 #!/usr/bin/env bash
33 set -euo pipefail31 set -euo pipefail
34- tag="{{tag}}"32+ # Only export when non-empty: an empty COSMICNIM_TAG would beat the default.
35- if [ -z "$tag" ]; then33+ [ -z "{{tag}}" ] || export COSMICNIM_TAG="{{tag}}"
36- # The remote is the source of truth; local tags may be stale or absent.34+ nimble fetchLib
37- tag=$(git ls-remote --tags --refs "$REMOTE" 'v*' \
38- | awk -F/ '{print $NF}' | sort -V | tail -1)
39- [ -n "$tag" ] || { echo "no v* tags on $REMOTE" >&2; exit 1; }
40- echo "latest release is $tag"
41- fi
42- just fetch-url "$BASE_URL/releases/download/$tag/cosmic_ffi-$tag-$TARGET.tar.gz"
43 35
44-# Install the .so from an explicit asset URL.36+# Install the package (and its cdylib) into the local nimble store.
45-fetch-url url:37+install:
46- #!/usr/bin/env bash38+ nimble install --verbose
47- set -euo pipefail
48- tmp=$(mktemp -d)
49- trap 'rm -rf "$tmp"' EXIT
50- curl -fsSL -o "$tmp/asset.tar.gz" "{{url}}"
51- # The workflow publishes a checksum beside every tarball; use it if it is there.
52- if curl -fsSL -o "$tmp/asset.sha256" "{{url}}.sha256" 2>/dev/null; then
53- (cd "$tmp" && sed "s| .*| asset.tar.gz|" asset.sha256 | sha256sum -c -)
54- else
55- echo "no .sha256 alongside the asset; skipping checksum" >&2
56- fi
57- tar xzf "$tmp/asset.tar.gz" -C "$tmp"
58- cp "$tmp"/cosmic_ffi-*/libcosmic_ffi.so {{so}}
59- echo "installed {{so}}"
60 39
61 # Cut a release by pushing a tag with git (an API-made tag triggers no CI)40 # Cut a release by pushing a tag with git (an API-made tag triggers no CI)
62 tag version:41 tag version:
@@ -64,7 +43,7 @@ tag version:
64 git push "$REMOTE" "{{version}}"43 git push "$REMOTE" "{{version}}"
65 44
66 clean:45 clean:
67- rm -rf cosmic_ffi/target nim/nimcache nim/app46+ rm -rf cosmic_ffi/target examples/nimcache examples/gallery
68 47
69 _have-so:48 _have-so:
70 @test -f {{so}} || { echo "missing {{so}} -- run 'just build' or 'just fetch <url>'" >&2; exit 1; }49 @test -f {{so}} || { echo "missing {{so}} -- run 'just build' or 'just fetch <url>'" >&2; exit 1; }
added nim/app +0 -0
new file mode 100755
Binary files /dev/null and b/nim/app differ
new file mode 100755
Binary files /dev/null and b/nim/app differBinary files /dev/null and b/nim/app differ
deleted nim/app.nim +0 -80
deleted file mode 100644
@@ -1,80 +0,0 @@
1-## A counter whose state *and layout* live in Nim; libcosmic only draws it.
2-##
3-## The tree is rebuilt from scratch every frame, so it can depend on the
4-## state: reset is disabled at zero, and the history only appears once
5-## there is some.
6-
7-import std/[strformat, strutils]
8-import cosmic
9-
10-const
11- IdDec = 0'i32
12- IdInc = 1'i32
13- IdReset = 2'i32
14- IdStepDown = 3'i32
15- IdStepUp = 4'i32
16-
17-type Counter = object
18- value: int
19- step: int
20- history: seq[int]
21-
22-proc apply(c: var Counter; delta: int) =
23- c.history.add c.value
24- if c.history.len > 5:
25- c.history.delete(0)
26- c.value += delta
27-
28-proc onPress(ctx: pointer; id: int32) {.cdecl.} =
29- let c = cast[ptr Counter](ctx)
30- case id
31- of IdDec: c[].apply(-c.step)
32- of IdInc: c[].apply(c.step)
33- of IdReset: c[].apply(-c.value)
34- of IdStepDown: c.step = max(1, c.step div 2)
35- of IdStepUp: c.step = min(100, c.step * 2)
36- else: discard
37-
38-proc onView(ctx: pointer; b: Builder) {.cdecl.} =
39- let c = cast[ptr Counter](ctx)
40-
41- b.container:
42- b.fill()
43- b.alignCenter()
44- b.spacing(space(SpaceM))
45-
46- b.text(&"{c.value}", TextTitle1)
47-
48- b.row:
49- b.spacing(space(SpaceS))
50- b.alignCenter()
51- b.button(&"−{c.step}", IdDec)
52- b.button("Reset", IdReset, ButtonDestructive, enabled = c.value != 0)
53- b.button(&"+{c.step}", IdInc, ButtonSuggested)
54-
55- b.row:
56- b.spacing(space(SpaceXs))
57- b.alignCenter()
58- b.button("÷2", IdStepDown, ButtonText, enabled = c.step > 1)
59- b.text(&"step {c.step}", TextCaption)
60- b.button("×2", IdStepUp, ButtonText, enabled = c.step < 100)
61-
62- if c.history.len > 0:
63- b.text(c.history.join("") & "" & $c.value, TextCaption)
64-
65-proc main() =
66- var counter = Counter(value: 0, step: 1)
67- var config = CosmicConfig(
68- title: "Nim ❤ COSMIC",
69- onView: onView,
70- onPress: onPress,
71- ctx: addr counter,
72- width: 460,
73- height: 320,
74- )
75- let rc = cosmicRun(addr config)
76- if rc != 0:
77- quit(&"cosmic_run failed: {rc}", 1)
78- echo &"final count: {counter.value}"
79-
80-main()
deleted file mode 100644
@@ -1,80 +0,0 @@
1-## A counter whose state *and layout* live in Nim; libcosmic only draws it.
2-##
3-## The tree is rebuilt from scratch every frame, so it can depend on the
4-## state: reset is disabled at zero, and the history only appears once
5-## there is some.
6-
7-import std/[strformat, strutils]
8-import cosmic
9-
10-const
11- IdDec = 0'i32
12- IdInc = 1'i32
13- IdReset = 2'i32
14- IdStepDown = 3'i32
15- IdStepUp = 4'i32
16-
17-type Counter = object
18- value: int
19- step: int
20- history: seq[int]
21-
22-proc apply(c: var Counter; delta: int) =
23- c.history.add c.value
24- if c.history.len > 5:
25- c.history.delete(0)
26- c.value += delta
27-
28-proc onPress(ctx: pointer; id: int32) {.cdecl.} =
29- let c = cast[ptr Counter](ctx)
30- case id
31- of IdDec: c[].apply(-c.step)
32- of IdInc: c[].apply(c.step)
33- of IdReset: c[].apply(-c.value)
34- of IdStepDown: c.step = max(1, c.step div 2)
35- of IdStepUp: c.step = min(100, c.step * 2)
36- else: discard
37-
38-proc onView(ctx: pointer; b: Builder) {.cdecl.} =
39- let c = cast[ptr Counter](ctx)
40-
41- b.container:
42- b.fill()
43- b.alignCenter()
44- b.spacing(space(SpaceM))
45-
46- b.text(&"{c.value}", TextTitle1)
47-
48- b.row:
49- b.spacing(space(SpaceS))
50- b.alignCenter()
51- b.button(&"−{c.step}", IdDec)
52- b.button("Reset", IdReset, ButtonDestructive, enabled = c.value != 0)
53- b.button(&"+{c.step}", IdInc, ButtonSuggested)
54-
55- b.row:
56- b.spacing(space(SpaceXs))
57- b.alignCenter()
58- b.button("÷2", IdStepDown, ButtonText, enabled = c.step > 1)
59- b.text(&"step {c.step}", TextCaption)
60- b.button("×2", IdStepUp, ButtonText, enabled = c.step < 100)
61-
62- if c.history.len > 0:
63- b.text(c.history.join("") & "" & $c.value, TextCaption)
64-
65-proc main() =
66- var counter = Counter(value: 0, step: 1)
67- var config = CosmicConfig(
68- title: "Nim ❤ COSMIC",
69- onView: onView,
70- onPress: onPress,
71- ctx: addr counter,
72- width: 460,
73- height: 320,
74- )
75- let rc = cosmicRun(addr config)
76- if rc != 0:
77- quit(&"cosmic_run failed: {rc}", 1)
78- echo &"final count: {counter.value}"
79-
80-main()
deleted nim/app.nims +0 -1
deleted file mode 100644
@@ -1 +0,0 @@
1-switch("passL", "-Wl,-rpath,$ORIGIN:$ORIGIN/../lib")
deleted file mode 100644
@@ -1 +0,0 @@
1-switch("passL", "-Wl,-rpath,$ORIGIN:$ORIGIN/../lib")
renamed nim/cosmicnim.nim +7 -1
similarity index 92%
rename from nim/cosmic.nim
rename to nim/cosmicnim.nim
@@ -14,7 +14,13 @@
1414 ## b.button("+", id = 1, style = ButtonSuggested)
1515 ## ```
1616
17-const libCosmicFfi* = "libcosmic_ffi.so"
17+import std/os
18+
19+const libCosmicFfi* {.strdefine.} = currentSourcePath().parentDir /
20+ "libcosmic_ffi.so"
21+ ## Absolute at compile time, so the library is found wherever nimble put
22+ ## the package rather than only next to the binary. Override with
23+ ## `-d:libCosmicFfi=/some/other/libcosmic_ffi.so`.
1824
1925 type
2026 Builder* = distinct pointer
similarity index 92%
rename from nim/cosmic.nim
rename to nim/cosmicnim.nim
@@ -14,7 +14,13 @@
14 ## b.button("+", id = 1, style = ButtonSuggested)14 ## b.button("+", id = 1, style = ButtonSuggested)
15 ## ```15 ## ```
16 16
17-const libCosmicFfi* = "libcosmic_ffi.so"17+import std/os
18+
19+const libCosmicFfi* {.strdefine.} = currentSourcePath().parentDir /
20+ "libcosmic_ffi.so"
21+ ## Absolute at compile time, so the library is found wherever nimble put
22+ ## the package rather than only next to the binary. Override with
23+ ## `-d:libCosmicFfi=/some/other/libcosmic_ffi.so`.
18 24
19 type25 type
20 Builder* = distinct pointer26 Builder* = distinct pointer