mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-19 16:16:48 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e87bcbff2 | ||
|
|
fcd7527c9d | ||
|
|
83d1630f55 | ||
|
|
cfb925e5ae | ||
|
|
515b0549ef | ||
|
|
8ea47df13e | ||
|
|
42ab831d97 | ||
|
|
89b4046d11 | ||
|
|
7ec6f8e2f2 | ||
|
|
5f7fa17ad8 | ||
|
|
30d59d4458 | ||
|
|
02dc36080c | ||
|
|
8734847968 | ||
|
|
608cd00764 | ||
|
|
b13727abde | ||
|
|
231aac15cd | ||
|
|
8b17d5f35e | ||
|
|
8608b2be46 | ||
|
|
1e0bd54989 | ||
|
|
56285fc6e5 | ||
|
|
dfe053a0ae | ||
|
|
12ac368e8b | ||
|
|
c8f32f9f25 | ||
|
|
ce3737ff33 | ||
|
|
84e4cdeb7e | ||
|
|
6d6d73c7b3 | ||
|
|
bea31543a0 | ||
|
|
99835a0178 | ||
|
|
342a1efcfb | ||
|
|
c587a127fb | ||
|
|
f1034a3ad6 | ||
|
|
8117998205 | ||
|
|
cc780bc521 | ||
|
|
14b7c8e607 | ||
|
|
3ff9794fff | ||
|
|
f71e27644e | ||
|
|
943f91ff98 | ||
|
|
ef1e01b5a5 | ||
|
|
50c0627b2b | ||
|
|
660f556ac6 | ||
|
|
997b036064 | ||
|
|
9308a3729c | ||
|
|
7616d8b1ac | ||
|
|
a86092b3c2 | ||
|
|
e613d9415f | ||
|
|
1a8eb326af | ||
|
|
9fb1642e93 | ||
|
|
8be86ee611 | ||
|
|
da68cf3a85 | ||
|
|
ec40866091 | ||
|
|
bd0714272e | ||
|
|
27acd9fcc7 | ||
|
|
4516685ca7 | ||
|
|
0bdbaf1d6c | ||
|
|
e67b7d0825 | ||
|
|
981d5473ee | ||
|
|
364f8c4407 | ||
|
|
ef9c7ad5df | ||
|
|
4288a60c5d | ||
|
|
cf38a37176 | ||
|
|
f5d9a60b9d | ||
|
|
0c17492c78 | ||
|
|
98648ae44b | ||
|
|
0dcca0f1a3 | ||
|
|
103cd358f2 | ||
|
|
aa46001923 | ||
|
|
ff48ff6047 | ||
|
|
d5a2187713 | ||
|
|
351adc2b20 | ||
|
|
a1e681f36b | ||
|
|
e3a467de80 | ||
|
|
cdadda5eb9 | ||
|
|
4c9a9d7e15 | ||
|
|
425e30b50f | ||
|
|
3905355522 | ||
|
|
9e2e1afafa | ||
|
|
6d218fa87f | ||
|
|
3b10406f95 | ||
|
|
f2c8e5d9eb | ||
|
|
b581c5d5e7 | ||
|
|
1ebc8cfa5f | ||
|
|
acfa797503 | ||
|
|
7fc20457ca | ||
|
|
ecee84b323 | ||
|
|
b8776d205d | ||
|
|
06433a0548 | ||
|
|
f4b602340b | ||
|
|
a78aef36e0 | ||
|
|
0d05523dfd | ||
|
|
0cfab60f37 | ||
|
|
21966ade97 | ||
|
|
96eb51eecb | ||
|
|
881147daa2 | ||
|
|
0f1a8e9b69 | ||
|
|
08f9cc6932 | ||
|
|
3099b15db1 | ||
|
|
07b1e6bdba | ||
|
|
7763c7384a | ||
|
|
61365d226d | ||
|
|
f33e78bc24 | ||
|
|
7f52623536 | ||
|
|
a30a4df9c0 | ||
|
|
1e0d5aa91d | ||
|
|
d09fadbc28 | ||
|
|
21ce889449 | ||
|
|
9d1a4696e9 | ||
|
|
ed0cbcf064 | ||
|
|
076e359891 | ||
|
|
bf98d3f3a6 | ||
|
|
c45c5ce920 | ||
|
|
e0a892f0d0 | ||
|
|
164b7f73c9 | ||
|
|
3a45be4cd8 | ||
|
|
107a3acf95 | ||
|
|
a5eafb8972 | ||
|
|
8199cc8a8b | ||
|
|
e5d897f3dc | ||
|
|
c0af09f7d8 | ||
|
|
1b1e14ca29 | ||
|
|
82b89aa099 | ||
|
|
aa91e1b2ba | ||
|
|
82e81afcdc | ||
|
|
1a5c39f813 | ||
|
|
fce1803d42 | ||
|
|
5a9a17afcb | ||
|
|
8648de6bb6 | ||
|
|
f227a63e15 | ||
|
|
aa47b74dea | ||
|
|
206ad1dd53 | ||
|
|
80aead7085 | ||
|
|
1220befacf | ||
|
|
01aa888c7a | ||
|
|
6a6aa054cd | ||
|
|
04939bbe72 | ||
|
|
2ea6290e4b | ||
|
|
c66c68b137 | ||
|
|
075a8a6548 | ||
|
|
3c6d1b47f6 | ||
|
|
6f281b9f7f | ||
|
|
511bf47af9 | ||
|
|
53c5a2cf1e | ||
|
|
eb8074ed9a | ||
|
|
38c19df95a | ||
|
|
b1228f11bd | ||
|
|
cfafafd7ff | ||
|
|
c8ce82ce54 | ||
|
|
05c3d97368 | ||
|
|
2c87e68635 | ||
|
|
8f1ef59770 | ||
|
|
a460c52861 | ||
|
|
a4aade6666 | ||
|
|
1d1bcd3b87 | ||
|
|
099ce2d91d | ||
|
|
56cd831ec8 | ||
|
|
e43be3c221 | ||
|
|
2754536727 | ||
|
|
a0cff637e1 | ||
|
|
a5a6c892b9 | ||
|
|
3d50d4a52f | ||
|
|
f69c31fd77 | ||
|
|
a2860c3f1f | ||
|
|
3f70e66ee3 | ||
|
|
160d3c832d | ||
|
|
15bcc47d6a | ||
|
|
e55bb93890 | ||
|
|
5a2a9e4530 | ||
|
|
b4239495a0 | ||
|
|
3222de6c9c | ||
|
|
be4d388813 | ||
|
|
a47842e2f8 | ||
|
|
f769d7474b | ||
|
|
2ae57642f4 | ||
|
|
7f1b7ac343 | ||
|
|
1290ab9708 | ||
|
|
965e26989c | ||
|
|
0caae4fbf0 | ||
|
|
4d1760cb69 | ||
|
|
22df87c86a | ||
|
|
72fb6e4aba | ||
|
|
9b046d9a34 | ||
|
|
d8918458bf | ||
|
|
d3a3f65e7b | ||
|
|
411d181473 | ||
|
|
caf7915003 | ||
|
|
4c5473d569 | ||
|
|
104f378c2c | ||
|
|
a364405cf0 | ||
|
|
960f5fdbba | ||
|
|
6813a51fce | ||
|
|
f7e86d90ce | ||
|
|
66d120c721 | ||
|
|
01973214bf | ||
|
|
af1edadf72 | ||
|
|
3bacaa6f7f | ||
|
|
b6e1a08aef | ||
|
|
47bd4259b8 | ||
|
|
dc486e79ce | ||
|
|
78551049d5 | ||
|
|
4aab008233 | ||
|
|
3a7a4a13e7 | ||
|
|
41b65ae9e8 | ||
|
|
2412ae7316 | ||
|
|
ec16d07fba | ||
|
|
37f10888a9 | ||
|
|
0db8a1ed6a | ||
|
|
cfaad60275 | ||
|
|
077484323c | ||
|
|
700fcfccf5 | ||
|
|
4b4801add6 | ||
|
|
741128cb23 | ||
|
|
3bee0f0b57 | ||
|
|
727c522fb8 | ||
|
|
00e5467e99 | ||
|
|
0371f03def | ||
|
|
d18c273293 | ||
|
|
0f24bb29ac | ||
|
|
3cb35a3a65 | ||
|
|
25b0bc72df | ||
|
|
e6fcebe4f3 | ||
|
|
46f85c0f6d | ||
|
|
7a9c3b7eb2 | ||
|
|
569a151da2 | ||
|
|
2f3e807e9d | ||
|
|
95ab37fdd2 | ||
|
|
1707dc27e3 | ||
|
|
c4126a0796 | ||
|
|
6acef3a638 | ||
|
|
b3656a0243 | ||
|
|
41b40b94fa | ||
|
|
ca59ae53a5 | ||
|
|
8c649d33ee | ||
|
|
f64ff9ca1e | ||
|
|
99c28ad3bc | ||
|
|
5becb334cd | ||
|
|
071af2e516 | ||
|
|
90b3585347 | ||
|
|
d7549f8d53 | ||
|
|
6ac7f389c5 | ||
|
|
2101ef5bcc | ||
|
|
dd1bea52cd | ||
|
|
df19f99976 | ||
|
|
24e778b95a | ||
|
|
a8a7b34cf3 | ||
|
|
6ae9641bcc | ||
|
|
4439c2a030 | ||
|
|
9872710720 | ||
|
|
b18aba86b6 | ||
|
|
33fc26f81f | ||
|
|
e8cd74cab0 | ||
|
|
2b500f194a | ||
|
|
e87867cd2a | ||
|
|
fa851eda3a | ||
|
|
f852474073 | ||
|
|
9e626228be | ||
|
|
71ddae8713 | ||
|
|
e216a81a27 | ||
|
|
264c5600f8 | ||
|
|
be49dbe1bd | ||
|
|
eb124316c9 | ||
|
|
77ef88b04c | ||
|
|
34f07e57f5 | ||
|
|
095fcf82a3 | ||
|
|
1b167d34d8 | ||
|
|
23824eaeb4 | ||
|
|
e310d24615 | ||
|
|
92312c8507 | ||
|
|
4b751c2d37 | ||
|
|
86b50d2d4e | ||
|
|
7e084ea7db | ||
|
|
6eca711f58 | ||
|
|
923d9608e8 | ||
|
|
3a034712f6 | ||
|
|
5db04b4b5f | ||
|
|
fa3266ca7f | ||
|
|
344014aa81 | ||
|
|
455a81290b | ||
|
|
deb54c58d8 | ||
|
|
2b04a791b7 | ||
|
|
8ee998e8aa | ||
|
|
de2a82800a | ||
|
|
212681ddc5 | ||
|
|
9dac54f223 | ||
|
|
78fa34098e | ||
|
|
54681e885a | ||
|
|
de5a871326 | ||
|
|
77bf16e9ae | ||
|
|
ad54c8be19 | ||
|
|
c769e959e8 | ||
|
|
1f3ebcf418 | ||
|
|
80085c9844 | ||
|
|
b85cc8c370 | ||
|
|
95732222d9 | ||
|
|
17a551d0a4 | ||
|
|
f74dc36e92 | ||
|
|
764bd8f7be | ||
|
|
b7f7f7fa97 | ||
|
|
7f410073d4 | ||
|
|
92ae63e842 | ||
|
|
d31e97e64c | ||
|
|
579690f411 | ||
|
|
ca449a73be | ||
|
|
2d86ed946a | ||
|
|
3e454f528c | ||
|
|
a4fdbae1ca | ||
|
|
aff66812c0 | ||
|
|
6472ac51e9 | ||
|
|
d3770802b1 | ||
|
|
bcbff5c82e | ||
|
|
09743ee187 | ||
|
|
3a33a6db2b | ||
|
|
c0d5f4795a | ||
|
|
ef9074ab4a | ||
|
|
2d03b89c2d | ||
|
|
64cc63b2bc | ||
|
|
514c478a39 | ||
|
|
8179f91c48 | ||
|
|
371764d800 | ||
|
|
1c44ef7967 | ||
|
|
aa97bac533 | ||
|
|
12d6302457 | ||
|
|
740fc3f84a | ||
|
|
f18719ced2 | ||
|
|
366f5fcc4c | ||
|
|
1729835b8c | ||
|
|
1180fd6dd3 | ||
|
|
19509e33d2 | ||
|
|
8f355d7dd5 | ||
|
|
2aa9697c87 | ||
|
|
978d067921 | ||
|
|
b83bd5fd14 | ||
|
|
dd906c8a4c | ||
|
|
6fb9111c03 | ||
|
|
bc382e0fd2 | ||
|
|
0197984db3 | ||
|
|
248b1aca1c | ||
|
|
9056898bbf | ||
|
|
5e584f246a | ||
|
|
7e964283b9 | ||
|
|
03dc17fff2 | ||
|
|
8cb68dce4a | ||
|
|
28260c434a | ||
|
|
fae9b993fe | ||
|
|
171eb9c7c0 | ||
|
|
174e703d2e | ||
|
|
efd0dfaa2f | ||
|
|
75d7a93724 | ||
|
|
50fa7ac694 | ||
|
|
7d64a47b88 | ||
|
|
5fba42f076 | ||
|
|
b0bb7ef38c | ||
|
|
85ce7d6178 | ||
|
|
40359df453 | ||
|
|
9b2a5a75ee | ||
|
|
b21172c609 | ||
|
|
f0444a1ca9 | ||
|
|
977d04229f | ||
|
|
757ae66327 | ||
|
|
42d0b5734c | ||
|
|
78050ed6b0 | ||
|
|
19ee44afe7 | ||
|
|
a234e9446c | ||
|
|
951eb9540d | ||
|
|
85a936c95e | ||
|
|
8210e63a66 | ||
|
|
facdb66746 | ||
|
|
1916e54a24 | ||
|
|
7fabe515f4 | ||
|
|
0ca5d6aad0 | ||
|
|
0c1aeb411d | ||
|
|
17fdbf7f42 | ||
|
|
27349e41ef | ||
|
|
b3ce95c422 | ||
|
|
cedc9f0f25 | ||
|
|
d68ad9ac01 | ||
|
|
ae6c4f7c25 | ||
|
|
87475098a1 | ||
|
|
d4dc0701d6 | ||
|
|
c1c2f075ee | ||
|
|
96d34f1eab | ||
|
|
f66fb7e2d4 | ||
|
|
edb3368078 | ||
|
|
bd70928268 | ||
|
|
337aade02d | ||
|
|
d6a2f06797 | ||
|
|
7890a4996c | ||
|
|
6aa6452d3e | ||
|
|
7d6c8e9333 | ||
|
|
a7069153bd | ||
|
|
5c71a75fdd | ||
|
|
fd33df04a3 | ||
|
|
a9ae36a3e4 | ||
|
|
569537df9e | ||
|
|
8534ee7ceb | ||
|
|
620cab2948 | ||
|
|
8635456818 | ||
|
|
0888f372aa | ||
|
|
e09b10c55b | ||
|
|
766b923116 | ||
|
|
dd7e9e2aa7 | ||
|
|
3fc0aa3809 | ||
|
|
b1dcc94e98 | ||
|
|
6d2c99e487 | ||
|
|
9d9eacfe7b | ||
|
|
b91cc1c191 | ||
|
|
6d2f26c60e | ||
|
|
0a94bd7cfc | ||
|
|
211e6c7115 | ||
|
|
335ca55a6e | ||
|
|
69de4de53f | ||
|
|
76c8d48dbd | ||
|
|
a927a15e9c | ||
|
|
0c555e71a0 | ||
|
|
82781b6ff8 | ||
|
|
b545352712 | ||
|
|
3d05999db0 | ||
|
|
f4a8105a42 | ||
|
|
004b616115 | ||
|
|
8d7017273f | ||
|
|
51b65cd126 | ||
|
|
0ed03a1535 | ||
|
|
b6d3c34d3f | ||
|
|
fdecabfaab | ||
|
|
3a1d8e03a1 | ||
|
|
e586d2fd1e | ||
|
|
e0087cd8a7 | ||
|
|
2377cb05b6 | ||
|
|
a8ffbc84f6 | ||
|
|
0aafdefc18 | ||
|
|
7221fded71 | ||
|
|
7a09f560f7 | ||
|
|
8b769dff7f | ||
|
|
6dcf6111af | ||
|
|
9849bcd3cf | ||
|
|
c92a10021e | ||
|
|
d817fa4e97 | ||
|
|
eb141c4c4e | ||
|
|
282ce08ddb | ||
|
|
51d97bb444 | ||
|
|
539f2221a3 | ||
|
|
2b1804d364 | ||
|
|
556c6522c0 | ||
|
|
543603bdfc | ||
|
|
7a86ed6508 | ||
|
|
707d298d7c | ||
|
|
36a4b7a23a | ||
|
|
22833bdfe2 | ||
|
|
775c3cad90 | ||
|
|
fa537961c5 | ||
|
|
ee13810f3b | ||
|
|
5d6c9cc56a | ||
|
|
832903378e | ||
|
|
2722f4f64d | ||
|
|
7cdd12bda4 | ||
|
|
5ab0fbcaee | ||
|
|
42836e0961 | ||
|
|
6a14a10e6c | ||
|
|
82430e1079 | ||
|
|
701f88de43 | ||
|
|
c72997f298 | ||
|
|
c681d6c2fe | ||
|
|
6bc3d77992 |
-512
@@ -1,512 +0,0 @@
|
||||
freebsd_task:
|
||||
name: "freebsd:11.4"
|
||||
freebsd_instance:
|
||||
image_family: freebsd-11-4
|
||||
env:
|
||||
ASSUME_ALWAYS_YES: yes
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- gmake -j4
|
||||
|
||||
freebsd_task:
|
||||
name: "freebsd:12.1"
|
||||
freebsd_instance:
|
||||
image_family: freebsd-12-1
|
||||
env:
|
||||
ASSUME_ALWAYS_YES: yes
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- gmake -j4
|
||||
|
||||
freebsd_task:
|
||||
name: "freebsd:12.2"
|
||||
freebsd_instance:
|
||||
image_family: freebsd-12-2
|
||||
env:
|
||||
ASSUME_ALWAYS_YES: yes
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- gmake -j4
|
||||
|
||||
freebsd_task:
|
||||
name: "freebsd:13.0"
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-0
|
||||
env:
|
||||
ASSUME_ALWAYS_YES: yes
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- gmake -j4
|
||||
|
||||
|
||||
#macos_task:
|
||||
# osx_instance:
|
||||
# image: catalina-base
|
||||
# script:
|
||||
# - tools/install-build-pkgs
|
||||
# - gmake -j4
|
||||
|
||||
linux_task:
|
||||
name: "alpine:3.11"
|
||||
container:
|
||||
image: alpine:3.11
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make STATIC=1 LTO=1
|
||||
|
||||
linux_task:
|
||||
name: "alpine:3.12"
|
||||
container:
|
||||
image: alpine:3.12
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make STATIC=1 LTO=1
|
||||
|
||||
linux_task:
|
||||
name: "alpine:3.13"
|
||||
container:
|
||||
image: alpine:3.13
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make STATIC=1 LTO=1
|
||||
|
||||
linux_task:
|
||||
name: "alpine:3.14"
|
||||
container:
|
||||
image: alpine:3.14
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make STATIC=1 LTO=1
|
||||
|
||||
linux_task:
|
||||
name: "alpine:3.15"
|
||||
container:
|
||||
image: alpine:3.15
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make STATIC=1 LTO=1
|
||||
|
||||
linux_task:
|
||||
name: "alpine:3.16"
|
||||
container:
|
||||
image: alpine:3.16
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make STATIC=1 LTO=1
|
||||
|
||||
linux_task:
|
||||
name: "alpine:3.17"
|
||||
container:
|
||||
image: alpine:3.17
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make STATIC=1 LTO=1
|
||||
|
||||
linux_task:
|
||||
name: "alpine:latest"
|
||||
container:
|
||||
image: alpine:latest
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make STATIC=1 LTO=1
|
||||
|
||||
linux_task:
|
||||
name: "alpine-arm:latest"
|
||||
arm_container:
|
||||
image: alpine:latest
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make STATIC=1 LTO=1
|
||||
|
||||
linux_task:
|
||||
name: "centos:7"
|
||||
container:
|
||||
image: centos:7
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "rocky:8"
|
||||
container:
|
||||
image: rocky:8
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:30"
|
||||
container:
|
||||
image: fedora:30
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:31"
|
||||
container:
|
||||
image: fedora:31
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:32"
|
||||
container:
|
||||
image: fedora:32
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:33"
|
||||
container:
|
||||
image: fedora:33
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:34"
|
||||
container:
|
||||
image: fedora:34
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:35"
|
||||
container:
|
||||
image: fedora:35
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:36"
|
||||
container:
|
||||
image: fedora:36
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:37"
|
||||
container:
|
||||
image: fedora:37
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:38"
|
||||
container:
|
||||
image: fedora:38
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora:latest"
|
||||
container:
|
||||
image: fedora:latest
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "fedora-arm:latest"
|
||||
arm_container:
|
||||
image: fedora:latest
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- make
|
||||
- make rpm
|
||||
|
||||
linux_task:
|
||||
name: "ubuntu:14.04"
|
||||
container:
|
||||
image: ubuntu:14.04
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "ubuntu:16.04"
|
||||
container:
|
||||
image: ubuntu:16.04
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "ubuntu:18.04"
|
||||
container:
|
||||
image: ubuntu:18.04
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "ubuntu:20.04"
|
||||
container:
|
||||
image: ubuntu:20.04
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "ubuntu:22.04"
|
||||
container:
|
||||
image: ubuntu:22.04
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "ubuntu:latest"
|
||||
container:
|
||||
image: ubuntu:latest
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "ubuntu-arm:latest"
|
||||
arm_container:
|
||||
image: ubuntu:latest
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "debian:7"
|
||||
container:
|
||||
image: debian:8
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "debian:8"
|
||||
container:
|
||||
image: debian:8
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "debian:9"
|
||||
container:
|
||||
image: debian:9
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "debian:10"
|
||||
container:
|
||||
image: debian:10
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "debian:11"
|
||||
container:
|
||||
image: debian:11
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "debian:latest"
|
||||
container:
|
||||
image: debian:latest
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
|
||||
linux_task:
|
||||
name: "debian-arm:latest"
|
||||
arm_container:
|
||||
image: debian:latest
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
timeout_in: 15m
|
||||
script:
|
||||
- tools/install-build-pkgs
|
||||
- git fetch
|
||||
- make deb
|
||||
- apt-get -y install fuse
|
||||
- dpkg -i ../*.deb
|
||||
- mergerfs -v || true
|
||||
+1
-6
@@ -1,7 +1,2 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [trapexit]
|
||||
patreon: trapexit
|
||||
custom: ['https://paypal.me/trapexit','https://buymeacoff.ee/trapexit']
|
||||
ko_fi: trapexit
|
||||
open_collective: trapexit
|
||||
custom: ['https://github.com/trapexit/support']
|
||||
|
||||
@@ -7,22 +7,31 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
See also https://trapexit.github.io/mergerfs/latest/support
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
A clear and concise description of the unexpected behavior.
|
||||
|
||||
**Please be sure to use latest release of mergerfs to ensure the issue still exists. Not your distro's latest but the latest official release.**
|
||||
**Please be sure to use latest release of mergerfs to ensure the issue
|
||||
still exists. Not your distro's latest but the latest official
|
||||
release. Support will NOT be provided for old versions.**
|
||||
|
||||
The master branch is **not** to be considered production ready. Feel free to file bug reports but do so indicating clearly that you are testing unreleased code.
|
||||
The `master` branch is **not** to be considered production ready. Feel
|
||||
free to file bug reports but do so indicating clearly that you are
|
||||
testing unreleased code.
|
||||
|
||||
|
||||
**To Reproduce**
|
||||
|
||||
Steps to reproduce the behavior. List **all** steps to reproduce. **All** settings.
|
||||
Provide steps to reproduce the behavior. List **all** steps to
|
||||
reproduce. **All** settings. The version of all software involved.
|
||||
|
||||
Please simplify the reproduction as much as possible.
|
||||
- Unless it is dependenat on multiple branches, use a single branch
|
||||
- Reproduce with standard tooling if possible (touch,truncate,rm,rmdir,ln,etc.) Having to install 3rd party software will make debugging more difficult.
|
||||
* Unless it is dependenat on multiple branches, use a single branch
|
||||
* Reproduce with standard tooling if possible
|
||||
(touch,truncate,rm,rmdir,ln,etc.) Having to install 3rd party
|
||||
software will make debugging more difficult.
|
||||
|
||||
|
||||
**Expected behavior**
|
||||
@@ -30,19 +39,38 @@ Please simplify the reproduction as much as possible.
|
||||
A clear and concise description of the expected behavior.
|
||||
|
||||
|
||||
**Workarounds already tested**
|
||||
|
||||
Please list all workarounds attempted and why they were ruled out as
|
||||
options.
|
||||
|
||||
|
||||
**System information:**
|
||||
|
||||
- OS, kernel version: `uname -a`
|
||||
- mergerfs version: `mergerfs -V`
|
||||
- mergerfs settings
|
||||
- List of drives, filesystems, & sizes:
|
||||
- `df -h`
|
||||
- `lsblk -f`
|
||||
- A strace of the application having a problem:
|
||||
- `strace -fvTtt -s 256 -o /tmp/app.strace.txt <cmd>`
|
||||
- `strace -fvTtt -s 256 -o /tmp/app.strace.txt -p <appPID>`
|
||||
- strace of mergerfs while app tried to do it's thing:
|
||||
- `strace -fvTtt -s 256 -p <mergerfsPID> -o /tmp/mergerfs.strace.txt`
|
||||
* Attach output from
|
||||
[mergerfs.collect-info](https://trapexit.github.io/mergerfs/latest/tooling/#mergerfscollect-info)
|
||||
tool.
|
||||
* Alternatively:
|
||||
* OS: `lsb_release -a`
|
||||
* kernel version: `uname -a`
|
||||
* mergerfs version: `mergerfs --version`
|
||||
* mergerfs settings / arguments: from fstab, systemd unit, command
|
||||
line, OMV plugin, etc.
|
||||
* List of drives, filesystems, & sizes:
|
||||
* `df -h`
|
||||
* `lsblk -o NAME,FSTYPE,FSSIZE,SIZE,MOUNTPOINTS,RM,RO,ROTA`
|
||||
* All information about the relevant paths and files: permissions,
|
||||
ownership, etc.
|
||||
* All information about the application making the requests:
|
||||
version, uid/gid
|
||||
* Is mergerfs running within a container or used with container
|
||||
technologies?
|
||||
* Are the client apps using mergerfs running in a container?
|
||||
* A strace of the application having a problem:
|
||||
* `strace -fvTtt -s 256 -o /tmp/app.strace.txt <cmd>`
|
||||
* `strace -fvTtt -s 256 -o /tmp/app.strace.txt -p <appPID>`
|
||||
* strace of mergerfs while app tried to do it's thing:
|
||||
* `strace -fvTtt -s 256 -p <mergerfsPID> -o /tmp/mergerfs.strace.txt`
|
||||
|
||||
**Additional context**
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: "7 3 * * 6"
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ python, cpp ]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
if: ${{ matrix.language == 'python' || matrix.language == 'cpp' }}
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
+9
-1
@@ -14,12 +14,20 @@
|
||||
|
||||
# build artifacts
|
||||
mergerfs
|
||||
obj/
|
||||
build/
|
||||
src/version.hpp
|
||||
VERSION
|
||||
|
||||
# Debian files
|
||||
debian/files
|
||||
debian/changelog
|
||||
debian/debhelper-build-stamp
|
||||
debian/mergerfs.debhelper.log
|
||||
debian/mergerfs.substvars
|
||||
|
||||
# RPM files
|
||||
rpmbuild/
|
||||
|
||||
# mkdocs files
|
||||
mkdocs/venv
|
||||
__pycache__/
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
## Libraries
|
||||
|
||||
### included in repo
|
||||
|
||||
* libfuse: https://github.com/libfuse/libfuse (heavily modified fork of v2.x)
|
||||
* rapidhash: https://github.com/Nicoshev/rapidhash
|
||||
* fmt: https://github.com/fmtlib/fmt
|
||||
* concurrentqueue: https://github.com/cameron314/concurrentqueue
|
||||
* scope_guard: https://github.com/Neargye/scope_guard
|
||||
* subprocess: https://github.com/arun11299/cpp-subprocess
|
||||
* CLI11: https://github.com/CLIUtils/CLI11
|
||||
* string-lite: https://github.com/martinmoene/string-lite
|
||||
* boost
|
||||
* download boost
|
||||
* ./bootstrap.sh
|
||||
* ./b2 tools/bcp
|
||||
* ./dist/bin/bcp unordered/concurrent_flat_map.hpp <target_dir>
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2023, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
Copyright (c) 2026, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
# Copyright (c) 2025, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -12,182 +12,279 @@
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
GIT = git
|
||||
TAR = tar
|
||||
MKDIR = mkdir
|
||||
TOUCH = touch
|
||||
CP = cp
|
||||
RM = rm
|
||||
LN = ln
|
||||
FIND = find
|
||||
INSTALL = install
|
||||
MKTEMP = mktemp
|
||||
STRIP = strip
|
||||
PANDOC = pandoc
|
||||
SED = sed
|
||||
RPMBUILD = rpmbuild
|
||||
GIT2DEBCL = ./tools/git2debcl
|
||||
PKGCONFIG = pkg-config
|
||||
$(info mergerfs MAKEFLAGS: $(MAKEFLAGS))
|
||||
|
||||
GIT_REPO = 0
|
||||
ifeq ($(shell id -u),0)
|
||||
FAKEROOT ?=
|
||||
endif
|
||||
|
||||
CP ?= cp
|
||||
FAKEROOT ?= fakeroot
|
||||
FIND ?= find
|
||||
GIT ?= git
|
||||
GIT2DEBCL ?= buildtools/git2debcl
|
||||
INSTALL ?= install
|
||||
LN ?= ln
|
||||
MKDIR ?= mkdir
|
||||
MKTEMP ?= mktemp
|
||||
MV ?= mv
|
||||
RM ?= rm
|
||||
RPMBUILD ?= rpmbuild
|
||||
RPMBUILD_FLAGS ?=
|
||||
SED ?= sed
|
||||
STRIP ?= strip
|
||||
TAR ?= tar
|
||||
TOUCH ?= touch
|
||||
|
||||
BUILDDIR := build
|
||||
GITHUB_REPO ?= "https://github.com/trapexit/mergerfs"
|
||||
|
||||
DEFAULT_TARGET := debian:13.amd64
|
||||
|
||||
ifndef GIT_REPO
|
||||
ifneq ($(shell $(GIT) --version 2> /dev/null),)
|
||||
ifeq ($(shell test -e .git; echo $$?),0)
|
||||
GIT_REPO = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
USE_XATTR = 1
|
||||
UGID_USE_RWLOCK = 0
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
OPT_FLAGS := -O0 -g -fsanitize=undefined
|
||||
else
|
||||
OPT_FLAGS := -O2
|
||||
endif
|
||||
|
||||
ifeq ($(STATIC),1)
|
||||
USE_XATTR ?= 1
|
||||
|
||||
ifdef SANITIZE
|
||||
ifeq ($(SANITIZE),1)
|
||||
override SANITIZE := -fsanitize=address,undefined,leak
|
||||
else ifeq ($(filter -fsanitize=%,$(SANITIZE)),)
|
||||
override SANITIZE := -fsanitize=$(SANITIZE)
|
||||
endif
|
||||
endif
|
||||
|
||||
COMMON_OPT_FLAGS += \
|
||||
-fstack-protector-strong \
|
||||
-Wextra \
|
||||
-Wno-unused-parameter
|
||||
|
||||
DEBUG_OPT_FLAGS += \
|
||||
-O0 \
|
||||
-g3 \
|
||||
-fno-omit-frame-pointer \
|
||||
$(SANITIZE)
|
||||
|
||||
ifdef RELEASE
|
||||
OPT_FLAGS := -O3 $(COMMON_OPT_FLAGS)
|
||||
else
|
||||
OPT_FLAGS ?= $(DEBUG_OPT_FLAGS) $(COMMON_OPT_FLAGS)
|
||||
endif
|
||||
|
||||
ifdef STATIC
|
||||
STATIC_FLAGS := -static
|
||||
else
|
||||
STATIC_FLAGS :=
|
||||
endif
|
||||
|
||||
ifeq ($(LTO),1)
|
||||
ifdef LTO
|
||||
LTO_FLAGS := -flto
|
||||
else
|
||||
LTO_FLAGS :=
|
||||
endif
|
||||
|
||||
SRC = $(wildcard src/*.cpp)
|
||||
OBJS = $(SRC:src/%.cpp=build/.src/%.o)
|
||||
DEPS = $(SRC:src/%.cpp=build/.src/%.d)
|
||||
SRC := $(wildcard src/*.cpp)
|
||||
OBJS := $(SRC:src/%.cpp=build/.objs/%.cpp.o)
|
||||
DEPS := $(SRC:src/%.cpp=build/.objs/%.cpp.d)
|
||||
|
||||
TESTS = $(wildcard tests/*.cpp)
|
||||
TESTS_OBJS = $(filter-out build/.src/mergerfs.o,$(OBJS))
|
||||
TESTS_OBJS += $(TESTS:tests/%.cpp=build/.tests/%.o)
|
||||
TESTS_DEPS = $(TESTS:tests/%.cpp=build/.tests/%.d)
|
||||
TESTS := $(wildcard tests/*.cpp)
|
||||
TESTS_OBJS := $(filter-out build/.objs/mergerfs.cpp.o,$(OBJS))
|
||||
TESTS_OBJS += $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.o)
|
||||
TESTS_DEPS := $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.d)
|
||||
TESTS_DEPS += $(DEPS)
|
||||
|
||||
MANPAGE = mergerfs.1
|
||||
CXXFLAGS ?= ${OPT_FLAGS}
|
||||
CXXFLAGS := \
|
||||
${CXXFLAGS} \
|
||||
-std=c++11 \
|
||||
$(STATIC_FLAGS) \
|
||||
$(LTO_FLAGS) \
|
||||
-Wall \
|
||||
-Wno-unused-result \
|
||||
-MMD
|
||||
FUSE_FLAGS = \
|
||||
-Ilibfuse/include \
|
||||
-D_FILE_OFFSET_BITS=64
|
||||
MFS_FLAGS = \
|
||||
-DUSE_XATTR=$(USE_XATTR) \
|
||||
-DUGID_USE_RWLOCK=$(UGID_USE_RWLOCK)
|
||||
TESTS_FLAGS = \
|
||||
-Isrc \
|
||||
-DTESTS
|
||||
MANPAGE := mergerfs.1
|
||||
CPPFLAGS ?=
|
||||
override CPPFLAGS += \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
-DBOOST_UNORDERED_DISABLE_PARALLEL_ALGORITHMS
|
||||
CFLAGS ?= \
|
||||
$(OPT_FLAGS) \
|
||||
-Wall \
|
||||
-Wno-unused-result \
|
||||
-pipe
|
||||
override CFLAGS += \
|
||||
-MMD \
|
||||
-MP
|
||||
CXXFLAGS ?= \
|
||||
$(OPT_FLAGS) \
|
||||
$(STATIC_FLAGS) \
|
||||
$(LTO_FLAGS) \
|
||||
-Wall \
|
||||
-Wpessimizing-move \
|
||||
-Werror=pessimizing-move \
|
||||
-Wredundant-move \
|
||||
-Werror=redundant-move \
|
||||
-Wno-unused-result \
|
||||
-pipe
|
||||
override CXXFLAGS += \
|
||||
-std=c++20 \
|
||||
-MMD \
|
||||
-MP
|
||||
override INC_FLAGS := \
|
||||
-Isrc \
|
||||
-Ivendored \
|
||||
-Ivendored/libfuse/include
|
||||
override MFS_FLAGS := \
|
||||
-DUSE_XATTR=$(USE_XATTR)
|
||||
override TESTS_FLAGS := \
|
||||
-Isrc \
|
||||
-Ivendored \
|
||||
-Ivendored/acutest \
|
||||
-DTESTS
|
||||
|
||||
LDFLAGS := \
|
||||
${LDFLAGS} \
|
||||
-pthread \
|
||||
-lrt
|
||||
LIBFUSE := vendored/libfuse/$(BUILDDIR)/libfuse.a
|
||||
LDFLAGS ?=
|
||||
LDLIBS := \
|
||||
-lrt \
|
||||
-pthread
|
||||
override LDLIBS += \
|
||||
$(LIBFUSE)
|
||||
ifeq ($(CXX),g++)
|
||||
GCC_VERSION := $(shell $(CXX) -dumpversion | cut -f1 -d.)
|
||||
ifeq ($(shell test $(GCC_VERSION) -lt 9; echo $$?),0)
|
||||
override LDLIBS += -lstdc++fs
|
||||
endif
|
||||
endif
|
||||
|
||||
DESTDIR =
|
||||
PREFIX = /usr/local
|
||||
EXEC_PREFIX = $(PREFIX)
|
||||
DATAROOTDIR = $(PREFIX)/share
|
||||
DATADIR = $(DATAROOTDIR)
|
||||
BINDIR = $(EXEC_PREFIX)/bin
|
||||
SBINDIR = $(EXEC_PREFIX)/sbin
|
||||
MANDIR = $(DATAROOTDIR)/man
|
||||
MAN1DIR = $(MANDIR)/man1
|
||||
# https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
|
||||
DESTDIR ?=
|
||||
PREFIX ?= /usr/local
|
||||
EXEC_PREFIX ?= $(PREFIX)
|
||||
DATAROOTDIR ?= $(PREFIX)/share
|
||||
DATADIR ?= $(DATAROOTDIR)
|
||||
BINDIR ?= $(EXEC_PREFIX)/bin
|
||||
SBINDIR ?= $(EXEC_PREFIX)/sbin
|
||||
LIBDIR ?= $(EXEC_PREFIX)/lib
|
||||
MANDIR ?= $(DATAROOTDIR)/man
|
||||
MAN1DIR ?= $(MANDIR)/man1
|
||||
|
||||
INSTALLBINDIR ?= $(DESTDIR)$(BINDIR)
|
||||
INSTALLSBINDIR ?= $(DESTDIR)$(SBINDIR)
|
||||
INSTALLLIBDIR ?= $(DESTDIR)$(LIBDIR)/mergerfs
|
||||
INSTALLMAN1DIR ?= $(DESTDIR)$(MAN1DIR)
|
||||
|
||||
INSTALLBINDIR = $(DESTDIR)$(BINDIR)
|
||||
INSTALLSBINDIR = $(DESTDIR)$(SBINDIR)
|
||||
INSTALLMAN1DIR = $(DESTDIR)$(MAN1DIR)
|
||||
|
||||
.PHONY: all
|
||||
all: mergerfs
|
||||
all: libfuse $(BUILDDIR)/mergerfs $(BUILDDIR)/fsck.mergerfs $(BUILDDIR)/mergerfs.collect-info
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo "usage: make\n"
|
||||
@echo "make USE_XATTR=0 - build program without xattrs functionality"
|
||||
@echo "make STATIC=1 - build static binary"
|
||||
@echo "make LTO=1 - build with link time optimization"
|
||||
@echo "usage: make ARG\n"
|
||||
@echo "USE_XATTR=0 - build program without xattrs functionality"
|
||||
@echo "STATIC=1 - build static binary"
|
||||
@echo "LTO=1 - build with link time optimization"
|
||||
@echo "SANITIZE=1 - build with sanitizers (address,undefined,leak)"
|
||||
@echo "SANITIZE=list - build with custom sanitizers (comma separated)"
|
||||
@echo "CLEANUP=1 - cleanup images between release build process"
|
||||
@echo "PKGDIR=/dir/ - location for release build pkgs"
|
||||
@echo "GITREF=gitref - gitref to use for release builds"
|
||||
|
||||
objects: version build/stamp
|
||||
$(MAKE) $(OBJS)
|
||||
|
||||
tests-objects:
|
||||
$(MAKE) $(TESTS_OBJS)
|
||||
$(BUILDDIR)/mergerfs: $(LIBFUSE) src/version.hpp $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(OBJS) -o $@ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
build/mergerfs: libfuse objects
|
||||
$(CXX) $(CXXFLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(OBJS) -o $@ libfuse/build/libfuse.a $(LDFLAGS)
|
||||
$(BUILDDIR)/fsck.mergerfs: $(BUILDDIR)/mergerfs
|
||||
$(LN) -sf "mergerfs" $@
|
||||
|
||||
build/tests: build/mergerfs tests-objects
|
||||
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(TESTS_OBJS) -o $@ libfuse/build/libfuse.a $(LDFLAGS)
|
||||
$(BUILDDIR)/mergerfs.collect-info: $(BUILDDIR)/mergerfs
|
||||
$(LN) -sf "mergerfs" $@
|
||||
|
||||
mergerfs: build/mergerfs
|
||||
$(BUILDDIR)/tests: $(BUILDDIR)/mergerfs $(TESTS_OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(TESTS_OBJS) -o $@ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
tests: build/tests
|
||||
.PHONY: libfuse
|
||||
libfuse: $(LIBFUSE)
|
||||
$(MAKE) -C vendored/libfuse
|
||||
|
||||
$(LIBFUSE):
|
||||
$(MAKE) -C vendored/libfuse $(BUILDDIR)/libfuse.a RELEASE=$(RELEASE)
|
||||
|
||||
tests: $(BUILDDIR)/tests
|
||||
|
||||
.PHONY:
|
||||
changelog:
|
||||
ifeq ($(GIT_REPO),1)
|
||||
ifdef GIT_REPO
|
||||
$(GIT2DEBCL) --name mergerfs > ChangeLog
|
||||
else
|
||||
@echo "WARNING: need git repo to generate ChangeLog"
|
||||
endif
|
||||
|
||||
.PHONY: version
|
||||
version:
|
||||
tools/update-version
|
||||
version: src/version.hpp
|
||||
|
||||
build/stamp:
|
||||
$(MKDIR) -p build/.src build/.tests
|
||||
src/version.hpp:
|
||||
./buildtools/update-version
|
||||
|
||||
$(BUILDDIR)/stamp:
|
||||
$(MKDIR) -p $(BUILDDIR)/.objs
|
||||
$(MKDIR) -p $(BUILDDIR)/.test_objs
|
||||
$(TOUCH) $@
|
||||
|
||||
build/.src/%.o: src/%.cpp
|
||||
$(CXX) $(CXXFLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
$(BUILDDIR)/.objs/%.cpp.o: src/%.cpp $(BUILDDIR)/stamp
|
||||
$(CXX) $(CXXFLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
build/.tests/%.o: tests/%.cpp
|
||||
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
$(BUILDDIR)/.test_objs/%.cpp.o: tests/%.cpp | $(BUILDDIR)/stamp
|
||||
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
$(BUILDDIR)/preload.so: $(BUILDDIR)/stamp tools/preload.c
|
||||
$(CC) -shared -fPIC $(CFLAGS) -o $@ tools/preload.c
|
||||
|
||||
preload: $(BUILDDIR)/preload.so
|
||||
|
||||
.PHONY: clean
|
||||
clean: rpm-clean
|
||||
$(RM) -rf build
|
||||
$(RM) -rf $(BUILDDIR)
|
||||
$(FIND) . -name "*~" -delete
|
||||
$(MAKE) -C libfuse clean
|
||||
$(MAKE) -C vendored/libfuse clean
|
||||
|
||||
.PHONY: distclean
|
||||
distclean: clean
|
||||
ifeq ($(GIT_REPO),1)
|
||||
ifdef GIT_REPO
|
||||
$(GIT) clean -xfd
|
||||
endif
|
||||
|
||||
.PHONY: install
|
||||
install: install-base install-mount-tools install-man
|
||||
install: install-base install-mount-tools install-preload install-man
|
||||
|
||||
install-base: build/mergerfs
|
||||
.PHONY: install-base
|
||||
install-base: all
|
||||
$(MKDIR) -p "$(INSTALLBINDIR)"
|
||||
$(INSTALL) -v -m 0755 build/mergerfs "$(INSTALLBINDIR)/mergerfs"
|
||||
$(INSTALL) -v -m 0755 "$(BUILDDIR)/mergerfs" "$(INSTALLBINDIR)/mergerfs"
|
||||
$(LN) -fs "mergerfs" "${INSTALLBINDIR}/fsck.mergerfs"
|
||||
$(LN) -fs "mergerfs" "${INSTALLBINDIR}/mergerfs.collect-info"
|
||||
|
||||
.PHONY: install-mount-tools
|
||||
install-mount-tools: install-base
|
||||
$(MKDIR) -p "$(INSTALLBINDIR)"
|
||||
$(MAKE) -C libfuse install
|
||||
$(MAKE) -C vendored/libfuse install
|
||||
|
||||
install-man: $(MANPAGE)
|
||||
.PHONY: install-man
|
||||
install-man: man/$(MANPAGE)
|
||||
$(MKDIR) -p "$(INSTALLMAN1DIR)"
|
||||
$(INSTALL) -v -m 0644 "man/$(MANPAGE)" "$(INSTALLMAN1DIR)/$(MANPAGE)"
|
||||
|
||||
.PHONY: install-preload
|
||||
install-preload: preload
|
||||
$(MKDIR) -p "$(INSTALLLIBDIR)"
|
||||
$(INSTALL) -v -m 444 "$(BUILDDIR)/preload.so" "$(INSTALLLIBDIR)/preload.so"
|
||||
|
||||
.PHONY: install-strip
|
||||
install-strip: install-base
|
||||
$(STRIP) "$(INSTALLBINDIR)/mergerfs"
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall: uninstall-base uninstall-mount.mergerfs uninstall-man
|
||||
uninstall: uninstall-base uninstall-mount.mergerfs uninstall-preload uninstall-man
|
||||
|
||||
uninstall-base:
|
||||
$(RM) -f "$(INSTALLBINDIR)/mergerfs"
|
||||
$(RM) -f "$(INSTALLBINDIR)/fsck.mergerfs"
|
||||
$(RM) -f "$(INSTALLBINDIR)/mergerfs.collect-info"
|
||||
|
||||
uninstall-mount.mergerfs:
|
||||
$(RM) -f "$(INSTALLBINDIR)/mount.mergerfs"
|
||||
@@ -195,17 +292,11 @@ uninstall-mount.mergerfs:
|
||||
uninstall-man:
|
||||
$(RM) -f "$(INSTALLMAN1DIR)/$(MANPAGE)"
|
||||
|
||||
$(MANPAGE): README.md
|
||||
ifneq ($(shell $(PANDOC) --version 2> /dev/null),)
|
||||
$(PANDOC) -s -t man -o "man/$(MANPAGE)" README.md
|
||||
else
|
||||
$(warning "pandoc does not appear available: unable to build manpage")
|
||||
endif
|
||||
|
||||
man: $(MANPAGE)
|
||||
uninstall-preload:
|
||||
$(RM) -f "$(INSTALLLIBDIR)/preload.so"
|
||||
|
||||
.PHONY: tarball
|
||||
tarball: man changelog version
|
||||
tarball: changelog version
|
||||
$(eval VERSION := $(shell cat VERSION))
|
||||
$(eval VERSION := $(subst -,_,$(VERSION)))
|
||||
$(eval FILENAME := mergerfs-$(VERSION))
|
||||
@@ -215,29 +306,38 @@ tarball: man changelog version
|
||||
$(TAR) --exclude=.git -cz -C $(TMPDIR) -f $(FILENAME).tar.gz $(FILENAME)
|
||||
$(RM) -rf $(TMPDIR)
|
||||
|
||||
.PHONY: debian-changelog
|
||||
debian-changelog:
|
||||
ifeq ($(GIT_REPO),1)
|
||||
ifdef GIT_REPO
|
||||
$(GIT2DEBCL) --name mergerfs > debian/changelog
|
||||
else
|
||||
cp ChangeLog debian/changelog
|
||||
$(CP) -v ChangeLog debian/changelog
|
||||
$(eval DISTRO := $(shell lsb_release -i -s | tr '[:upper:]' '[:lower:]'))
|
||||
$(eval CODENAME := $(shell lsb_release -c -s | tr '[:upper:]' '[:lower:]'))
|
||||
sed -i 's/~unknown-unknown/~$(DISTRO)-$(CODENAME)/g' debian/changelog
|
||||
sed -i 's/ unknown; / $(CODENAME); /g' debian/changelog
|
||||
endif
|
||||
|
||||
.PHONY: signed-deb
|
||||
signed-deb:
|
||||
$(MAKE) distclean
|
||||
$(MAKE) debian-changelog
|
||||
dpkg-source -b .
|
||||
dpkg-buildpackage -nc
|
||||
$(FAKEROOT) dpkg-buildpackage -nc
|
||||
|
||||
.PHONY: deb
|
||||
deb:
|
||||
$(MAKE) distclean
|
||||
$(MAKE) debian-changelog
|
||||
dpkg-source -b .
|
||||
dpkg-buildpackage -nc -uc -us
|
||||
$(MAKE) version
|
||||
$(FAKEROOT) dpkg-buildpackage -nc -uc -us
|
||||
$(MKDIR) -p ./$(BUILDDIR)/pkgs/
|
||||
$(MV) -v ../mergerfs*deb ./$(BUILDDIR)/pkgs/
|
||||
|
||||
.PHONY: rpm-clean
|
||||
rpm-clean:
|
||||
$(RM) -rf rpmbuild
|
||||
|
||||
.PHONY: rpm
|
||||
rpm: tarball
|
||||
$(eval VERSION := $(shell cat VERSION))
|
||||
$(eval VERSION := $(subst -,_,$(VERSION)))
|
||||
@@ -245,15 +345,65 @@ rpm: tarball
|
||||
$(SED) 's/__VERSION__/$(VERSION)/g' mergerfs.spec > \
|
||||
rpmbuild/SOURCES/mergerfs.spec
|
||||
cp -ar mergerfs-$(VERSION).tar.gz rpmbuild/SOURCES
|
||||
$(RPMBUILD) -ba rpmbuild/SOURCES/mergerfs.spec \
|
||||
$(RPMBUILD) $(RPMBUILD_FLAGS) -ba rpmbuild/SOURCES/mergerfs.spec \
|
||||
--define "_topdir $(CURDIR)/rpmbuild"
|
||||
|
||||
.PHONY: install-build-pkgs
|
||||
install-build-pkgs:
|
||||
tools/install-build-pkgs
|
||||
./buildtools/install-build-pkgs
|
||||
|
||||
.PHONY: install-build-tools
|
||||
install-build-tools:
|
||||
./buildtools/install-build-tools
|
||||
|
||||
define build_release
|
||||
$(eval GITREF ?= $(shell git describe --exact-match --tags HEAD 2>/dev/null || git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD))
|
||||
@echo "GITREF=$(GITREF)"
|
||||
./buildtools/build-release \
|
||||
--target=$(1) \
|
||||
$(if $(CLEANUP),--cleanup) \
|
||||
$(if $(PKGDIR),--pkgdirpath=$(PKGDIR)) \
|
||||
--git-repo=$(if $(REMOTE_REPO),$(GITHUB_REPO),".") \
|
||||
--branch=$(GITREF)
|
||||
endef
|
||||
|
||||
.PHONY: release release-all
|
||||
.PHONY: release-amd64 release-arm64 release-armhf release-riscv64
|
||||
.PHONY: release-sample release-static release-tarball release-installer
|
||||
release:
|
||||
$(MAKE) RELEASE=1 CPPFLAGS="$(CPPFLAGS) -DNDEBUG" all
|
||||
release-all:
|
||||
$(call build_release,"all")
|
||||
release-sample:
|
||||
$(if $(TARGET),,$(eval TARGET := $(shell ./buildtools/detect-local-target 2>/dev/null)))
|
||||
$(call build_release,$(if $(TARGET),$(TARGET),$(DEFAULT_TARGET)))
|
||||
release-amd64:
|
||||
$(call build_release,"amd64")
|
||||
release-arm64:
|
||||
$(call build_release,"arm64")
|
||||
release-armhf:
|
||||
$(call build_release,"armhf")
|
||||
release-riscv64:
|
||||
$(call build_release,"riscv64")
|
||||
release-static:
|
||||
$(call build_release,"static")
|
||||
release-tarball:
|
||||
$(call build_release,"tarball")
|
||||
release-installer:
|
||||
$(call build_release,"installer")
|
||||
|
||||
container:
|
||||
$(eval GITREF ?= $(shell git describe --exact-match --tags HEAD 2>/dev/null || git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD))
|
||||
@echo "GITREF=$(GITREF)"
|
||||
./buildtools/build-containerimage "$(GITREF)"
|
||||
|
||||
.PHONY: tags
|
||||
tags:
|
||||
rm -fv TAGS
|
||||
find . -name "*.c" -print | etags --append -
|
||||
find . -name "*.h" -print | etags --append -
|
||||
find . -name "*.cpp" -print | etags --append -
|
||||
find . -name "*.hpp" -print | etags --append -
|
||||
|
||||
.PHONY: libfuse
|
||||
libfuse:
|
||||
$(MAKE) DEBUG=$(DEBUG) -C libfuse
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
GIT_BRANCH="${1:-master}"
|
||||
|
||||
set -x
|
||||
podman \
|
||||
build \
|
||||
--squash \
|
||||
--no-cache \
|
||||
--force-rm \
|
||||
--build-arg="GIT_REPO=file:///mnt" \
|
||||
--build-arg="BRANCH=${GIT_BRANCH}" \
|
||||
-v "${PWD}":/mnt:ro \
|
||||
-f "buildtools/containerimage/Containerfile" \
|
||||
--tag "ghcr.io/trapexit/mergerfs:${GIT_BRANCH}" \
|
||||
buildtools/
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ -e /tmp/build-env ]; then
|
||||
. /tmp/build-env
|
||||
fi
|
||||
|
||||
rpmbuild_flags()
|
||||
{
|
||||
case "$(command -v "${CXX:-g++}")" in
|
||||
/opt/rh/*)
|
||||
printf '%s' '--undefine _annotated_build'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "usage: $0 <branch> <git_repo>"
|
||||
echo "argv: $@"
|
||||
echo "argc: $#"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GIT_REPO="${1}"
|
||||
BRANCH="${2}"
|
||||
BUILDDIR="/tmp/build"
|
||||
|
||||
echo "Clone source from ${GIT_REPO} to ${BUILDDIR}"
|
||||
git \
|
||||
clone \
|
||||
--single-branch \
|
||||
--branch="${BRANCH}" \
|
||||
"${GIT_REPO}" \
|
||||
"${BUILDDIR}"
|
||||
|
||||
cd "${BUILDDIR}"
|
||||
|
||||
git log HEAD^1..
|
||||
|
||||
mkdir "/build"
|
||||
if [ -e /usr/bin/apt-get ]; then
|
||||
make deb
|
||||
elif [ -e /usr/bin/dnf ]; then
|
||||
make RPMBUILD_FLAGS="$(rpmbuild_flags)" rpm
|
||||
elif [ -e /usr/bin/yum ]; then
|
||||
make RPMBUILD_FLAGS="$(rpmbuild_flags)" rpm
|
||||
elif [ -e /sbin/apk ]; then
|
||||
echo "NOT YET SUPPORTED"
|
||||
exit 1
|
||||
elif [ -e /usr/sbin/pkg ]; then
|
||||
echo "NOT YET SUPPORTED"
|
||||
exit 1
|
||||
elif [ -e /usr/bin/pacman ]; then
|
||||
make tarball
|
||||
else
|
||||
echo "NOT YET SUPPORTED"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Copy packages to host..."
|
||||
if [ -e /usr/bin/pacman ]; then
|
||||
find "${BUILDDIR}" \
|
||||
-type f \
|
||||
-name "*.tar.gz" \
|
||||
-exec cp -v {} /build/ \;
|
||||
else
|
||||
find "${BUILDDIR}" \
|
||||
-type f \
|
||||
\( -name "*.deb" -or -name "*.rpm" \) \
|
||||
-not -name "*dbgsym*" \
|
||||
-not -name "*sym*" \
|
||||
-not -name "*src.rpm" \
|
||||
-exec cp -v {} /build/ \;
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+178
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import time
|
||||
|
||||
|
||||
def build(git_repo,
|
||||
branch,
|
||||
containerfile,
|
||||
pkgdirpath):
|
||||
timestamp = time.time_ns()
|
||||
args = ['podman',
|
||||
'build',
|
||||
'--pull=always',
|
||||
'--force-rm']
|
||||
if os.path.exists(git_repo):
|
||||
git_repo = os.path.realpath(git_repo)
|
||||
args += ['-v',f'{git_repo}:/tmp/mergerfs.git:ro:z']
|
||||
args += ['--build-arg=GIT_REPO=file:///tmp/mergerfs.git']
|
||||
else:
|
||||
args += [f'--build-arg=GIT_REPO={git_repo}']
|
||||
os.makedirs(pkgdirpath,exist_ok=True)
|
||||
args += ['-v',f'{os.path.realpath(pkgdirpath)}:/pkgs:ro']
|
||||
args += ['-o',pkgdirpath,
|
||||
'-f',containerfile,
|
||||
f'--build-arg=BRANCH={branch}',
|
||||
f'--build-arg=BUILD_TIMESTAMP={timestamp}',
|
||||
'buildtools/']
|
||||
# TODO: Capture output and write to log
|
||||
print(args)
|
||||
rv = subprocess.run(args)
|
||||
report_filepath = os.path.join(pkgdirpath,"build-report.txt")
|
||||
with open(report_filepath,"a+") as f:
|
||||
build = os.path.basename(containerfile)
|
||||
f.write(build + ": ")
|
||||
f.write(f"branch={branch}; ")
|
||||
f.write(f"timestamp={timestamp}; ")
|
||||
f.write("rv=")
|
||||
if rv.returncode == 0:
|
||||
f.write("success;")
|
||||
else:
|
||||
f.write("fail;")
|
||||
f.write("\n")
|
||||
|
||||
|
||||
def setup():
|
||||
# Detect distribution
|
||||
if os.path.exists('/usr/bin/apt-get'):
|
||||
args = ['sudo',
|
||||
'apt-get',
|
||||
'install',
|
||||
'-fy',
|
||||
'qemu-user-static',
|
||||
'qemu-user-binfmt']
|
||||
elif os.path.exists('/usr/bin/pacman'):
|
||||
args = ['sudo',
|
||||
'pacman',
|
||||
'-Sy',
|
||||
'--noconfirm',
|
||||
'qemu-user-static']
|
||||
else:
|
||||
print("Unsupported distribution for setup")
|
||||
sys.exit(1)
|
||||
print(args)
|
||||
subprocess.run(args)
|
||||
setup_binfmt()
|
||||
|
||||
|
||||
def setup_binfmt():
|
||||
"""Register qemu-user-static binfmt handlers (needed on Arch, etc.)."""
|
||||
binfmt_conf = """\
|
||||
:qemu-aarch64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-aarch64-static:F
|
||||
:qemu-arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-arm-static:F
|
||||
:qemu-armeb:M::\\x7fELF\\x01\\x02\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:/usr/bin/qemu-armeb-static:F
|
||||
:qemu-riscv64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xf3\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-riscv64-static:F
|
||||
:qemu-i386:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x03\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-i386-static:F
|
||||
"""
|
||||
conf_path = '/etc/binfmt.d/qemu-static.conf'
|
||||
print(f"Writing {conf_path}")
|
||||
try:
|
||||
with open(conf_path, 'w') as f:
|
||||
f.write(binfmt_conf)
|
||||
except PermissionError:
|
||||
print(f"Permission denied writing {conf_path}; trying with sudo...")
|
||||
subprocess.run(['sudo', 'tee', conf_path],
|
||||
input=binfmt_conf.encode(), check=True)
|
||||
|
||||
print("Restarting systemd-binfmt...")
|
||||
subprocess.run(['sudo', 'systemctl', 'restart', 'systemd-binfmt'])
|
||||
|
||||
|
||||
def podman_cleanup():
|
||||
args = ['podman',
|
||||
'system',
|
||||
'prune',
|
||||
'-af']
|
||||
print(args)
|
||||
subprocess.run(args)
|
||||
|
||||
|
||||
def parse_args():
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('--target',
|
||||
default='debian:13.amd64')
|
||||
p.add_argument('--pkgdirpath',
|
||||
default='build/pkgs/')
|
||||
p.add_argument('--branch',
|
||||
default='master')
|
||||
p.add_argument('--setup',
|
||||
required=False,
|
||||
action='store_true')
|
||||
p.add_argument('--cleanup',
|
||||
required=False,
|
||||
action='store_true')
|
||||
p.add_argument('--git-repo',
|
||||
required=False,
|
||||
type=str)
|
||||
|
||||
return p.parse_args()
|
||||
|
||||
|
||||
def should_skip(filename):
|
||||
if filename.endswith('~'):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
print(args)
|
||||
|
||||
if args.setup:
|
||||
setup()
|
||||
sys.exit(0)
|
||||
|
||||
if not args.git_repo:
|
||||
print("error: the following arguments are required: --git-repo")
|
||||
sys.exit(1)
|
||||
|
||||
containerfiles = []
|
||||
basepath = 'buildtools/containerfiles'
|
||||
if os.path.exists(f'{basepath}/{args.target}'):
|
||||
containerfiles.append(f'{basepath}/{args.target}')
|
||||
elif args.target == 'all':
|
||||
for root,dirnames,filenames in os.walk(basepath):
|
||||
filenames.sort()
|
||||
for filename in filenames:
|
||||
if should_skip(filename):
|
||||
continue
|
||||
containerfile = f'buildtools/containerfiles/{filename}'
|
||||
containerfiles.append(containerfile)
|
||||
else:
|
||||
for root,dirnames,filenames in os.walk(basepath):
|
||||
filenames.sort()
|
||||
for filename in filenames:
|
||||
if args.target not in filename:
|
||||
continue
|
||||
if should_skip(filename):
|
||||
continue
|
||||
containerfile = f'buildtools/containerfiles/{filename}'
|
||||
containerfiles.append(containerfile)
|
||||
|
||||
for containerfile in containerfiles:
|
||||
if args.cleanup:
|
||||
podman_cleanup()
|
||||
build(git_repo=args.git_repo,
|
||||
branch=args.branch,
|
||||
containerfile=containerfile,
|
||||
pkgdirpath=args.pkgdirpath)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 debian:11 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 debian:11 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=armhf debian:11 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=i386 debian:11 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 debian:12 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 debian:12 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=armhf debian:12 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=i386 debian:12 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 debian:13 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 debian:13 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=armhf debian:13 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=i386 debian:13 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=riscv64 debian:13 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 fedora:40 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 fedora:40 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 fedora:41 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 fedora:41 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 fedora:42 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 fedora:42 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 fedora:43 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 fedora:43 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 fedora:44 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 fedora:44 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 quay.io/rockylinux/rockylinux:10 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 quay.io/rockylinux/rockylinux:10 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 quay.io/rockylinux/rockylinux:8 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 quay.io/rockylinux/rockylinux:8 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 quay.io/rockylinux/rockylinux:9 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 quay.io/rockylinux/rockylinux:9 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,15 @@
|
||||
FROM --platform=linux/amd64 alpine:latest as build
|
||||
COPY install-build-pkgs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
||||
WORKDIR /tmp/mergerfs
|
||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
||||
RUN mkdir /build
|
||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_amd64.tar.gz --directory=/tmp usr sbin
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,15 @@
|
||||
FROM --platform=linux/arm64 alpine:latest as build
|
||||
COPY install-build-pkgs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
||||
WORKDIR /tmp/mergerfs
|
||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
||||
RUN mkdir /build
|
||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_arm64.tar.gz --directory=/tmp usr sbin
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,15 @@
|
||||
FROM --platform=linux/armhf alpine:latest as build
|
||||
COPY install-build-pkgs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
||||
WORKDIR /tmp/mergerfs
|
||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
||||
RUN mkdir /build
|
||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_armhf.tar.gz --directory=/tmp usr sbin
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,15 @@
|
||||
FROM --platform=linux/i386 alpine:latest as build
|
||||
COPY install-build-pkgs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
||||
WORKDIR /tmp/mergerfs
|
||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
||||
RUN mkdir /build
|
||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_i386.tar.gz --directory=/tmp usr sbin
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,14 @@
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
FROM --platform=linux/amd64 ubuntu:latest as build
|
||||
COPY install-build-pkgs /tmp/
|
||||
RUN /tmp/install-build-pkgs && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -qy --no-install-suggests --no-install-recommends install \
|
||||
makeself
|
||||
RUN mkdir -p /tmp/mergerfs/
|
||||
RUN ls -lhd /pkgs
|
||||
RUN cp -v /pkgs/*static*.gz /tmp/mergerfs/
|
||||
RUN mkdir -p /build
|
||||
RUN makeself /tmp/mergerfs/ /build/mergerfs-installer.run "mergerfs" echo "foo"
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,15 @@
|
||||
FROM --platform=linux/riscv64 alpine:latest as build
|
||||
COPY install-build-pkgs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
||||
WORKDIR /tmp/mergerfs
|
||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
||||
RUN mkdir /build
|
||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_riscv64.tar.gz --directory=/tmp usr sbin
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,17 @@
|
||||
FROM alpine:latest as tarball
|
||||
|
||||
COPY install-build-pkgs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG BRANCH=master
|
||||
ARG GIT_REPO
|
||||
|
||||
RUN git clone --single-branch "${GIT_REPO}" /tmp/mergerfs --branch="${BRANCH}"
|
||||
RUN cd /tmp/mergerfs && make version tarball
|
||||
|
||||
RUN mkdir /build
|
||||
RUN cp -v /tmp/mergerfs/*.tar.gz /build/
|
||||
|
||||
FROM scratch
|
||||
COPY --from=tarball /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 ubuntu:22.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 ubuntu:22.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=armhf ubuntu:22.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=riscv64 ubuntu:22.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 ubuntu:24.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 ubuntu:24.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=armhf ubuntu:24.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=riscv64 ubuntu:24.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 ubuntu:25.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 ubuntu:25.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=armhf ubuntu:25.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=riscv64 ubuntu:25.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 ubuntu:25.10 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 ubuntu:25.10 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=armhf ubuntu:25.10 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=riscv64 ubuntu:25.10 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=amd64 ubuntu:26.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=arm64 ubuntu:26.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=armhf ubuntu:26.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM --platform=riscv64 ubuntu:26.04 as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM --platform=linux/amd64 alpine:latest as build
|
||||
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
|
||||
RUN <<EOF
|
||||
apk add git gcc g++ make linux-headers
|
||||
git clone --single-branch --branch="${BRANCH}" "${GIT_REPO}" /tmp/mergerfs
|
||||
cd /tmp/mergerfs
|
||||
make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp/install -j$(nproc) install
|
||||
tar cvfz /tmp/mergerfs.tgz --directory=/tmp/install usr sbin
|
||||
EOF
|
||||
|
||||
FROM --platform=linux/amd64 alpine:latest
|
||||
RUN --mount=from=build,source=/tmp/mergerfs.tgz,target=/tmp/mergerfs.tgz <<EOF
|
||||
tar xvf /tmp/mergerfs.tgz -C /
|
||||
EOF
|
||||
ENTRYPOINT ["/usr/local/bin/mergerfs"]
|
||||
CMD ["--help"]
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
#!/bin/bash
|
||||
# Detects local OS and maps to containerfiles target
|
||||
# Returns target if found in buildtools/containerfiles/, empty string otherwise
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CONTAINERFILES_DIR="buildtools/containerfiles"
|
||||
|
||||
# Detect system architecture and map to containerfiles format
|
||||
detect_arch() {
|
||||
local arch
|
||||
arch=$(uname -m)
|
||||
case "$arch" in
|
||||
x86_64) echo "amd64" ;;
|
||||
aarch64) echo "arm64" ;;
|
||||
armv7l) echo "armhf" ;;
|
||||
i686|i386) echo "i386" ;;
|
||||
riscv64) echo "riscv64" ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Detect distro and version from os-release
|
||||
detect_distro() {
|
||||
local os_release="${1:-}"
|
||||
if [[ ! -r "$os_release" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Source the file safely - ID and VERSION_ID are environment variables
|
||||
. "$os_release"
|
||||
|
||||
local distro="$ID"
|
||||
local version="$VERSION_ID"
|
||||
|
||||
# Map distro ID to containerfiles naming convention
|
||||
case "$distro" in
|
||||
ubuntu|debian|fedora) ;;
|
||||
rocky|rhel|centos|almalinux) distro="rockylinux" ;;
|
||||
*)
|
||||
# Fallback to ID_LIKE for derivatives
|
||||
if [[ -n "${ID_LIKE:-}" ]]; then
|
||||
case "$ID_LIKE" in
|
||||
*ubuntu*) distro="ubuntu" ;;
|
||||
*debian*) distro="debian" ;;
|
||||
*fedora*) distro="fedora" ;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Only return if we have valid distro and version
|
||||
if [[ -n "$distro" && -n "$version" ]]; then
|
||||
echo "$distro:$version"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Try to find a matching containerfile target
|
||||
find_containerfile() {
|
||||
local target="$1"
|
||||
local containerfile="${CONTAINERFILES_DIR}/${target}"
|
||||
|
||||
# Direct match
|
||||
if [[ -d "$containerfile" || -f "$containerfile" ]]; then
|
||||
echo "$target"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Main detection logic
|
||||
main() {
|
||||
local arch
|
||||
|
||||
# Detect architecture
|
||||
arch=$(detect_arch)
|
||||
if [[ -z "$arch" ]]; then
|
||||
echo "WARNING: Could not detect system architecture" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Try to detect distro from multiple locations
|
||||
local distro_ver
|
||||
distro_ver=$(detect_distro "/etc/os-release") || \
|
||||
distro_ver=$(detect_distro "/usr/lib/os-release") || {
|
||||
echo "WARNING: Could not detect distro from os-release" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Build target string
|
||||
local target="${distro_ver}.${arch}"
|
||||
|
||||
# Try to find matching containerfile
|
||||
if find_containerfile "$target"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Try with partial version matching (e.g., 25.10 → 25)
|
||||
local distro="${distro_ver%%:*}"
|
||||
local version="${distro_ver##*:}"
|
||||
|
||||
# Strip last minor version number and try again
|
||||
local short_version="${version%.*}"
|
||||
if [[ -n "$short_version" ]]; then
|
||||
target="${distro}:${short_version}.${arch}"
|
||||
if find_containerfile "$target"; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# No match found
|
||||
echo "WARNING: No containerfile found for target: ${distro_ver}.${arch}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
input_file="${1}"
|
||||
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
# Skip empty lines
|
||||
if [ -z "$line" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
image=$(echo "$line" | cut -d' ' -f1)
|
||||
platform=$(echo "$line" | cut -d' ' -f2-)
|
||||
|
||||
echo "${image} ${platform}"
|
||||
cat <<EOF > "containerfiles/${image##*/}.${platform}"
|
||||
FROM --platform=${platform} ${image} as build
|
||||
COPY install-build-pkgs build-mergerfs /tmp/
|
||||
RUN /tmp/install-build-pkgs
|
||||
ARG BUILD_TIMESTAMP=0
|
||||
ARG GIT_REPO
|
||||
ARG BRANCH
|
||||
RUN /tmp/build-mergerfs \$GIT_REPO \$BRANCH
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /build/ /
|
||||
EOF
|
||||
done < "$input_file"
|
||||
Executable
+202
@@ -0,0 +1,202 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# Default values
|
||||
NAME=""
|
||||
VERSION="::guess::"
|
||||
DISTRO="::guess::"
|
||||
CODENAME="::guess::"
|
||||
URGENCY="medium"
|
||||
|
||||
# Function to display usage
|
||||
usage() {
|
||||
cat << EOF
|
||||
Usage: $0 --name NAME [OPTIONS]
|
||||
|
||||
Generated debian/changelog from git log
|
||||
|
||||
Options:
|
||||
--name NAME Name of package (required)
|
||||
--version VERSION Place in git history to include upto (default: ::guess::)
|
||||
--distro DISTRO Distribution name (default: ::guess::)
|
||||
--codename NAME Distribution codename (default: ::guess::)
|
||||
--urgency URGENCY Urgency (default: medium)
|
||||
-h, --help Show this help message
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--name)
|
||||
NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
--version)
|
||||
VERSION="$2"
|
||||
shift 2
|
||||
;;
|
||||
--distro)
|
||||
DISTRO="$2"
|
||||
shift 2
|
||||
;;
|
||||
--codename)
|
||||
CODENAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
--urgency)
|
||||
URGENCY="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check required arguments
|
||||
if [ -z "$NAME" ]; then
|
||||
echo "Error: --name is required" >&2
|
||||
usage
|
||||
fi
|
||||
|
||||
# Function to get git tags sorted in reverse order
|
||||
git_tags() {
|
||||
git tag -l | sort -rV
|
||||
}
|
||||
|
||||
# Function to get git log between two tags
|
||||
git_log() {
|
||||
local fromtag="$1"
|
||||
local totag="$2"
|
||||
git log --no-merges --oneline "${fromtag}...${totag}" 2>/dev/null
|
||||
}
|
||||
|
||||
# Function to get author and time for a tag
|
||||
git_author_and_time() {
|
||||
local tag="$1"
|
||||
git log -1 --format="-- %an <%ae> %cD" "$tag"
|
||||
}
|
||||
|
||||
# Function to get git version
|
||||
git_version() {
|
||||
git describe --always --tags --dirty 2>/dev/null || echo "unknown"
|
||||
}
|
||||
|
||||
# Function to guess distribution
|
||||
guess_distro() {
|
||||
if command -v lsb_release >/dev/null 2>&1; then
|
||||
lsb_release -i -s 2>/dev/null | tr '[:upper:]' '[:lower:]'
|
||||
else
|
||||
echo "unknown"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to guess codename
|
||||
guess_codename() {
|
||||
if command -v lsb_release >/dev/null 2>&1; then
|
||||
lsb_release -c -s 2>/dev/null | tr '[:upper:]' '[:lower:]'
|
||||
else
|
||||
echo "unknown"
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle guessing of values
|
||||
if [ "$DISTRO" = "::guess::" ]; then
|
||||
DISTRO=$(guess_distro)
|
||||
fi
|
||||
|
||||
if [ "$CODENAME" = "::guess::" ]; then
|
||||
CODENAME=$(guess_codename)
|
||||
fi
|
||||
|
||||
if [ "$VERSION" = "::guess::" ]; then
|
||||
VERSION=$(git_version)
|
||||
fi
|
||||
|
||||
# Version suffix
|
||||
VERSUFFIX="~${DISTRO}-${CODENAME}"
|
||||
|
||||
# Get all tags
|
||||
TAGS=$(git_tags)
|
||||
|
||||
# Create temporary file for tag pairs
|
||||
TMPFILE=$(mktemp)
|
||||
trap 'rm -f "$TMPFILE"' EXIT
|
||||
|
||||
# Check if version is in tags
|
||||
if echo "$TAGS" | grep -q "^${VERSION}$"; then
|
||||
# If version is a tag, start from that tag
|
||||
echo "$TAGS" | awk -v ver="$VERSION" 'BEGIN{found=0} {if($0==ver)found=1; if(found)print}' > "$TMPFILE"
|
||||
else
|
||||
# If version is not a tag, use HEAD as starting point
|
||||
echo "$VERSION HEAD" > "$TMPFILE"
|
||||
echo "$TAGS" >> "$TMPFILE"
|
||||
fi
|
||||
|
||||
# Process tags and generate changelog
|
||||
PREV_TAG=""
|
||||
PREV_REF=""
|
||||
FIRST=1
|
||||
|
||||
while IFS= read -r line; do
|
||||
if [ -z "$line" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Handle the special case of VERSION HEAD
|
||||
if [ "$line" = "$VERSION HEAD" ]; then
|
||||
TAG="$VERSION"
|
||||
REF="HEAD"
|
||||
else
|
||||
TAG="$line"
|
||||
REF="$line"
|
||||
fi
|
||||
|
||||
if [ -n "$PREV_TAG" ]; then
|
||||
# Get log entries between current and previous tag
|
||||
LOG_ENTRIES=$(git_log "$REF" "$PREV_REF")
|
||||
|
||||
# Skip if no changes
|
||||
if [ -z "$LOG_ENTRIES" ] || [ "$LOG_ENTRIES" = "" ]; then
|
||||
PREV_TAG="$TAG"
|
||||
PREV_REF="$REF"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Print package header
|
||||
printf "%s (%s%s) %s; urgency=%s\n\n" "$NAME" "$PREV_TAG" "$VERSUFFIX" "$CODENAME" "$URGENCY"
|
||||
|
||||
# Print each log entry
|
||||
echo "$LOG_ENTRIES" | while IFS= read -r entry; do
|
||||
if [ -n "$entry" ]; then
|
||||
printf " * %s\n" "$entry"
|
||||
fi
|
||||
done
|
||||
|
||||
# Print author and time
|
||||
AUTHOR_TIME=$(git_author_and_time "$PREV_REF")
|
||||
printf "\n %s\n\n" "$AUTHOR_TIME"
|
||||
fi
|
||||
|
||||
PREV_TAG="$TAG"
|
||||
PREV_REF="$REF"
|
||||
done < "$TMPFILE"
|
||||
Executable
+162
@@ -0,0 +1,162 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
BUILD_ENV=/tmp/build-env
|
||||
|
||||
write_gcc_env()
|
||||
{
|
||||
{
|
||||
printf 'export CC=%s\n' "$1"
|
||||
printf 'export CXX=%s\n' "$2"
|
||||
} > "$BUILD_ENV"
|
||||
}
|
||||
|
||||
write_toolset_env()
|
||||
{
|
||||
{
|
||||
printf '. %s\n' "$1"
|
||||
printf 'export CC=gcc\n'
|
||||
printf 'export CXX=g++\n'
|
||||
} > "$BUILD_ENV"
|
||||
}
|
||||
|
||||
latest_apt_gxx()
|
||||
{
|
||||
apt-cache --names-only search '^g[+][+]-[0-9]' \
|
||||
| sed -n 's/^\(g++-[0-9][0-9]*\) .*/\1/p' \
|
||||
| sort -t- -k2,2V \
|
||||
| tail -n 1
|
||||
}
|
||||
|
||||
latest_dnf_toolset()
|
||||
{
|
||||
dnf -q list --showduplicates 'gcc-toolset-*-gcc-c++' 2>/dev/null \
|
||||
| sed -n 's/^gcc-toolset-\([0-9][0-9]*\)-gcc-c++\..*/\1/p' \
|
||||
| sort -V \
|
||||
| tail -n 1
|
||||
}
|
||||
|
||||
latest_yum_toolset()
|
||||
{
|
||||
yum -q list available 'devtoolset-*-gcc-c++' 2>/dev/null \
|
||||
| sed -n 's/^devtoolset-\([0-9][0-9]*\)-gcc-c++\..*/\1/p' \
|
||||
| sort -V \
|
||||
| tail -n 1
|
||||
}
|
||||
|
||||
version_gt()
|
||||
{
|
||||
highest="$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n 1)"
|
||||
[ "$highest" = "$1" ] && [ "$1" != "$2" ]
|
||||
}
|
||||
|
||||
check_cxx20()
|
||||
{
|
||||
cxx="${CXX:-g++}"
|
||||
test_src=/tmp/mergerfs-cxx20-check.cpp
|
||||
test_bin=/tmp/mergerfs-cxx20-check
|
||||
|
||||
cat > "$test_src" <<'EOF'
|
||||
template <typename T>
|
||||
concept Incrementable = requires(T value) { value + 1; };
|
||||
|
||||
static_assert(Incrementable<int>);
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
if ! "$cxx" -std=c++20 "$test_src" -o "$test_bin" >/dev/null 2>&1; then
|
||||
echo "error: $cxx does not support C++20" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -f "$test_src" "$test_bin"
|
||||
}
|
||||
|
||||
: > "$BUILD_ENV"
|
||||
|
||||
if [ -e /usr/bin/apt-get ]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get -qy update
|
||||
cxx_pkg="$(latest_apt_gxx)"
|
||||
if [ -n "$cxx_pkg" ]; then
|
||||
gcc_pkg="gcc-${cxx_pkg#g++-}"
|
||||
compiler_pkgs="$gcc_pkg $cxx_pkg"
|
||||
write_gcc_env "$gcc_pkg" "$cxx_pkg"
|
||||
else
|
||||
compiler_pkgs="g++"
|
||||
write_gcc_env gcc g++
|
||||
fi
|
||||
apt-get -qy --force-yes --no-install-suggests --no-install-recommends \
|
||||
install \
|
||||
ca-certificates \
|
||||
build-essential \
|
||||
dpkg-dev \
|
||||
git \
|
||||
$compiler_pkgs \
|
||||
debhelper \
|
||||
lsb-release \
|
||||
fakeroot
|
||||
. "$BUILD_ENV"
|
||||
check_cxx20
|
||||
elif [ -e /usr/bin/dnf ]; then
|
||||
dnf -y update
|
||||
toolset="$(latest_dnf_toolset)"
|
||||
dnf -y install \
|
||||
git rpm-build gcc-c++ make which libatomic
|
||||
default_gxx_major="$(g++ -dumpversion | cut -f1 -d.)"
|
||||
if [ -n "$toolset" ] && version_gt "$toolset" "$default_gxx_major"; then
|
||||
dnf -y install \
|
||||
"gcc-toolset-${toolset}-gcc" \
|
||||
"gcc-toolset-${toolset}-gcc-c++"
|
||||
write_toolset_env "/opt/rh/gcc-toolset-${toolset}/enable"
|
||||
else
|
||||
write_gcc_env gcc g++
|
||||
fi
|
||||
. "$BUILD_ENV"
|
||||
check_cxx20
|
||||
elif [ -e /usr/bin/yum ]; then
|
||||
yum -y update
|
||||
yum -y install \
|
||||
git rpm-build gcc-c++ make which
|
||||
yum -y install centos-release-scl || true
|
||||
yum -y update
|
||||
toolset="$(latest_yum_toolset)"
|
||||
default_gxx_major="$(g++ -dumpversion | cut -f1 -d.)"
|
||||
if [ -n "$toolset" ] && version_gt "$toolset" "$default_gxx_major"; then
|
||||
yum -y install \
|
||||
"devtoolset-${toolset}-gcc" \
|
||||
"devtoolset-${toolset}-gcc-c++"
|
||||
write_toolset_env "/opt/rh/devtoolset-${toolset}/enable"
|
||||
else
|
||||
write_gcc_env gcc g++
|
||||
fi
|
||||
. "$BUILD_ENV"
|
||||
check_cxx20
|
||||
elif [ -e /usr/bin/zypper ]; then
|
||||
zypper update -y
|
||||
zypper install -y \
|
||||
git rpm-build gcc-c++ make which
|
||||
write_gcc_env gcc g++
|
||||
. "$BUILD_ENV"
|
||||
check_cxx20
|
||||
elif [ -e /sbin/apk ]; then
|
||||
apk add \
|
||||
abuild git gcc g++ make \
|
||||
linux-headers
|
||||
write_gcc_env gcc g++
|
||||
. "$BUILD_ENV"
|
||||
check_cxx20
|
||||
elif [ -e /usr/sbin/pkg ]; then
|
||||
pkg install \
|
||||
git gmake gcc
|
||||
elif [ -e /usr/bin/pacman ]; then
|
||||
pacman -Sy --noconfirm base-devel git fakeroot
|
||||
write_gcc_env gcc g++
|
||||
. "$BUILD_ENV"
|
||||
check_cxx20
|
||||
fi
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
SUDO=
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
SUDO=sudo
|
||||
elif command -v doas >/dev/null 2>&1; then
|
||||
SUDO=doas
|
||||
else
|
||||
printf '%s\n' "error: need root privileges; run as root or install sudo/doas" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -e /usr/bin/apt-get ]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
${SUDO} apt-get -qy update
|
||||
${SUDO} apt-get -qy --no-install-suggests --no-install-recommends install \
|
||||
qemu-user-static \
|
||||
podman
|
||||
elif [ -e /usr/bin/dnf ]; then
|
||||
${SUDO} dnf -y update
|
||||
${SUDO} dnf -y install \
|
||||
qemu-user-static \
|
||||
podman
|
||||
elif [ -e /sbin/apk ]; then
|
||||
${SUDO} apk add \
|
||||
python3 \
|
||||
qemu-user-static \
|
||||
podman
|
||||
elif [ -e /usr/bin/pacman ]; then
|
||||
${SUDO} pacman -Sy --noconfirm qemu-user-static podman
|
||||
fi
|
||||
@@ -0,0 +1,39 @@
|
||||
debian:11 amd64
|
||||
debian:11 arm64
|
||||
debian:11 armhf
|
||||
debian:11 i386
|
||||
debian:12 amd64
|
||||
debian:12 arm64
|
||||
debian:12 armhf
|
||||
debian:12 i386
|
||||
debian:13 amd64
|
||||
debian:13 arm64
|
||||
debian:13 armhf
|
||||
debian:13 i386
|
||||
debian:13 riscv64
|
||||
fedora:40 amd64
|
||||
fedora:40 arm64
|
||||
fedora:41 amd64
|
||||
fedora:41 arm64
|
||||
fedora:42 amd64
|
||||
fedora:42 arm64
|
||||
fedora:43 amd64
|
||||
fedora:43 arm64
|
||||
quay.io/rockylinux/rockylinux:10 amd64
|
||||
quay.io/rockylinux/rockylinux:10 arm64
|
||||
quay.io/rockylinux/rockylinux:8 amd64
|
||||
quay.io/rockylinux/rockylinux:8 arm64
|
||||
quay.io/rockylinux/rockylinux:9 amd64
|
||||
quay.io/rockylinux/rockylinux:9 arm64
|
||||
ubuntu:22.04 amd64
|
||||
ubuntu:22.04 arm64
|
||||
ubuntu:22.04 armhf
|
||||
ubuntu:22.04 riscv64
|
||||
ubuntu:24.04 amd64
|
||||
ubuntu:24.04 arm64
|
||||
ubuntu:24.04 armhf
|
||||
ubuntu:24.04 riscv64
|
||||
ubuntu:25.04 amd64
|
||||
ubuntu:25.04 arm64
|
||||
ubuntu:25.04 armhf
|
||||
ubuntu:25.04 riscv64
|
||||
@@ -9,10 +9,12 @@ if [ "${VERSION}" = "" ]; then
|
||||
VERSION="unknown"
|
||||
fi
|
||||
|
||||
echo "version = ${VERSION}"
|
||||
echo -n "${VERSION}" > VERSION
|
||||
grep -q \"${VERSION}\" src/version.hpp
|
||||
grep -sq \"${VERSION}\" src/version.hpp
|
||||
RV=$?
|
||||
if [ $RV -ne 0 ]; then
|
||||
echo "Writing 'src/version.hpp'"
|
||||
echo "#pragma once" > src/version.hpp
|
||||
echo "static const char MERGERFS_VERSION[] = \"${VERSION}\";" >> src/version.hpp
|
||||
fi
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
9
|
||||
Vendored
+1
-1
@@ -2,7 +2,7 @@ Source: mergerfs
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
Build-Depends: debhelper (>= 8.0.0)
|
||||
Build-Depends: debhelper-compat (= 10)
|
||||
Standards-Version: 3.9.4
|
||||
Homepage: http://github.com/trapexit/mergerfs
|
||||
|
||||
|
||||
Vendored
+8
-3
@@ -1,11 +1,16 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
export DH_VERBOSE=1
|
||||
|
||||
%:
|
||||
dh $@ --parallel
|
||||
dh $@
|
||||
|
||||
override_dh_auto_build:
|
||||
$(MAKE) release
|
||||
|
||||
override_dh_auto_install:
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/mergerfs PREFIX=/usr install
|
||||
$(MAKE) \
|
||||
DESTDIR=$(CURDIR)/debian/mergerfs \
|
||||
PREFIX=/usr \
|
||||
install
|
||||
@@ -1,137 +0,0 @@
|
||||
VERSION = 2.9.7-mergerfs_2.30.0
|
||||
|
||||
OS := $(shell uname -s)
|
||||
ifeq ($(OS),Linux)
|
||||
UTILS := utils
|
||||
INSTALLUTILS := install-utils
|
||||
else
|
||||
UTILS :=
|
||||
INSTALLUTILS :=
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
OPT_FLAGS := -O0 -g -fsanitize=undefined
|
||||
else
|
||||
OPT_FLAGS := -O2
|
||||
endif
|
||||
|
||||
DESTDIR =
|
||||
PREFIX = /usr/local
|
||||
EXEC_PREFIX = $(PREFIX)
|
||||
DATAROOTDIR = $(PREFIX)/share
|
||||
DATADIR = $(DATAROOTDIR)
|
||||
BINDIR = $(EXEC_PREFIX)/bin
|
||||
SBINDIR = /sbin
|
||||
MANDIR = $(DATAROOTDIR)/man
|
||||
MAN1DIR = $(MANDIR)/man1
|
||||
|
||||
INSTALLBINDIR = $(DESTDIR)$(BINDIR)
|
||||
INSTALLSBINDIR = $(DESTDIR)$(SBINDIR)
|
||||
INSTALLMAN1DIR = $(DESTDIR)$(MAN1DIR)
|
||||
|
||||
AR ?= ar
|
||||
|
||||
SRC_C = \
|
||||
lib/buffer.c \
|
||||
lib/crc32b.c \
|
||||
lib/debug.c \
|
||||
lib/fuse.c \
|
||||
lib/fuse_dirents.c \
|
||||
lib/fuse_lowlevel.c \
|
||||
lib/fuse_mt.c \
|
||||
lib/fuse_node.c \
|
||||
lib/fuse_opt.c \
|
||||
lib/fuse_session.c \
|
||||
lib/fuse_signals.c \
|
||||
lib/helper.c \
|
||||
lib/mount.c
|
||||
SRC_CPP = \
|
||||
lib/format.cpp \
|
||||
lib/os.cpp \
|
||||
lib/cpu.cpp \
|
||||
lib/fuse_loop_mt.cpp \
|
||||
lib/fuse_msgbuf.cpp
|
||||
OBJS_C = $(SRC_C:lib/%.c=build/%.o)
|
||||
OBJS_CPP = $(SRC_CPP:lib/%.cpp=build/%.o)
|
||||
DEPS_C = $(SRC_C:lib/%.c=build/%.d)
|
||||
DEPS_CPP = $(SRC_CPP:lib/%.cpp=build/%.d)
|
||||
CFLAGS ?= \
|
||||
$(OPT_FLAGS)
|
||||
CFLAGS := \
|
||||
${CFLAGS} \
|
||||
-std=gnu99 \
|
||||
-Wall \
|
||||
-pipe \
|
||||
-MMD
|
||||
CXXFLAGS := \
|
||||
${CXXFLAGS} \
|
||||
-std=c++11 \
|
||||
-Wall \
|
||||
-pipe \
|
||||
-MMD
|
||||
FUSERMOUNT_DIR = $(BINDIR)
|
||||
FUSE_FLAGS = \
|
||||
-Iinclude \
|
||||
-Ibuild \
|
||||
-D_REENTRANT \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
-DPACKAGE_VERSION=\"$(VERSION)\" \
|
||||
-DFUSERMOUNT_DIR=\"$(FUSERMOUNT_DIR)\"
|
||||
LDFLAGS := \
|
||||
${LDFLAGS} \
|
||||
-lrt \
|
||||
-pthread
|
||||
|
||||
all: build/libfuse.a $(UTILS)
|
||||
|
||||
build/config.h: build/stamp
|
||||
ecfd/build | tee build/config.h
|
||||
|
||||
build/stamp:
|
||||
mkdir -p build
|
||||
touch $@
|
||||
|
||||
objects: build/config.h
|
||||
$(MAKE) $(OBJS_C) $(OBJS_CPP)
|
||||
|
||||
build/libfuse.a: objects
|
||||
${AR} rcs build/libfuse.a $(OBJS_C) $(OBJS_CPP)
|
||||
|
||||
utils: mergerfs-fusermount mount.mergerfs
|
||||
|
||||
build/mergerfs-fusermount: build/config.h util/fusermount.c lib/mount_util.c
|
||||
$(CC) $(CFLAGS) $(FUSE_FLAGS) -Ilib -o build/mergerfs-fusermount util/fusermount.c lib/mount_util.c
|
||||
|
||||
mergerfs-fusermount: build/mergerfs-fusermount
|
||||
|
||||
build/mount.mergerfs: build/libfuse.a util/mount.mergerfs.c
|
||||
$(CC) $(CFLAGS) $(FUSE_FLAGS) -o build/mount.mergerfs util/mount.mergerfs.c build/libfuse.a $(LDFLAGS)
|
||||
|
||||
mount.mergerfs: build/mount.mergerfs
|
||||
|
||||
build/%.o: lib/%.c
|
||||
$(CC) $(CFLAGS) $(FUSE_FLAGS) -c $< -o $@
|
||||
|
||||
build/%.o: lib/%.cpp
|
||||
$(CXX) $(CXXFLAGS) $(FUSE_FLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
|
||||
distclean: clean
|
||||
|
||||
strip:
|
||||
strip --strip-all build/mount.mergerfs
|
||||
strip --strip-all build/mergerfs-fusermount
|
||||
|
||||
install-utils: mergerfs-fusermount mount.mergerfs strip
|
||||
install -D build/mergerfs-fusermount "$(INSTALLBINDIR)/mergerfs-fusermount"
|
||||
install -D build/mount.mergerfs "$(INSTALLSBINDIR)/mount.mergerfs"
|
||||
chown root "$(INSTALLBINDIR)/mergerfs-fusermount"
|
||||
chmod u+s "$(INSTALLBINDIR)/mergerfs-fusermount"
|
||||
|
||||
install: $(INSTALLUTILS)
|
||||
|
||||
.PHONY: objects strip utils install install-utils
|
||||
|
||||
-include $(DEPS_C) $(DEPS_CPP)
|
||||
@@ -1,16 +0,0 @@
|
||||
# ecfd: embeddable C feature discovery
|
||||
|
||||
This is a simple script and set of tests to help with what would traditionally be the `configure` step of most C/C++. It is intended to be simple to be embedded into a project and only depends on the C compiler and /bin/sh.
|
||||
|
||||
|
||||
## USAGE
|
||||
|
||||
First copy `ecfd` into your project. Next simply call the build script which will run the tests and output a `config.` style file to `stdout`. Compile errors will output to `stderr` which can be used to understand why they aren't working.
|
||||
|
||||
```
|
||||
$ ./ecfd/build > include/config.h
|
||||
```
|
||||
|
||||
## TESTS
|
||||
|
||||
Each test is in a single module. The build script will try to compile each module and on success will execute the program. If anything is printed to `stdout` it will be appended to the `#define` printed to the build script's `stdout`. If the compilation fails nothing will be printed. Look at the tests directory for examples.
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PWD=$(pwd)
|
||||
BASEPATH="${PWD}/${0%/*}"
|
||||
|
||||
CC=${CC:-cc}
|
||||
OUTPUT="/dev/null"
|
||||
|
||||
echo "#ifndef CONFIG_H_INCLUDED"
|
||||
echo "#define CONFIG_H_INCLUDED"
|
||||
echo
|
||||
|
||||
IFS=
|
||||
for file in "${BASEPATH}/tests/"*.c
|
||||
do
|
||||
binary="${file%.c}"
|
||||
basename=$(basename ${binary})
|
||||
|
||||
${CC} -o "${binary}" "${file}" 1>&2
|
||||
if [ $? -eq 0 ]; then
|
||||
STDOUT=$(${binary})
|
||||
if [ "${STDOUT}" != "" ]; then
|
||||
echo "#define ${basename} ${STDOUT}"
|
||||
else
|
||||
echo "#define ${basename}"
|
||||
fi
|
||||
rm -f "${binary}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo "#endif"
|
||||
@@ -1,10 +0,0 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
(void)fork;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#include <malloc.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
malloc_trim(0);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(int argc,
|
||||
char *argv[])
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
(void)st.st_atim;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int
|
||||
main(int argc,
|
||||
char *argv[])
|
||||
{
|
||||
(void)utimensat;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define STATIC_ASSERT(condition) \
|
||||
((void)sizeof(char[1 - 2*!(condition)]))
|
||||
@@ -1,769 +0,0 @@
|
||||
/*
|
||||
FUSE: Filesystem in Userspace
|
||||
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||
|
||||
This program can be distributed under the terms of the GNU LGPLv2.
|
||||
See the file COPYING.LIB.
|
||||
*/
|
||||
|
||||
#ifndef _FUSE_H_
|
||||
#define _FUSE_H_
|
||||
|
||||
#include "extern_c.h"
|
||||
#include "fuse_common.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <utime.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/* ----------------------------------------------------------- *
|
||||
* Basic FUSE API *
|
||||
* ----------------------------------------------------------- */
|
||||
|
||||
/** Handle for a FUSE filesystem */
|
||||
struct fuse;
|
||||
|
||||
/** Structure containing a raw command */
|
||||
struct fuse_cmd;
|
||||
|
||||
struct fuse_dirents_t;
|
||||
typedef struct fuse_dirents_t fuse_dirents_t;
|
||||
|
||||
/**
|
||||
* The file system operations:
|
||||
*
|
||||
* Most of these should work very similarly to the well known UNIX
|
||||
* file system operations. A major exception is that instead of
|
||||
* returning an error in 'errno', the operation should return the
|
||||
* negated error value (-errno) directly.
|
||||
*
|
||||
* All methods are optional, but some are essential for a useful
|
||||
* filesystem (e.g. getattr). Open, flush, release, fsync, opendir,
|
||||
* releasedir, fsyncdir, access, create, ftruncate, fgetattr, lock,
|
||||
* init and destroy are special purpose methods, without which a full
|
||||
* featured filesystem can still be implemented.
|
||||
*
|
||||
* Almost all operations take a path which can be of any length.
|
||||
*
|
||||
* Changed in fuse 2.8.0 (regardless of API version)
|
||||
* Previously, paths were limited to a length of PATH_MAX.
|
||||
*
|
||||
* See http://fuse.sourceforge.net/wiki/ for more information. There
|
||||
* is also a snapshot of the relevant wiki pages in the doc/ folder.
|
||||
*/
|
||||
struct fuse_operations
|
||||
{
|
||||
/** Get file attributes.
|
||||
*
|
||||
* Similar to stat(). The 'st_dev' and 'st_blksize' fields are
|
||||
* ignored. The 'st_ino' field is ignored except if the 'use_ino'
|
||||
* mount option is given.
|
||||
*/
|
||||
int (*getattr) (const char *, struct stat *, fuse_timeouts_t *);
|
||||
|
||||
/** Read the target of a symbolic link
|
||||
*
|
||||
* The buffer should be filled with a null terminated string. The
|
||||
* buffer size argument includes the space for the terminating
|
||||
* null character. If the linkname is too long to fit in the
|
||||
* buffer, it should be truncated. The return value should be 0
|
||||
* for success.
|
||||
*/
|
||||
int (*readlink) (const char *, char *, size_t);
|
||||
|
||||
/** Create a file node
|
||||
*
|
||||
* This is called for creation of all non-directory, non-symlink
|
||||
* nodes. If the filesystem defines a create() method, then for
|
||||
* regular files that will be called instead.
|
||||
*/
|
||||
int (*mknod) (const char *, mode_t, dev_t);
|
||||
|
||||
/** Create a directory
|
||||
*
|
||||
* Note that the mode argument may not have the type specification
|
||||
* bits set, i.e. S_ISDIR(mode) can be false. To obtain the
|
||||
* correct directory type bits use mode|S_IFDIR
|
||||
* */
|
||||
int (*mkdir) (const char *, mode_t);
|
||||
|
||||
/** Hide files unlinked / renamed over
|
||||
*
|
||||
* Allows storing of a file handle when a file is unlinked
|
||||
* while open. Helps manage the fact the kernel usually does
|
||||
* not send fh with getattr requests.
|
||||
*/
|
||||
int (*prepare_hide)(const char *name_, uint64_t *fh_);
|
||||
int (*free_hide)(const uint64_t fh_);
|
||||
|
||||
/** Remove a file */
|
||||
int (*unlink) (const char *);
|
||||
|
||||
/** Remove a directory */
|
||||
int (*rmdir) (const char *);
|
||||
|
||||
/** Create a symbolic link */
|
||||
int (*symlink) (const char *, const char *, struct stat *, fuse_timeouts_t *);
|
||||
|
||||
/** Rename a file */
|
||||
int (*rename) (const char *, const char *);
|
||||
|
||||
/** Create a hard link to a file */
|
||||
int (*link) (const char *, const char *, struct stat *, fuse_timeouts_t *);
|
||||
|
||||
/** Change the permission bits of a file */
|
||||
int (*chmod) (const char *, mode_t);
|
||||
int (*fchmod)(const fuse_file_info_t *, const mode_t);
|
||||
|
||||
/** Change the owner and group of a file */
|
||||
int (*chown) (const char *, uid_t, gid_t);
|
||||
int (*fchown)(const fuse_file_info_t *, const uid_t, const gid_t);
|
||||
|
||||
/** Change the size of a file */
|
||||
int (*truncate) (const char *, off_t);
|
||||
|
||||
/** File open operation
|
||||
*
|
||||
* No creation (O_CREAT, O_EXCL) and by default also no
|
||||
* truncation (O_TRUNC) flags will be passed to open(). If an
|
||||
* application specifies O_TRUNC, fuse first calls truncate()
|
||||
* and then open(). Only if 'atomic_o_trunc' has been
|
||||
* specified and kernel version is 2.6.24 or later, O_TRUNC is
|
||||
* passed on to open.
|
||||
*
|
||||
* Unless the 'default_permissions' mount option is given,
|
||||
* open should check if the operation is permitted for the
|
||||
* given flags. Optionally open may also return an arbitrary
|
||||
* filehandle in the fuse_file_info structure, which will be
|
||||
* passed to all file operations.
|
||||
*
|
||||
* Changed in version 2.2
|
||||
*/
|
||||
int (*open) (const char *, fuse_file_info_t *);
|
||||
|
||||
/** Get file system statistics
|
||||
*
|
||||
* The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
|
||||
*
|
||||
* Replaced 'struct statfs' parameter with 'struct statvfs' in
|
||||
* version 2.5
|
||||
*/
|
||||
int (*statfs) (const char *, struct statvfs *);
|
||||
|
||||
/** Possibly flush cached data
|
||||
*
|
||||
* BIG NOTE: This is not equivalent to fsync(). It's not a
|
||||
* request to sync dirty data.
|
||||
*
|
||||
* Flush is called on each close() of a file descriptor. So if a
|
||||
* filesystem wants to return write errors in close() and the file
|
||||
* has cached dirty data, this is a good place to write back data
|
||||
* and return any errors. Since many applications ignore close()
|
||||
* errors this is not always useful.
|
||||
*
|
||||
* NOTE: The flush() method may be called more than once for each
|
||||
* open(). This happens if more than one file descriptor refers
|
||||
* to an opened file due to dup(), dup2() or fork() calls. It is
|
||||
* not possible to determine if a flush is final, so each flush
|
||||
* should be treated equally. Multiple write-flush sequences are
|
||||
* relatively rare, so this shouldn't be a problem.
|
||||
*
|
||||
* Filesystems shouldn't assume that flush will always be called
|
||||
* after some writes, or that if will be called at all.
|
||||
*
|
||||
* Changed in version 2.2
|
||||
*/
|
||||
int (*flush) (const fuse_file_info_t *);
|
||||
|
||||
/** Release an open file
|
||||
*
|
||||
* Release is called when there are no more references to an open
|
||||
* file: all file descriptors are closed and all memory mappings
|
||||
* are unmapped.
|
||||
*
|
||||
* For every open() call there will be exactly one release() call
|
||||
* with the same flags and file descriptor. It is possible to
|
||||
* have a file opened more than once, in which case only the last
|
||||
* release will mean, that no more reads/writes will happen on the
|
||||
* file. The return value of release is ignored.
|
||||
*
|
||||
* Changed in version 2.2
|
||||
*/
|
||||
int (*release) (const fuse_file_info_t *);
|
||||
|
||||
/** Synchronize file contents
|
||||
*
|
||||
* If the datasync parameter is non-zero, then only the user data
|
||||
* should be flushed, not the meta data.
|
||||
*
|
||||
* Changed in version 2.2
|
||||
*/
|
||||
int (*fsync) (const fuse_file_info_t *, int);
|
||||
|
||||
/** Set extended attributes */
|
||||
int (*setxattr) (const char *, const char *, const char *, size_t, int);
|
||||
|
||||
/** Get extended attributes */
|
||||
int (*getxattr) (const char *, const char *, char *, size_t);
|
||||
|
||||
/** List extended attributes */
|
||||
int (*listxattr) (const char *, char *, size_t);
|
||||
|
||||
/** Remove extended attributes */
|
||||
int (*removexattr) (const char *, const char *);
|
||||
|
||||
/** Open directory
|
||||
*
|
||||
* Unless the 'default_permissions' mount option is given,
|
||||
* this method should check if opendir is permitted for this
|
||||
* directory. Optionally opendir may also return an arbitrary
|
||||
* filehandle in the fuse_file_info structure, which will be
|
||||
* passed to readdir, closedir and fsyncdir.
|
||||
*
|
||||
* Introduced in version 2.3
|
||||
*/
|
||||
int (*opendir) (const char *,
|
||||
fuse_file_info_t *);
|
||||
|
||||
/** Read directory
|
||||
*
|
||||
* This supersedes the old getdir() interface. New applications
|
||||
* should use this.
|
||||
*
|
||||
* The filesystem may choose between two modes of operation:
|
||||
*
|
||||
* 1) The readdir implementation ignores the offset parameter, and
|
||||
* passes zero to the filler function's offset. The filler
|
||||
* function will not return '1' (unless an error happens), so the
|
||||
* whole directory is read in a single readdir operation. This
|
||||
* works just like the old getdir() method.
|
||||
*
|
||||
* 2) The readdir implementation keeps track of the offsets of the
|
||||
* directory entries. It uses the offset parameter and always
|
||||
* passes non-zero offset to the filler function. When the buffer
|
||||
* is full (or an error happens) the filler function will return
|
||||
* '1'.
|
||||
*
|
||||
* Introduced in version 2.3
|
||||
*/
|
||||
int (*readdir)(const fuse_file_info_t *,
|
||||
fuse_dirents_t *);
|
||||
|
||||
int (*readdir_plus)(const fuse_file_info_t *,
|
||||
fuse_dirents_t *);
|
||||
|
||||
|
||||
/** Release directory
|
||||
*
|
||||
* Introduced in version 2.3
|
||||
*/
|
||||
int (*releasedir) (const fuse_file_info_t *);
|
||||
|
||||
/** Synchronize directory contents
|
||||
*
|
||||
* If the datasync parameter is non-zero, then only the user data
|
||||
* should be flushed, not the meta data
|
||||
*
|
||||
* Introduced in version 2.3
|
||||
*/
|
||||
int (*fsyncdir) (const fuse_file_info_t *, int);
|
||||
|
||||
/**
|
||||
* Initialize filesystem
|
||||
*
|
||||
* The return value will passed in the private_data field of
|
||||
* fuse_context to all file operations and as a parameter to the
|
||||
* destroy() method.
|
||||
*
|
||||
* Introduced in version 2.3
|
||||
* Changed in version 2.6
|
||||
*/
|
||||
void *(*init) (struct fuse_conn_info *conn);
|
||||
|
||||
/**
|
||||
* Clean up filesystem
|
||||
*
|
||||
* Called on filesystem exit.
|
||||
*
|
||||
* Introduced in version 2.3
|
||||
*/
|
||||
void (*destroy) (void);
|
||||
|
||||
/**
|
||||
* Check file access permissions
|
||||
*
|
||||
* This will be called for the access() system call. If the
|
||||
* 'default_permissions' mount option is given, this method is not
|
||||
* called.
|
||||
*
|
||||
* This method is not called under Linux kernel versions 2.4.x
|
||||
*
|
||||
* Introduced in version 2.5
|
||||
*/
|
||||
int (*access) (const char *, int);
|
||||
|
||||
/**
|
||||
* Create and open a file
|
||||
*
|
||||
* If the file does not exist, first create it with the specified
|
||||
* mode, and then open it.
|
||||
*
|
||||
* If this method is not implemented or under Linux kernel
|
||||
* versions earlier than 2.6.15, the mknod() and open() methods
|
||||
* will be called instead.
|
||||
*
|
||||
* Introduced in version 2.5
|
||||
*/
|
||||
int (*create) (const char *, mode_t, fuse_file_info_t *);
|
||||
|
||||
/**
|
||||
* Change the size of an open file
|
||||
*
|
||||
* This method is called instead of the truncate() method if the
|
||||
* truncation was invoked from an ftruncate() system call.
|
||||
*
|
||||
* If this method is not implemented or under Linux kernel
|
||||
* versions earlier than 2.6.15, the truncate() method will be
|
||||
* called instead.
|
||||
*
|
||||
* Introduced in version 2.5
|
||||
*/
|
||||
int (*ftruncate) (const fuse_file_info_t *, off_t);
|
||||
|
||||
/**
|
||||
* Get attributes from an open file
|
||||
*
|
||||
* This method is called instead of the getattr() method if the
|
||||
* file information is available.
|
||||
*
|
||||
* Currently this is only called after the create() method if that
|
||||
* is implemented (see above). Later it may be called for
|
||||
* invocations of fstat() too.
|
||||
*
|
||||
* Introduced in version 2.5
|
||||
*/
|
||||
int (*fgetattr) (const fuse_file_info_t *, struct stat *, fuse_timeouts_t *);
|
||||
|
||||
/**
|
||||
* Perform POSIX file locking operation
|
||||
*
|
||||
* The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.
|
||||
*
|
||||
* For the meaning of fields in 'struct flock' see the man page
|
||||
* for fcntl(2). The l_whence field will always be set to
|
||||
* SEEK_SET.
|
||||
*
|
||||
* For checking lock ownership, the 'fuse_file_info->owner'
|
||||
* argument must be used.
|
||||
*
|
||||
* For F_GETLK operation, the library will first check currently
|
||||
* held locks, and if a conflicting lock is found it will return
|
||||
* information without calling this method. This ensures, that
|
||||
* for local locks the l_pid field is correctly filled in. The
|
||||
* results may not be accurate in case of race conditions and in
|
||||
* the presence of hard links, but it's unlikely that an
|
||||
* application would rely on accurate GETLK results in these
|
||||
* cases. If a conflicting lock is not found, this method will be
|
||||
* called, and the filesystem may fill out l_pid by a meaningful
|
||||
* value, or it may leave this field zero.
|
||||
*
|
||||
* For F_SETLK and F_SETLKW the l_pid field will be set to the pid
|
||||
* of the process performing the locking operation.
|
||||
*
|
||||
* Note: if this method is not implemented, the kernel will still
|
||||
* allow file locking to work locally. Hence it is only
|
||||
* interesting for network filesystems and similar.
|
||||
*
|
||||
* Introduced in version 2.6
|
||||
*/
|
||||
int (*lock) (const fuse_file_info_t *,
|
||||
int cmd,
|
||||
struct flock *);
|
||||
|
||||
/**
|
||||
* Change the access and modification times of a file with
|
||||
* nanosecond resolution
|
||||
*
|
||||
* This supersedes the old utime() interface. New applications
|
||||
* should use this.
|
||||
*
|
||||
* See the utimensat(2) man page for details.
|
||||
*
|
||||
* Introduced in version 2.6
|
||||
*/
|
||||
int (*utimens)(const char *, const struct timespec tv[2]);
|
||||
int (*futimens)(const fuse_file_info_t *ffi_, const struct timespec tv_[2]);
|
||||
|
||||
/**
|
||||
* Map block index within file to block index within device
|
||||
*
|
||||
* Note: This makes sense only for block device backed filesystems
|
||||
* mounted with the 'blkdev' option
|
||||
*
|
||||
* Introduced in version 2.6
|
||||
*/
|
||||
int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
|
||||
|
||||
/**
|
||||
* Ioctl
|
||||
*
|
||||
* flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in
|
||||
* 64bit environment. The size and direction of data is
|
||||
* determined by _IOC_*() decoding of cmd. For _IOC_NONE,
|
||||
* data will be NULL, for _IOC_WRITE data is out area, for
|
||||
* _IOC_READ in area and if both are set in/out area. In all
|
||||
* non-NULL cases, the area is of _IOC_SIZE(cmd) bytes.
|
||||
*
|
||||
* If flags has FUSE_IOCTL_DIR then the fuse_file_info refers to a
|
||||
* directory file handle.
|
||||
*
|
||||
* Introduced in version 2.8
|
||||
*/
|
||||
int (*ioctl) (const fuse_file_info_t *ffi,
|
||||
unsigned long cmd,
|
||||
void *arg,
|
||||
unsigned int flags,
|
||||
void *data,
|
||||
uint32_t *out_bufsz);
|
||||
|
||||
/**
|
||||
* Poll for IO readiness events
|
||||
*
|
||||
* Note: If ph is non-NULL, the client should notify
|
||||
* when IO readiness events occur by calling
|
||||
* fuse_notify_poll() with the specified ph.
|
||||
*
|
||||
* Regardless of the number of times poll with a non-NULL ph
|
||||
* is received, single notification is enough to clear all.
|
||||
* Notifying more times incurs overhead but doesn't harm
|
||||
* correctness.
|
||||
*
|
||||
* The callee is responsible for destroying ph with
|
||||
* fuse_pollhandle_destroy() when no longer in use.
|
||||
*
|
||||
* Introduced in version 2.8
|
||||
*/
|
||||
int (*poll) (const fuse_file_info_t *ffi,
|
||||
fuse_pollhandle_t *ph,
|
||||
unsigned *reventsp);
|
||||
|
||||
/** Write contents of buffer to an open file
|
||||
*
|
||||
* Similar to the write() method, but data is supplied in a
|
||||
* generic buffer. Use fuse_buf_copy() to transfer data to
|
||||
* the destination.
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*/
|
||||
int (*write) (const fuse_file_info_t *ffi,
|
||||
const char *data,
|
||||
size_t size,
|
||||
off_t off);
|
||||
|
||||
/** Store data from an open file in a buffer
|
||||
*
|
||||
* Similar to the read() method, but data is stored and
|
||||
* returned in a generic buffer.
|
||||
*
|
||||
* No actual copying of data has to take place, the source
|
||||
* file descriptor may simply be stored in the buffer for
|
||||
* later data transfer.
|
||||
*
|
||||
* The buffer must be allocated dynamically and stored at the
|
||||
* location pointed to by bufp. If the buffer contains memory
|
||||
* regions, they too must be allocated using malloc(). The
|
||||
* allocated memory will be freed by the caller.
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*/
|
||||
int (*read)(const fuse_file_info_t *ffi,
|
||||
char *buf,
|
||||
size_t size,
|
||||
off_t off);
|
||||
/**
|
||||
* Perform BSD file locking operation
|
||||
*
|
||||
* The op argument will be either LOCK_SH, LOCK_EX or LOCK_UN
|
||||
*
|
||||
* Nonblocking requests will be indicated by ORing LOCK_NB to
|
||||
* the above operations
|
||||
*
|
||||
* For more information see the flock(2) manual page.
|
||||
*
|
||||
* Additionally fi->owner will be set to a value unique to
|
||||
* this open file. This same value will be supplied to
|
||||
* ->release() when the file is released.
|
||||
*
|
||||
* Note: if this method is not implemented, the kernel will still
|
||||
* allow file locking to work locally. Hence it is only
|
||||
* interesting for network filesystems and similar.
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*/
|
||||
int (*flock) (const fuse_file_info_t *, int op);
|
||||
|
||||
/**
|
||||
* Allocates space for an open file
|
||||
*
|
||||
* This function ensures that required space is allocated for specified
|
||||
* file. If this function returns success then any subsequent write
|
||||
* request to specified range is guaranteed not to fail because of lack
|
||||
* of space on the file system media.
|
||||
*
|
||||
* Introduced in version 2.9.1
|
||||
*/
|
||||
int (*fallocate) (const fuse_file_info_t *, int, off_t, off_t);
|
||||
|
||||
/**
|
||||
* Copy a range of data from one file to another
|
||||
*
|
||||
* Performs an optimized copy between two file descriptors without
|
||||
* the additional cost of transferring data through the FUSE kernel
|
||||
* module to user space (glibc) and then back into the FUSE filesystem
|
||||
* again.
|
||||
*
|
||||
* In case this method is not implemented, glibc falls back to
|
||||
* reading data from the source and writing to the
|
||||
* destination. Effectively doing an inefficient copy of the
|
||||
* data.
|
||||
*/
|
||||
ssize_t (*copy_file_range)(const fuse_file_info_t *fi_in,
|
||||
off_t offset_in,
|
||||
const fuse_file_info_t *fi_out,
|
||||
off_t offset_out,
|
||||
size_t size,
|
||||
int flags);
|
||||
};
|
||||
|
||||
/** Extra context that may be needed by some filesystems
|
||||
*
|
||||
* The uid, gid and pid fields are not filled in case of a writepage
|
||||
* operation.
|
||||
*/
|
||||
struct fuse_context
|
||||
{
|
||||
/** Pointer to the fuse object */
|
||||
struct fuse *fuse;
|
||||
|
||||
/** User ID of the calling process */
|
||||
uid_t uid;
|
||||
|
||||
/** Group ID of the calling process */
|
||||
gid_t gid;
|
||||
|
||||
/** Thread ID of the calling process */
|
||||
pid_t pid;
|
||||
|
||||
/** Umask of the calling process (introduced in version 2.8) */
|
||||
mode_t umask;
|
||||
};
|
||||
|
||||
/**
|
||||
* Main function of FUSE.
|
||||
*
|
||||
* This is for the lazy. This is all that has to be called from the
|
||||
* main() function.
|
||||
*
|
||||
* This function does the following:
|
||||
* - parses command line options (-d -s and -h)
|
||||
* - passes relevant mount options to the fuse_mount()
|
||||
* - installs signal handlers for INT, HUP, TERM and PIPE
|
||||
* - registers an exit handler to unmount the filesystem on program exit
|
||||
* - creates a fuse handle
|
||||
* - registers the operations
|
||||
* - calls either the single-threaded or the multi-threaded event loop
|
||||
*
|
||||
* Note: this is currently implemented as a macro.
|
||||
*
|
||||
* @param argc the argument counter passed to the main() function
|
||||
* @param argv the argument vector passed to the main() function
|
||||
* @param op the file system operation
|
||||
* @return 0 on success, nonzero on failure
|
||||
*/
|
||||
/*
|
||||
int fuse_main(int argc, char *argv[], const struct fuse_operations *op);
|
||||
*/
|
||||
#define fuse_main(argc, argv, op) \
|
||||
fuse_main_real(argc, argv, op, sizeof(*(op)))
|
||||
|
||||
/* ----------------------------------------------------------- *
|
||||
* More detailed API *
|
||||
* ----------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Create a new FUSE filesystem.
|
||||
*
|
||||
* @param ch the communication channel
|
||||
* @param args argument vector
|
||||
* @param op the filesystem operations
|
||||
* @param op_size the size of the fuse_operations structure
|
||||
* @return the created FUSE handle
|
||||
*/
|
||||
struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
|
||||
const struct fuse_operations *op, size_t op_size);
|
||||
|
||||
/**
|
||||
* Destroy the FUSE handle.
|
||||
*
|
||||
* The communication channel attached to the handle is also destroyed.
|
||||
*
|
||||
* NOTE: This function does not unmount the filesystem. If this is
|
||||
* needed, call fuse_unmount() before calling this function.
|
||||
*
|
||||
* @param f the FUSE handle
|
||||
*/
|
||||
void fuse_destroy(struct fuse *f);
|
||||
|
||||
/**
|
||||
* Exit from event loop
|
||||
*
|
||||
* @param f the FUSE handle
|
||||
*/
|
||||
void fuse_exit(struct fuse *f);
|
||||
|
||||
int fuse_config_read_thread_count(const struct fuse *f);
|
||||
int fuse_config_process_thread_count(const struct fuse *f);
|
||||
const char* fuse_config_pin_threads(const struct fuse *f);
|
||||
|
||||
/**
|
||||
* FUSE event loop with multiple threads
|
||||
*
|
||||
* Requests from the kernel are processed, and the appropriate
|
||||
* operations are called. Request are processed in parallel by
|
||||
* distributing them between multiple threads.
|
||||
*
|
||||
* Calling this function requires the pthreads library to be linked to
|
||||
* the application.
|
||||
*
|
||||
* @param f the FUSE handle
|
||||
* @return 0 if no error occurred, -1 otherwise
|
||||
*/
|
||||
int fuse_loop_mt(struct fuse *f);
|
||||
|
||||
/**
|
||||
* Get the current context
|
||||
*
|
||||
* The context is only valid for the duration of a filesystem
|
||||
* operation, and thus must not be stored and used later.
|
||||
*
|
||||
* @return the context
|
||||
*/
|
||||
struct fuse_context *fuse_get_context(void);
|
||||
|
||||
/**
|
||||
* Check if the current request has already been interrupted
|
||||
*
|
||||
* @return 1 if the request has been interrupted, 0 otherwise
|
||||
*/
|
||||
int fuse_interrupted(void);
|
||||
|
||||
/**
|
||||
* Obsolete, doesn't do anything
|
||||
*
|
||||
* @return -EINVAL
|
||||
*/
|
||||
int fuse_invalidate(struct fuse *f, const char *path);
|
||||
|
||||
/* Deprecated, don't use */
|
||||
int fuse_is_lib_option(const char *opt);
|
||||
|
||||
/**
|
||||
* The real main function
|
||||
*
|
||||
* Do not call this directly, use fuse_main()
|
||||
*/
|
||||
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, size_t op_size);
|
||||
|
||||
int fuse_start_maintenance_thread(struct fuse *fuse);
|
||||
void fuse_stop_maintenance_thread(struct fuse *fuse);
|
||||
|
||||
int fuse_log_metrics_get(void);
|
||||
void fuse_log_metrics_set(int enabled);
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over cache removing stale entries
|
||||
* use in conjunction with "-oremember"
|
||||
*
|
||||
* NOTE: This is already done for the standard sessions
|
||||
*
|
||||
* @param fuse struct fuse pointer for fuse instance
|
||||
* @return the number of seconds until the next cleanup
|
||||
*/
|
||||
int fuse_clean_cache(struct fuse *fuse);
|
||||
|
||||
/*
|
||||
* Stacking API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fuse filesystem object
|
||||
*
|
||||
* This is opaque object represents a filesystem layer
|
||||
*/
|
||||
struct fuse_fs;
|
||||
|
||||
/*
|
||||
* These functions call the relevant filesystem operation, and return
|
||||
* the result.
|
||||
*
|
||||
* If the operation is not defined, they return -ENOSYS, with the
|
||||
* exception of fuse_fs_open, fuse_fs_release, fuse_fs_opendir,
|
||||
* fuse_fs_releasedir and fuse_fs_statfs, which return 0.
|
||||
*/
|
||||
|
||||
int fuse_notify_poll(fuse_pollhandle_t *ph);
|
||||
|
||||
/**
|
||||
* Create a new fuse filesystem object
|
||||
*
|
||||
* This is usually called from the factory of a fuse module to create
|
||||
* a new instance of a filesystem.
|
||||
*
|
||||
* @param op the filesystem operations
|
||||
* @param op_size the size of the fuse_operations structure
|
||||
* @return a new filesystem object
|
||||
*/
|
||||
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size);
|
||||
|
||||
/* ----------------------------------------------------------- *
|
||||
* Advanced API for event handling, don't worry about this... *
|
||||
* ----------------------------------------------------------- */
|
||||
|
||||
/* NOTE: the following functions are deprecated, and will be removed
|
||||
from the 3.0 API. Use the lowlevel session functions instead */
|
||||
|
||||
/** Function type used to process commands */
|
||||
typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
|
||||
|
||||
/** This is the part of fuse_main() before the event loop */
|
||||
struct fuse *fuse_setup(int argc, char *argv[],
|
||||
const struct fuse_operations *op, size_t op_size,
|
||||
char **mountpoint);
|
||||
|
||||
/** This is the part of fuse_main() after the event loop */
|
||||
void fuse_teardown(struct fuse *fuse, char *mountpoint);
|
||||
|
||||
/** Multi threaded event loop, which calls the custom command
|
||||
processor function */
|
||||
int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data);
|
||||
|
||||
/** Return the exited flag, which indicates if fuse_exit() has been
|
||||
called */
|
||||
int fuse_exited(struct fuse *f);
|
||||
|
||||
/** This function is obsolete and implemented as a no-op */
|
||||
void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
|
||||
|
||||
/** Get session from fuse object */
|
||||
struct fuse_session *fuse_get_session(struct fuse *f);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif /* _FUSE_H_ */
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "extern_c.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#include "kvec.h"
|
||||
#include "fuse_dirent.h"
|
||||
#include "fuse_direntplus.h"
|
||||
#include "fuse_entry.h"
|
||||
#include "linux_dirent64.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
enum fuse_dirents_type_e
|
||||
{
|
||||
UNSET = 0,
|
||||
NORMAL,
|
||||
PLUS
|
||||
};
|
||||
typedef enum fuse_dirents_type_e fuse_dirents_type_t;
|
||||
|
||||
typedef struct fuse_dirents_t fuse_dirents_t;
|
||||
struct fuse_dirents_t
|
||||
{
|
||||
kvec_t(char) data;
|
||||
kvec_t(uint32_t) offs;
|
||||
fuse_dirents_type_t type;
|
||||
};
|
||||
|
||||
int fuse_dirents_init(fuse_dirents_t *d);
|
||||
void fuse_dirents_free(fuse_dirents_t *d);
|
||||
void fuse_dirents_reset(fuse_dirents_t *d);
|
||||
|
||||
int fuse_dirents_add(fuse_dirents_t *d,
|
||||
const struct dirent *de,
|
||||
const uint64_t namelen);
|
||||
int fuse_dirents_add_plus(fuse_dirents_t *d,
|
||||
const struct dirent *de,
|
||||
const uint64_t namelen,
|
||||
const fuse_entry_t *entry,
|
||||
const struct stat *st);
|
||||
int fuse_dirents_add_linux(fuse_dirents_t *d,
|
||||
const struct linux_dirent64 *de,
|
||||
const uint64_t namelen);
|
||||
int fuse_dirents_add_linux_plus(fuse_dirents_t *d,
|
||||
const struct linux_dirent64 *de,
|
||||
const uint64_t namelen,
|
||||
const fuse_entry_t *entry,
|
||||
const struct stat *st);
|
||||
|
||||
void *fuse_dirents_find(fuse_dirents_t *d,
|
||||
const uint64_t ino);
|
||||
|
||||
int fuse_dirents_convert_plus2normal(fuse_dirents_t *d);
|
||||
|
||||
EXTERN_C_END
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct linux_dirent64
|
||||
{
|
||||
uint64_t ino;
|
||||
int64_t off;
|
||||
uint16_t reclen;
|
||||
uint8_t type;
|
||||
char name[];
|
||||
};
|
||||
@@ -1,165 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
|
||||
|
||||
template<typename T>
|
||||
class BoundedQueue
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
BoundedQueue(std::size_t max_size_,
|
||||
bool block_ = true)
|
||||
: _block(block),
|
||||
_max_size(max_size_)
|
||||
{
|
||||
if(_max_size == 0)
|
||||
_max_size = 1;
|
||||
}
|
||||
|
||||
bool
|
||||
push(const T& item_)
|
||||
{
|
||||
{
|
||||
std::unique_lock guard(_queue_lock);
|
||||
|
||||
_condition_push.wait(guard, [&]() { return _queue.size() < _max_size || !_block; });
|
||||
|
||||
if(_queue.size() == _max_size)
|
||||
return false;
|
||||
|
||||
_queue.push(item);
|
||||
}
|
||||
|
||||
_condition_pop.notify_one();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
push(T&& item_)
|
||||
{
|
||||
{
|
||||
std::unique_lock guard(_queue_lock);
|
||||
|
||||
_condition_push.wait(guard, [&]() { return _queue.size() < _max_size || !_block; });
|
||||
|
||||
if(_queue.size() == _max_size)
|
||||
return false;
|
||||
|
||||
_queue.push(std::move(item_));
|
||||
}
|
||||
_condition_pop.notify_one();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
bool
|
||||
emplace(Args&&... args_)
|
||||
{
|
||||
{
|
||||
std::unique_lock guard(_queue_lock);
|
||||
|
||||
_condition_push.wait(guard, [&]() { return _queue.size() < _max_size || !_block; });
|
||||
|
||||
if(_queue.size() == _max_size)
|
||||
return false;
|
||||
|
||||
_queue.emplace(std::forward<Args>(args_)...);
|
||||
}
|
||||
|
||||
_condition_pop.notify_one();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
pop(T& item_)
|
||||
{
|
||||
{
|
||||
std::unique_lock guard(_queue_lock);
|
||||
|
||||
_condition_pop.wait(guard, [&]() { return !_queue.empty() || !_block; });
|
||||
if(_queue.empty())
|
||||
return false;
|
||||
|
||||
item_ = std::move(_queue.front());
|
||||
|
||||
_queue.pop();
|
||||
}
|
||||
|
||||
_condition_push.notify_one();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
std::lock_guard guard(_queue_lock);
|
||||
|
||||
return _queue.size();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
capacity() const
|
||||
{
|
||||
return _max_size;
|
||||
}
|
||||
|
||||
bool
|
||||
empty() const
|
||||
{
|
||||
std::lock_guard guard(_queue_lock);
|
||||
|
||||
return _queue.empty();
|
||||
}
|
||||
|
||||
bool
|
||||
full() const
|
||||
{
|
||||
std::lock_guard lock(_queue_lock);
|
||||
|
||||
return (_queue.size() == capacity());
|
||||
}
|
||||
|
||||
void
|
||||
block()
|
||||
{
|
||||
std::lock_guard guard(_queue_lock);
|
||||
_block = true;
|
||||
}
|
||||
|
||||
void
|
||||
unblock()
|
||||
{
|
||||
{
|
||||
std::lock_guard guard(_queue_lock);
|
||||
_block = false;
|
||||
}
|
||||
|
||||
_condition_push.notify_all();
|
||||
_condition_pop.notify_all();
|
||||
}
|
||||
|
||||
bool
|
||||
blocking() const
|
||||
{
|
||||
std::lock_guard guard(_queue_lock);
|
||||
|
||||
return _block;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::mutex _queue_lock;
|
||||
|
||||
private:
|
||||
bool _block;
|
||||
std::queue<T> _queue;
|
||||
const std::size_t _max_size;
|
||||
std::condition_variable _condition_push;
|
||||
std::condition_variable _condition_pop;
|
||||
};
|
||||
@@ -1,317 +0,0 @@
|
||||
/*
|
||||
FUSE: Filesystem in Userspace
|
||||
Copyright (C) 2010 Miklos Szeredi <miklos@szeredi.hu>
|
||||
|
||||
This program can be distributed under the terms of the GNU LGPLv2.
|
||||
See the file COPYING.LIB
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "config.h"
|
||||
#include "fuse_i.h"
|
||||
#include "fuse_lowlevel.h"
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
|
||||
{
|
||||
size_t i;
|
||||
size_t size = 0;
|
||||
|
||||
for (i = 0; i < bufv->count; i++) {
|
||||
if (bufv->buf[i].size == SIZE_MAX)
|
||||
size = SIZE_MAX;
|
||||
else
|
||||
size += bufv->buf[i].size;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static size_t min_size(size_t s1, size_t s2)
|
||||
{
|
||||
return s1 < s2 ? s1 : s2;
|
||||
}
|
||||
|
||||
static ssize_t fuse_buf_write(const struct fuse_buf *dst, size_t dst_off,
|
||||
const struct fuse_buf *src, size_t src_off,
|
||||
size_t len)
|
||||
{
|
||||
ssize_t res = 0;
|
||||
size_t copied = 0;
|
||||
|
||||
while (len) {
|
||||
if (dst->flags & FUSE_BUF_FD_SEEK) {
|
||||
res = pwrite(dst->fd, src->mem + src_off, len,
|
||||
dst->pos + dst_off);
|
||||
} else {
|
||||
res = write(dst->fd, src->mem + src_off, len);
|
||||
}
|
||||
if (res == -1) {
|
||||
if (!copied)
|
||||
return -errno;
|
||||
break;
|
||||
}
|
||||
if (res == 0)
|
||||
break;
|
||||
|
||||
copied += res;
|
||||
if (!(dst->flags & FUSE_BUF_FD_RETRY))
|
||||
break;
|
||||
|
||||
src_off += res;
|
||||
dst_off += res;
|
||||
len -= res;
|
||||
}
|
||||
|
||||
return copied;
|
||||
}
|
||||
|
||||
static ssize_t fuse_buf_read(const struct fuse_buf *dst, size_t dst_off,
|
||||
const struct fuse_buf *src, size_t src_off,
|
||||
size_t len)
|
||||
{
|
||||
ssize_t res = 0;
|
||||
size_t copied = 0;
|
||||
|
||||
while (len) {
|
||||
if (src->flags & FUSE_BUF_FD_SEEK) {
|
||||
res = pread(src->fd, dst->mem + dst_off, len,
|
||||
src->pos + src_off);
|
||||
} else {
|
||||
res = read(src->fd, dst->mem + dst_off, len);
|
||||
}
|
||||
if (res == -1) {
|
||||
if (!copied)
|
||||
return -errno;
|
||||
break;
|
||||
}
|
||||
if (res == 0)
|
||||
break;
|
||||
|
||||
copied += res;
|
||||
if (!(src->flags & FUSE_BUF_FD_RETRY))
|
||||
break;
|
||||
|
||||
dst_off += res;
|
||||
src_off += res;
|
||||
len -= res;
|
||||
}
|
||||
|
||||
return copied;
|
||||
}
|
||||
|
||||
static ssize_t fuse_buf_fd_to_fd(const struct fuse_buf *dst, size_t dst_off,
|
||||
const struct fuse_buf *src, size_t src_off,
|
||||
size_t len)
|
||||
{
|
||||
char buf[4096];
|
||||
struct fuse_buf tmp = {
|
||||
.size = sizeof(buf),
|
||||
.flags = 0,
|
||||
};
|
||||
ssize_t res;
|
||||
size_t copied = 0;
|
||||
|
||||
tmp.mem = buf;
|
||||
|
||||
while (len) {
|
||||
size_t this_len = min_size(tmp.size, len);
|
||||
size_t read_len;
|
||||
|
||||
res = fuse_buf_read(&tmp, 0, src, src_off, this_len);
|
||||
if (res < 0) {
|
||||
if (!copied)
|
||||
return res;
|
||||
break;
|
||||
}
|
||||
if (res == 0)
|
||||
break;
|
||||
|
||||
read_len = res;
|
||||
res = fuse_buf_write(dst, dst_off, &tmp, 0, read_len);
|
||||
if (res < 0) {
|
||||
if (!copied)
|
||||
return res;
|
||||
break;
|
||||
}
|
||||
if (res == 0)
|
||||
break;
|
||||
|
||||
copied += res;
|
||||
|
||||
if (res < this_len)
|
||||
break;
|
||||
|
||||
dst_off += res;
|
||||
src_off += res;
|
||||
len -= res;
|
||||
}
|
||||
|
||||
return copied;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SPLICE
|
||||
static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
|
||||
const struct fuse_buf *src, size_t src_off,
|
||||
size_t len, enum fuse_buf_copy_flags flags)
|
||||
{
|
||||
int splice_flags = 0;
|
||||
off_t *srcpos = NULL;
|
||||
off_t *dstpos = NULL;
|
||||
off_t srcpos_val;
|
||||
off_t dstpos_val;
|
||||
ssize_t res;
|
||||
size_t copied = 0;
|
||||
|
||||
if (flags & FUSE_BUF_SPLICE_MOVE)
|
||||
splice_flags |= SPLICE_F_MOVE;
|
||||
if (flags & FUSE_BUF_SPLICE_NONBLOCK)
|
||||
splice_flags |= SPLICE_F_NONBLOCK;
|
||||
|
||||
if (src->flags & FUSE_BUF_FD_SEEK) {
|
||||
srcpos_val = src->pos + src_off;
|
||||
srcpos = &srcpos_val;
|
||||
}
|
||||
if (dst->flags & FUSE_BUF_FD_SEEK) {
|
||||
dstpos_val = dst->pos + dst_off;
|
||||
dstpos = &dstpos_val;
|
||||
}
|
||||
|
||||
while (len) {
|
||||
res = splice(src->fd, srcpos, dst->fd, dstpos, len, splice_flags);
|
||||
if (res == -1) {
|
||||
if (copied)
|
||||
break;
|
||||
|
||||
if (errno != EINVAL || (flags & FUSE_BUF_FORCE_SPLICE))
|
||||
return -errno;
|
||||
|
||||
/* Maybe splice is not supported for this combination */
|
||||
return fuse_buf_fd_to_fd(dst, dst_off, src, src_off,
|
||||
len);
|
||||
}
|
||||
if (res == 0)
|
||||
break;
|
||||
|
||||
copied += res;
|
||||
if (!(src->flags & FUSE_BUF_FD_RETRY) &&
|
||||
!(dst->flags & FUSE_BUF_FD_RETRY)) {
|
||||
break;
|
||||
}
|
||||
|
||||
len -= res;
|
||||
}
|
||||
|
||||
return copied;
|
||||
}
|
||||
#else
|
||||
static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
|
||||
const struct fuse_buf *src, size_t src_off,
|
||||
size_t len, enum fuse_buf_copy_flags flags)
|
||||
{
|
||||
(void) flags;
|
||||
|
||||
return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static ssize_t fuse_buf_copy_one(const struct fuse_buf *dst, size_t dst_off,
|
||||
const struct fuse_buf *src, size_t src_off,
|
||||
size_t len, enum fuse_buf_copy_flags flags)
|
||||
{
|
||||
int src_is_fd = src->flags & FUSE_BUF_IS_FD;
|
||||
int dst_is_fd = dst->flags & FUSE_BUF_IS_FD;
|
||||
|
||||
if (!src_is_fd && !dst_is_fd) {
|
||||
char *dstmem = dst->mem + dst_off;
|
||||
char *srcmem = src->mem + src_off;
|
||||
|
||||
if (dstmem != srcmem) {
|
||||
if (dstmem + len <= srcmem || srcmem + len <= dstmem)
|
||||
memcpy(dstmem, srcmem, len);
|
||||
else
|
||||
memmove(dstmem, srcmem, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
} else if (!src_is_fd) {
|
||||
return fuse_buf_write(dst, dst_off, src, src_off, len);
|
||||
} else if (!dst_is_fd) {
|
||||
return fuse_buf_read(dst, dst_off, src, src_off, len);
|
||||
} else if (flags & FUSE_BUF_NO_SPLICE) {
|
||||
return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
|
||||
} else {
|
||||
return fuse_buf_splice(dst, dst_off, src, src_off, len, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct fuse_buf *fuse_bufvec_current(struct fuse_bufvec *bufv)
|
||||
{
|
||||
if (bufv->idx < bufv->count)
|
||||
return &bufv->buf[bufv->idx];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int fuse_bufvec_advance(struct fuse_bufvec *bufv, size_t len)
|
||||
{
|
||||
const struct fuse_buf *buf = fuse_bufvec_current(bufv);
|
||||
|
||||
bufv->off += len;
|
||||
assert(bufv->off <= buf->size);
|
||||
if (bufv->off == buf->size) {
|
||||
assert(bufv->idx < bufv->count);
|
||||
bufv->idx++;
|
||||
if (bufv->idx == bufv->count)
|
||||
return 0;
|
||||
bufv->off = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssize_t fuse_buf_copy(struct fuse_bufvec *dstv, struct fuse_bufvec *srcv,
|
||||
enum fuse_buf_copy_flags flags)
|
||||
{
|
||||
size_t copied = 0;
|
||||
|
||||
if (dstv == srcv)
|
||||
return fuse_buf_size(dstv);
|
||||
|
||||
for (;;) {
|
||||
const struct fuse_buf *src = fuse_bufvec_current(srcv);
|
||||
const struct fuse_buf *dst = fuse_bufvec_current(dstv);
|
||||
size_t src_len;
|
||||
size_t dst_len;
|
||||
size_t len;
|
||||
ssize_t res;
|
||||
|
||||
if (src == NULL || dst == NULL)
|
||||
break;
|
||||
|
||||
src_len = src->size - srcv->off;
|
||||
dst_len = dst->size - dstv->off;
|
||||
len = min_size(src_len, dst_len);
|
||||
|
||||
res = fuse_buf_copy_one(dst, dstv->off, src, srcv->off, len, flags);
|
||||
if (res < 0) {
|
||||
if (!copied)
|
||||
return res;
|
||||
break;
|
||||
}
|
||||
copied += res;
|
||||
|
||||
if (!fuse_bufvec_advance(srcv, res) ||
|
||||
!fuse_bufvec_advance(dstv, res))
|
||||
break;
|
||||
|
||||
if (res < len)
|
||||
break;
|
||||
}
|
||||
|
||||
return copied;
|
||||
}
|
||||
-1278
File diff suppressed because it is too large
Load Diff
@@ -1,380 +0,0 @@
|
||||
/*
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kvec.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define ROUND_UP(N,S) ((((N) + (S) - 1) / (S)) * (S))
|
||||
|
||||
typedef kvec_t(void*) slab_kvec_t;
|
||||
|
||||
typedef struct mem_stack_t mem_stack_t;
|
||||
struct mem_stack_t
|
||||
{
|
||||
mem_stack_t *next;
|
||||
};
|
||||
|
||||
typedef struct fmp_t fmp_t;
|
||||
struct fmp_t
|
||||
{
|
||||
mem_stack_t *objs;
|
||||
slab_kvec_t slabs;
|
||||
uint64_t avail_objs;
|
||||
uint64_t obj_size;
|
||||
uint64_t page_size;
|
||||
uint64_t slab_size;
|
||||
};
|
||||
|
||||
static
|
||||
inline
|
||||
uint64_t
|
||||
fmp_page_size()
|
||||
{
|
||||
return sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
fmp_init(fmp_t *fmp_,
|
||||
const uint64_t obj_size_,
|
||||
const uint64_t page_multiple_)
|
||||
{
|
||||
kv_init(fmp_->slabs);
|
||||
fmp_->objs = NULL;
|
||||
fmp_->avail_objs = 0;
|
||||
fmp_->obj_size = ROUND_UP(obj_size_,sizeof(void*));
|
||||
fmp_->page_size = fmp_page_size();
|
||||
fmp_->slab_size = (fmp_->page_size * page_multiple_);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
uint64_t
|
||||
fmp_slab_count(fmp_t *fmp_)
|
||||
{
|
||||
return kv_size(fmp_->slabs);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void*
|
||||
fmp_slab_alloc_posix_memalign(fmp_t *fmp_)
|
||||
{
|
||||
int rv;
|
||||
void *mem;
|
||||
const size_t alignment = fmp_->page_size;
|
||||
const size_t size = fmp_->slab_size;
|
||||
|
||||
rv = posix_memalign(&mem,alignment,size);
|
||||
if(rv != 0)
|
||||
return NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void*
|
||||
fmp_slab_alloc_mmap(fmp_t *fmp_)
|
||||
{
|
||||
void *mem;
|
||||
void *address = NULL;
|
||||
const size_t length = fmp_->slab_size;
|
||||
const int protect = PROT_READ|PROT_WRITE;
|
||||
const int flags = MAP_PRIVATE|MAP_ANONYMOUS;
|
||||
const int filedes = -1;
|
||||
const off_t offset = 0;
|
||||
|
||||
mem = mmap(address,length,protect,flags,filedes,offset);
|
||||
if(mem == MAP_FAILED)
|
||||
return NULL;
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
fmp_slab_free_posix_memalign(fmp_t* fmp_,
|
||||
void *mem_)
|
||||
{
|
||||
(void)fmp_;
|
||||
free(mem_);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
fmp_slab_free_mmap(fmp_t* fmp_,
|
||||
void *mem_)
|
||||
{
|
||||
void *addr = mem_;
|
||||
size_t length = fmp_->slab_size;
|
||||
|
||||
(void)munmap(addr,length);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
int
|
||||
fmp_slab_alloc(fmp_t *fmp_)
|
||||
{
|
||||
char *i;
|
||||
void *mem;
|
||||
|
||||
mem = fmp_slab_alloc_mmap(fmp_);
|
||||
if(mem == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
kv_push(void*,fmp_->slabs,mem);
|
||||
|
||||
i = ((char*)mem + fmp_->slab_size - fmp_->obj_size);
|
||||
while(i >= (char*)mem)
|
||||
{
|
||||
mem_stack_t *obj = (mem_stack_t*)i;
|
||||
|
||||
obj->next = fmp_->objs;
|
||||
fmp_->objs = obj;
|
||||
fmp_->avail_objs++;
|
||||
|
||||
i -= fmp_->obj_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void*
|
||||
fmp_alloc(fmp_t *fmp_)
|
||||
{
|
||||
void *rv;
|
||||
|
||||
if(fmp_->objs == NULL)
|
||||
fmp_slab_alloc(fmp_);
|
||||
if(fmp_->objs == NULL)
|
||||
return NULL;
|
||||
|
||||
rv = fmp_->objs;
|
||||
|
||||
fmp_->objs = fmp_->objs->next;
|
||||
fmp_->avail_objs--;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void*
|
||||
fmp_calloc(fmp_t *fmp_)
|
||||
{
|
||||
void *obj;
|
||||
|
||||
obj = fmp_alloc(fmp_);
|
||||
if(obj == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(obj,0,fmp_->obj_size);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
fmp_free(fmp_t *fmp_,
|
||||
void *obj_)
|
||||
{
|
||||
mem_stack_t *obj = (mem_stack_t*)obj_;
|
||||
|
||||
obj->next = fmp_->objs;
|
||||
fmp_->objs = obj;
|
||||
fmp_->avail_objs++;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
fmp_clear(fmp_t *fmp_)
|
||||
{
|
||||
while(kv_size(fmp_->slabs))
|
||||
{
|
||||
void *slab = kv_pop(fmp_->slabs);
|
||||
|
||||
fmp_slab_free_mmap(fmp_,slab);
|
||||
}
|
||||
|
||||
fmp_->objs = NULL;
|
||||
fmp_->avail_objs = 0;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
fmp_destroy(fmp_t *fmp_)
|
||||
{
|
||||
fmp_clear(fmp_);
|
||||
kv_destroy(fmp_->slabs);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
uint64_t
|
||||
fmp_avail_objs(fmp_t *fmp_)
|
||||
{
|
||||
return fmp_->avail_objs;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
uint64_t
|
||||
fmp_objs_per_slab(fmp_t *fmp_)
|
||||
{
|
||||
return (fmp_->slab_size / fmp_->obj_size);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
uint64_t
|
||||
fmp_objs_in_slab(fmp_t *fmp_,
|
||||
void *slab_)
|
||||
{
|
||||
char *slab;
|
||||
uint64_t objs_per_slab;
|
||||
uint64_t objs_in_slab;
|
||||
|
||||
slab = (char*)slab_;
|
||||
objs_in_slab = 0;
|
||||
objs_per_slab = fmp_objs_per_slab(fmp_);
|
||||
for(mem_stack_t *stack = fmp_->objs; stack != NULL; stack = stack->next)
|
||||
{
|
||||
char *obj = (char*)stack;
|
||||
if((obj >= slab) && (obj < (slab + fmp_->slab_size)))
|
||||
objs_in_slab++;
|
||||
if(objs_in_slab >= objs_per_slab)
|
||||
break;
|
||||
}
|
||||
|
||||
return objs_in_slab;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
fmp_remove_objs_in_slab(fmp_t *fmp_,
|
||||
void *slab_)
|
||||
{
|
||||
char *slab;
|
||||
uint64_t objs_per_slab;
|
||||
uint64_t objs_in_slab;
|
||||
mem_stack_t **p;
|
||||
|
||||
p = &fmp_->objs;
|
||||
slab = (char*)slab_;
|
||||
objs_in_slab = 0;
|
||||
objs_per_slab = fmp_objs_per_slab(fmp_);
|
||||
while((*p) != NULL)
|
||||
{
|
||||
char *obj = (char*)*p;
|
||||
|
||||
if((obj >= slab) && (obj < (slab + fmp_->slab_size)))
|
||||
{
|
||||
objs_in_slab++;
|
||||
*p = (*p)->next;
|
||||
fmp_->avail_objs--;
|
||||
|
||||
if(objs_in_slab >= objs_per_slab)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
p = &(*p)->next;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
int
|
||||
fmp_gc_slab(fmp_t *fmp_,
|
||||
uint64_t slab_idx_)
|
||||
{
|
||||
char *slab;
|
||||
uint64_t objs_in_slab;
|
||||
uint64_t objs_per_slab;
|
||||
|
||||
slab_idx_ = (slab_idx_ % kv_size(fmp_->slabs));
|
||||
|
||||
slab = kv_A(fmp_->slabs,slab_idx_);
|
||||
|
||||
objs_per_slab = fmp_objs_per_slab(fmp_);
|
||||
objs_in_slab = fmp_objs_in_slab(fmp_,slab);
|
||||
if(objs_in_slab != objs_per_slab)
|
||||
return 0;
|
||||
|
||||
fmp_remove_objs_in_slab(fmp_,slab);
|
||||
kv_delete(fmp_->slabs,slab_idx_);
|
||||
fmp_slab_free_mmap(fmp_,slab);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
inline
|
||||
int
|
||||
fmp_gc(fmp_t *fmp_)
|
||||
{
|
||||
uint64_t slab_idx;
|
||||
|
||||
slab_idx = rand();
|
||||
|
||||
return fmp_gc_slab(fmp_,slab_idx);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
double
|
||||
fmp_slab_usage_ratio(fmp_t *fmp_)
|
||||
{
|
||||
double avail_objs;
|
||||
double objs_per_slab;
|
||||
double nums_of_slabs;
|
||||
|
||||
avail_objs = fmp_->avail_objs;
|
||||
objs_per_slab = fmp_objs_per_slab(fmp_);
|
||||
nums_of_slabs = kv_size(fmp_->slabs);
|
||||
|
||||
return (avail_objs / (objs_per_slab * nums_of_slabs));
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
uint64_t
|
||||
fmp_total_allocated_memory(fmp_t *fmp_)
|
||||
{
|
||||
return (fmp_->slab_size * kv_size(fmp_->slabs));
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
// Formatting library for C++ - dynamic format arguments
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_ARGS_H_
|
||||
#define FMT_ARGS_H_
|
||||
|
||||
#include <functional> // std::reference_wrapper
|
||||
#include <memory> // std::unique_ptr
|
||||
#include <vector>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T> struct is_reference_wrapper : std::false_type {};
|
||||
template <typename T>
|
||||
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
|
||||
|
||||
template <typename T> const T& unwrap(const T& v) { return v; }
|
||||
template <typename T> const T& unwrap(const std::reference_wrapper<T>& v) {
|
||||
return static_cast<const T&>(v);
|
||||
}
|
||||
|
||||
class dynamic_arg_list {
|
||||
// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for
|
||||
// templates it doesn't complain about inability to deduce single translation
|
||||
// unit for placing vtable. So storage_node_base is made a fake template.
|
||||
template <typename = void> struct node {
|
||||
virtual ~node() = default;
|
||||
std::unique_ptr<node<>> next;
|
||||
};
|
||||
|
||||
template <typename T> struct typed_node : node<> {
|
||||
T value;
|
||||
|
||||
template <typename Arg>
|
||||
FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR typed_node(const basic_string_view<Char>& arg)
|
||||
: value(arg.data(), arg.size()) {}
|
||||
};
|
||||
|
||||
std::unique_ptr<node<>> head_;
|
||||
|
||||
public:
|
||||
template <typename T, typename Arg> const T& push(const Arg& arg) {
|
||||
auto new_node = std::unique_ptr<typed_node<T>>(new typed_node<T>(arg));
|
||||
auto& value = new_node->value;
|
||||
new_node->next = std::move(head_);
|
||||
head_ = std::move(new_node);
|
||||
return value;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
\rst
|
||||
A dynamic version of `fmt::format_arg_store`.
|
||||
It's equipped with a storage to potentially temporary objects which lifetimes
|
||||
could be shorter than the format arguments object.
|
||||
|
||||
It can be implicitly converted into `~fmt::basic_format_args` for passing
|
||||
into type-erased formatting functions such as `~fmt::vformat`.
|
||||
\endrst
|
||||
*/
|
||||
template <typename Context>
|
||||
class dynamic_format_arg_store
|
||||
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
|
||||
// Workaround a GCC template argument substitution bug.
|
||||
: public basic_format_args<Context>
|
||||
#endif
|
||||
{
|
||||
private:
|
||||
using char_type = typename Context::char_type;
|
||||
|
||||
template <typename T> struct need_copy {
|
||||
static constexpr detail::type mapped_type =
|
||||
detail::mapped_type_constant<T, Context>::value;
|
||||
|
||||
enum {
|
||||
value = !(detail::is_reference_wrapper<T>::value ||
|
||||
std::is_same<T, basic_string_view<char_type>>::value ||
|
||||
std::is_same<T, detail::std_string_view<char_type>>::value ||
|
||||
(mapped_type != detail::type::cstring_type &&
|
||||
mapped_type != detail::type::string_type &&
|
||||
mapped_type != detail::type::custom_type))
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using stored_type = conditional_t<
|
||||
std::is_convertible<T, std::basic_string<char_type>>::value &&
|
||||
!detail::is_reference_wrapper<T>::value,
|
||||
std::basic_string<char_type>, T>;
|
||||
|
||||
// Storage of basic_format_arg must be contiguous.
|
||||
std::vector<basic_format_arg<Context>> data_;
|
||||
std::vector<detail::named_arg_info<char_type>> named_info_;
|
||||
|
||||
// Storage of arguments not fitting into basic_format_arg must grow
|
||||
// without relocation because items in data_ refer to it.
|
||||
detail::dynamic_arg_list dynamic_args_;
|
||||
|
||||
friend class basic_format_args<Context>;
|
||||
|
||||
unsigned long long get_types() const {
|
||||
return detail::is_unpacked_bit | data_.size() |
|
||||
(named_info_.empty()
|
||||
? 0ULL
|
||||
: static_cast<unsigned long long>(detail::has_named_args_bit));
|
||||
}
|
||||
|
||||
const basic_format_arg<Context>* data() const {
|
||||
return named_info_.empty() ? data_.data() : data_.data() + 1;
|
||||
}
|
||||
|
||||
template <typename T> void emplace_arg(const T& arg) {
|
||||
data_.emplace_back(detail::make_arg<Context>(arg));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void emplace_arg(const detail::named_arg<char_type, T>& arg) {
|
||||
if (named_info_.empty()) {
|
||||
constexpr const detail::named_arg_info<char_type>* zero_ptr{nullptr};
|
||||
data_.insert(data_.begin(), {zero_ptr, 0});
|
||||
}
|
||||
data_.emplace_back(detail::make_arg<Context>(detail::unwrap(arg.value)));
|
||||
auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
|
||||
data->pop_back();
|
||||
};
|
||||
std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
|
||||
guard{&data_, pop_one};
|
||||
named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});
|
||||
data_[0].value_.named_args = {named_info_.data(), named_info_.size()};
|
||||
guard.release();
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr dynamic_format_arg_store() = default;
|
||||
|
||||
/**
|
||||
\rst
|
||||
Adds an argument into the dynamic store for later passing to a formatting
|
||||
function.
|
||||
|
||||
Note that custom types and string types (but not string views) are copied
|
||||
into the store dynamically allocating memory if necessary.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||
store.push_back(42);
|
||||
store.push_back("abc");
|
||||
store.push_back(1.5f);
|
||||
std::string result = fmt::vformat("{} and {} and {}", store);
|
||||
\endrst
|
||||
*/
|
||||
template <typename T> void push_back(const T& arg) {
|
||||
if (detail::const_check(need_copy<T>::value))
|
||||
emplace_arg(dynamic_args_.push<stored_type<T>>(arg));
|
||||
else
|
||||
emplace_arg(detail::unwrap(arg));
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Adds a reference to the argument into the dynamic store for later passing to
|
||||
a formatting function.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||
char band[] = "Rolling Stones";
|
||||
store.push_back(std::cref(band));
|
||||
band[9] = 'c'; // Changing str affects the output.
|
||||
std::string result = fmt::vformat("{}", store);
|
||||
// result == "Rolling Scones"
|
||||
\endrst
|
||||
*/
|
||||
template <typename T> void push_back(std::reference_wrapper<T> arg) {
|
||||
static_assert(
|
||||
need_copy<T>::value,
|
||||
"objects of built-in types and string views are always copied");
|
||||
emplace_arg(arg.get());
|
||||
}
|
||||
|
||||
/**
|
||||
Adds named argument into the dynamic store for later passing to a formatting
|
||||
function. ``std::reference_wrapper`` is supported to avoid copying of the
|
||||
argument. The name is always copied into the store.
|
||||
*/
|
||||
template <typename T>
|
||||
void push_back(const detail::named_arg<char_type, T>& arg) {
|
||||
const char_type* arg_name =
|
||||
dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();
|
||||
if (detail::const_check(need_copy<T>::value)) {
|
||||
emplace_arg(
|
||||
fmt::arg(arg_name, dynamic_args_.push<stored_type<T>>(arg.value)));
|
||||
} else {
|
||||
emplace_arg(fmt::arg(arg_name, arg.value));
|
||||
}
|
||||
}
|
||||
|
||||
/** Erase all elements from the store */
|
||||
void clear() {
|
||||
data_.clear();
|
||||
named_info_.clear();
|
||||
dynamic_args_ = detail::dynamic_arg_list();
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Reserves space to store at least *new_cap* arguments including
|
||||
*new_cap_named* named arguments.
|
||||
\endrst
|
||||
*/
|
||||
void reserve(size_t new_cap, size_t new_cap_named) {
|
||||
FMT_ASSERT(new_cap >= new_cap_named,
|
||||
"Set of arguments includes set of named arguments");
|
||||
data_.reserve(new_cap);
|
||||
named_info_.reserve(new_cap_named);
|
||||
}
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_ARGS_H_
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user