You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
16 KiB
HTML

<!doctype html>
<html lang=en>
<head id="head">
<meta charset=utf-8>
<title id=title >the codeartist — programmer and engineer based in BerlinRunning writefreely 0.7 on Arm</title>
<meta name=description content="The personal page and weblog of Norman Köhring">
<meta name=author content="Norman Köhring">
<meta name=DC.title content="the codeartist — programmer and engineer based in Berlin">
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@koehr_in">
<meta name="twitter:author" content="@koehr_in">
<meta name=twitter:description content="The personal page and weblog of the codeartist Norman Köhring">
<meta name="twitter:title" content="Running writefreely 0.7 on Arm // the codeartist">
<meta name="og:title" content="Running writefreely 0.7 on Arm // the codeartist">
<meta property="og:type" content="website">
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"/>
<meta name=ICBM content="52.4595, 13.5335">
<meta name=geo.position content="52.4595; 13.5335">
<meta name=geo.region content=DE-BE>
<meta name=geo.placename content=Berlin>
<link rel=me href=https://koehr.in>
<link rel=me href=https://k0r.in>
<link rel=me href=https://koehr.ing>
<link rel=me href=@Koehr@mstdn.io>
<link rel=me href=https://sr.ht/~koehr/>
<link rel=me href=https://git.k0r.in>
<link rel=me href=https://threads.net/@coffee_n_code>
<link rel=me href=https://instagram.com/@coffee_n_code>
<link rel=me href=https://ko-fi.com/koehr>
<link rel=me href=https://reddit.com/user/koehr>
<link rel=icon href=/favicon.png type=image/x-icon>
<link rel=stylesheet href=/style.css>
</head>
<body>
<main id="main">
<header>
<h1 >Running writefreely 0.7 on Arm</h1>
<em >What was necessary to make cross-compiling work for newer WriteFreely versions with SQLite support.</em>
<br/>
Last updated: <time datetime="Thu, 10 Jan 2019 00:00:00 +0000" >January 10, 2019</time>
</header>
<div ><hr><p>This is a follow-up on <a href="https://write.as/buttpicker/the-expected-tutorial-how-to-install-writefreely-on-a-raspberry-pi-3-in-10">The expected tutorial: How to install WriteFreely on a Raspberry pi 3 in 10 steps</a>.</p><hr><p>I did it! I finally got WriteFreely to run on my Arm server (check out <a href="https://www.scaleway.com/baremetal-cloud-servers/">Scaleways baremetal cloud servers</a>).</p><p>It wasn't so easy because with 512MB of RAM I couldn't simply download and build the source on my webserver. Only solution: Cross compiling. Easy especially in Go, right?</p><p>If you read the article linked in the beginning you know how easy it could be. But as the article already mentions in an update, since Version 0.6 it is not working anymore because of the new SQLite dependency (newest version as of writing this article is 0.7).</p><p>With a bit of research I figured out what to do to make it work anyhow. There are two solutions. A quick (and slightly dirty) one for people who don't need SQLite support and a correct solution that needs a tad more effort.</p><h2>Quick solution: remove SQLite support</h2><p>SQLite support makes problems with the cross compiling because it needs some C code to be compiled. Before figuring out how to make this working with the otherwise super easy Go cross compiling, removing the feature might be a viable quick fix. For this, simply change or remove all occurences of sqlite in the Makefile:</p><pre><code class="diff"><span class="variable builtin">diff --git a/Makefile b/Makefile</span>
index <span class="constant">5950dfd</span>..<span class="constant">032fd0c</span> 100644
<span class="keyword">--- a/Makefile</span>
<span class="string">+++ b/Makefile</span>
<span class="attribute">@@ -13,25 +13,25 @@ IMAGE_NAME=writeas/writefreely</span>
all : build
build: assets deps
<span class="keyword">- cd cmd/writefreely; $(GOBUILD) -v -tags='sqlite'</span>
<span class="string">+ cd cmd/writefreely; $(GOBUILD) -v</span>
build-linux: deps
@hash xgo &gt; /dev/null 2&gt;&1; if [ $$? -ne 0 ]; then \
$(GOGET) -u github.com/karalabe/xgo; \
fi
<span class="keyword">- xgo --targets=linux/amd64, -dest build/ $(LDFLAGS) -tags='sqlite' -out writefreely ./cmd/writefreely</span>
<span class="string">+ xgo --targets=linux/amd64, -dest build/ $(LDFLAGS) -out writefreely ./cmd/writefreely</span>
build-windows: deps
@hash xgo &gt; /dev/null 2&gt;&1; if [ $$? -ne 0 ]; then \
$(GOGET) -u github.com/karalabe/xgo; \
fi
<span class="keyword">- xgo --targets=windows/amd64, -dest build/ $(LDFLAGS) -tags='sqlite' -out writefreely ./cmd/writefreely</span>
<span class="string">+ xgo --targets=windows/amd64, -dest build/ $(LDFLAGS) -out writefreely ./cmd/writefreely</span>
build-darwin: deps
@hash xgo &gt; /dev/null 2&gt;&1; if [ $$? -ne 0 ]; then \
$(GOGET) -u github.com/karalabe/xgo; \
fi
<span class="keyword">- xgo --targets=darwin/amd64, -dest build/ $(LDFLAGS) -tags='sqlite' -out writefreely ./cmd/writefreely</span>
<span class="string">+ xgo --targets=darwin/amd64, -dest build/ $(LDFLAGS) -out writefreely ./cmd/writefreely</span>
build-docker :
$(DOCKERCMD) build -t $(IMAGE_NAME):latest -t $(IMAGE_NAME):$(GITREV) .
<span class="attribute">@@ -40,11 +40,11 @@ test:</span>
$(GOTEST) -v ./...
run: dev-assets
<span class="keyword">- $(GOINSTALL) -tags='sqlite' ./...</span>
<span class="string">+ $(GOINSTALL) ./...</span>
$(BINARY_NAME) --debug
deps :
<span class="keyword">- $(GOGET) -tags='sqlite' -v ./...</span>
<span class="string">+ $(GOGET) -v ./...</span>
install : build
cmd/writefreely/$(BINARY_NAME) --gen-keys
<span class="attribute">@@ -77,10 +77,10 @@ ui : force_look</span>
cd less/; $(MAKE) $(MFLAGS)
assets : generate
<span class="keyword">- go-bindata -pkg writefreely -ignore=\\.gitignore schema.sql sqlite.sql</span>
<span class="string">+ go-bindata -pkg writefreely -ignore=\\.gitignore schema.sql</span>
dev-assets : generate
<span class="keyword">- go-bindata -pkg writefreely -ignore=\\.gitignore -debug schema.sql sqlite.sql</span>
<span class="string">+ go-bindata -pkg writefreely -ignore=\\.gitignore -debug schema.sql</span>
generate :
@hash go-bindata &gt; /dev/null 2&gt;&1; if [ $$? -ne 0 ]; then \
</code></pre>
<p>Now just go on as described in the original article and it should work:</p><pre><code class="bash"><span class="constant">env</span> <span class="constant">GOARCH=arm</span> <span class="constant">GOARM=7</span> <span class="constant">go</span> <span class="constant">get</span> <span class="constant">github.com/writeas/writefreely/cmd/writefreely</span>
</code></pre>
<h2>The correct solution</h2><p>To get WriteFreely cross compiled with SQLite support, a C cross compiler is needed. Void Linux, the distribution of my choice, offers a bunch of packages for all kind of architectures. They are called for example <code>cross-armv7l-linux-gnueabihf</code> (ARMv7), <code>cross-arm-linux-gnueabihf</code> (ARMv6) or <code>cross-arm-linux-gnueabi</code> (ARMv5). I found similar packages in AUR (for Arch Linux).</p><p>As soon as the corresponding cross compiler is found, go can be told to use it:</p><pre><code class="sh">env CGO_ENABLED=1 CC=armv7l-linux-gnueabihf-gcc GOOS=linux GOARCH=arm GOARM=7 make
</code></pre>
<p>The environment variables used are:</p><p><code>CGO_ENABLED=1</code> should be obvious. It tells Go to enable the C compilation.</p><p><code>CC=armv...</code> tells Go which C compiler to use. Usually this would be just <code>gcc</code>. In this case it is the name of the cross compiler. Please set it to the compiler for your target platform. I'm going to use ARMv7 examples here. It is the name of a directory found in <code>/usr/</code>, eg <code>/usr/armv7l-linux-gnueabihf</code>. Initially that failed for me though because it expected to find a file <code>./lib/libc.so</code> which ended up in another subfolder <code>/usr/</code>. So I cheated a bit and did:</p><pre><code class="bash"><span class="comment"># You might not need to do this on your platform.</span>
<span class="constant">sudo</span> <span class="constant">ln</span> <span class="constant">-s</span> <span class="constant">/usr/armv7l-linux-gnueabihf/usr/lib</span> <span class="constant">/usr/armv7l-linux-gnueabihf/lib</span>
</code></pre>
<p><code>GOOS=linux GOARCH=arm</code> are the same as in the original article.</p><p><code>GOARM=7</code> is optional, even on an actual ARMv7. It enables some register optimizations that only work on ARMv7.</p><p>And finally <code>make</code> is called. This is short for <code>make all</code> which should do everything necessary.</p><p>Not all files are necessary to be transferred to the Server or RaspberryPi. What I did after some experimentation was:</p><pre><code class="bash"><span class="comment"># after building everything create a package</span>
<span class="constant">mkdir</span> <span class="constant">writefreely-arm</span>
<span class="constant">cp</span> <span class="constant">-r</span> <span class="constant">templates</span> <span class="constant">pages</span> <span class="constant">static</span> <span class="constant">writefreely-arm</span>
<span class="constant">mkdir</span> <span class="constant">writefreely-arm/keys</span> <span class="comment"># fun fact: key generation crashes without this</span>
<span class="constant">cp</span> <span class="constant">cmd/writefreely/writefreely</span> <span class="constant">writefreely-arm</span>
<span class="constant">tar</span> <span class="constant">cvzf</span> <span class="constant">writefreely-arm.tgz</span> <span class="constant">writefreely-arm</span>
<span class="comment"># copy that package to the server</span>
<span class="constant">scp</span> <span class="constant">writefreely-arm.tgz</span> <span class="constant">you@yourserver.tld:~</span>
<span class="comment"># ssh into the server and unpack everything</span>
<span class="constant">ssh</span> <span class="constant">you@yourserver.tld</span>
<span class="constant">tar</span> <span class="constant">czf</span> <span class="constant">writefreely-arm.tgz</span>
<span class="constant">cd</span> <span class="constant">writefreely-arm</span>
<span class="comment"># generate config, keys and database</span>
<span class="constant">./writefreely</span> <span class="constant">-config</span> <span class="comment"># starts interactive configuration</span>
<span class="comment"># This should lead you through all necessary steps</span>
<span class="comment"># like filling the config, generating keys, generating database tables</span>
<span class="comment"># run `./writefreely --help` to learn more if something is missing.</span>
</code></pre>
<p>Now <code>./writefreely</code> should run an empty blog at the specified port.</p><p>Have fun!</p></div>
</main>
<div id="spacer"></div>
<header id="header">
<a href="/">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 832.4 143.1">
<path id="header-underscore"
d="M832.4 131.1q0 5.5-3.1 8.6-3 3.4-8.2 3.3h-75.5q-5.2 0-8.2-3.3-1.7-1.6-2.4-3.8-.7-2.3-.7-4.8 0-5.5 3.1-8.7 1.6-1.7 3.7-2.4 2.2-.8 4.5-.8h75.5q5.2 0 8.2 3.2 3 3.1 3 8.7z" />
<path id="header-bracket"
d="M731.9 81.4q0 6.7-6.5 10.7l-1 .6-74.3 39.2q-2.5 1.3-5.2 1.2-4.8 0-8.1-3.8-3.2-3.6-3.2-8.4 0-3.3 1.7-6 1.8-2.9 4.6-4.4l55.3-29.1-55.3-29q-2.8-1.6-4.6-4.3-1.7-2.7-1.7-6.2 0-4.7 3.2-8.4 3.3-4 8-3.7 2.7 0 5.3 1.2l74.4 39.2q3.3 1.7 5.3 4.7 2 2.8 2 6.5z" />
<path id="header-r"
d="M588.7 66.5q0 5-3.5 8.5-3.5 3.4-8.1 3.5-4.4 0-8.3-4.3-10-10.7-20.9-10.6-2.2 0-4.3.3-2.1.3-4 1-1.8.6-3.7 1.6-1.7 1-3.4 2.3-1.7 1.3-3.3 2.9-7.8 8.2-7.6 19.7V131q0 5.5-3.1 8.6-3 3.4-8.3 3.3l-2.2-.2q-1-.1-2.2-.5-1-.3-2-1-1-.6-1.8-1.6-1.7-1.6-2.4-3.8-.7-2.3-.7-4.8V51.6q0-5.4 3-8.6 3-3.4 8.3-3.3 2 0 3.7.6 1.8.6 3.3 1.8 1.4 1 2.2 2.7 1 1.5 1.6 3.3 11.8-8.4 27-8.4 10.6 0 21 5 11.3 5.4 17.2 14.5 2.5 3.7 2.5 7.3z" />
<path id="header-h"
d="M483.9 131.1q0 5.5-3.1 8.6-3 3.4-8.3 3.3-5.2 0-8.2-3.3-3.2-3.1-3.1-8.6V84.8q0-4.6-1.5-8.2-1.4-3.5-4.4-6.9-2.1-2-4.3-3.4-2.2-1.4-4.7-2-2.4-.7-5.3-.7-4.3 0-7.8 1.5-3.3 1.5-6.4 4.6-5.9 6.3-5.8 15v46.4q0 5.5-3 8.6-3.1 3.4-8.4 3.3l-2.2-.2q-1-.1-2.2-.5-1-.3-2-1-1-.6-1.8-1.6-1.7-1.6-2.4-3.8-.7-2.3-.7-4.8V11.9q0-5.5 3-8.6 3-3.4 8.3-3.3 5.2 0 8.2 3.3 3.2 3.1 3.2 8.6v33q1.5-1 3-1.6l3.2-1.2 3.4-1q1.6-.5 3.3-.8l3.5-.4 3.6-.2q4.4 0 8.5 1 4.1.7 7.9 2.4 3.8 1.6 7.3 4.1 3.5 2.5 6.6 5.8Q484 66 484 84.8z" />
<path id="header-e"
d="M387.5 111.1q0 1.2-.3 2.3-.1 1-.5 2l-.9 2q-6.6 12-19.4 19-12 6.6-25.4 6.6-20.8 0-35.8-14.6-15.9-15-15.9-37 0-22.1 15.9-37.1 15-14.6 35.8-14.6 3.9 0 7.8.7 4 .7 8 2.2 9.2 3.1 18.2 10 6 4.6 9.1 9.3 3.3 4.7 3.3 10 0 1.3-.3 2.5-.2 1.3-.7 2.4-1.5 3.4-5 5.3l-56.9 32.2q7.2 4.9 16.5 4.9 7.2 0 12.6-2.5 5.5-2.5 9.7-7.4l.7-1 .8-1 .9-1.3 1-1.5q3.3-4.2 7.4-5.1l1.8-.2q4.4 0 8 3.4 3.6 3.5 3.6 8.5zm-29.9-42.7q-7.2-4.8-16.6-4.8-6 0-11 2-4.9 1.8-9.3 6-4.5 4-6.7 9-2 4.8-2 10.8l.1 2.9z" />
<path id="header-o"
d="M286.8 91.4q0 4.2-.6 8.3-.6 4-1.8 7.7-1.1 3.8-2.9 7.4-1.7 3.5-4 6.9-2.4 3.3-5.2 6.1Q258 143 237.7 143T203 128q-14.3-15.2-14.3-36.6 0-21.5 14.3-36.6 14.4-15 34.7-15 4 0 7.8.5 3.9.7 7.5 1.9t7 3q3.3 1.9 6.4 4.3 3.2 2.4 5.9 5.4 14.4 15 14.5 36.5zm-22.6 0q0-2.4-.4-4.5-.2-2.2-.9-4.2-.6-2-1.5-3.9-1-2-2.2-3.7-1.2-1.7-2.8-3.4-4-4.2-8.6-6.1-4.5-2-10-2-11 0-18.7 8.2-7.8 8-7.8 19.6 0 11.4 7.8 19.7 7.8 8 18.6 8 5.6 0 10.1-1.9 4.6-2 8.6-6.1 4-4.3 5.8-9 2-4.9 2-10.7z" />
<path id="header-k"
d="M186.3 131q0 4.7-3.3 8.3-1.5 1.8-3.7 2.7-2 1.1-4.3 1.1-3.5 0-6.6-2L119.2 105v26q0 5.5-3 8.6-3.1 3.4-8.4 3.3l-2.2-.2q-1-.1-2.2-.5-1-.3-2-1-1-.6-1.8-1.6-1.7-1.6-2.4-3.8-.7-2.3-.7-4.8V11.9q0-5.5 3-8.6 3-3.4 8.3-3.3 5.2 0 8.2 3.3 3.2 3.1 3.2 8.6v65.9l49.2-36.1q3.2-2 6.6-2 4.7 0 8 3.7t3.3 8.4q-.2 6-5 9.6l-41 30 41 29.9q2.3 1.7 3.6 4.2 1.4 2.5 1.4 5.4z" />
<path id="header-tilde"
d="M73.1 91q0 2-.6 3.9T71 98.6q-3.2 5.7-8.9 8.5-5.6 2.8-12.9 2.8-8.8 0-18-7.8-2.4-2.3-4.5-3.7-2.1-1.5-3-1.7-1.5 0-2.1.3l-.8 1.3q-.3.7-.8 1.2l-1 1-.9.8q-2.7 2-6.4 2-1.7 0-3.2-.3-1.4-.3-3-1.1-1.5-.8-2.6-2.1-2.8-3.1-2.8-8v-1.3q0-.7.2-1.2l.2-1 .4-1 .4-1q.1-.6.5-1.1l.5-1q3.2-5.7 8.8-8.5 5.7-2.9 13-2.9 3.2 0 6.2 1 3 .9 6 2.7 2.9 1.6 5.7 4.2 5.2 4.6 7.6 5.4 1 0 1.6-.2l.7-.4q.3-.1.5-.4 3.6-5.6 9.2-5.6 5.7 0 8.8 3.5 2.8 3 2.8 8z" />
</svg>
Homepage of
<div class=p-name>
<span class=first-name>Norman</span>
<span class=last-name>Köhring</span>
</div>
Code Artist
</a>
</header>
<div id="main-menu">
<menu>
<li><a title="What I do these days" href="/now">/now</a></li>
<li><a title="Today I Learned" href="/til">/til</a></li>
<li><a title="My projects" href="/projects">/projects</a></li>
<li><a title="Weblog" href="/blog">/blog</a></li>
<li><a title="CV / Resume" href="/cv">/cv</a></li>
<li><a title="Tools I use" href="/stack">/stack</a></li>
<li><a title="Hardware I use" href="/setup">/setup</a></li>
<li><a title="Shared Bookmarks" href="/bookmarks">/links</a></li>
</menu>
</div>
<footer id="footer">
</footer>
<script defer>
const el = document.getElementById('header')
const threshhold = 24
let headerIsSmall = false
window.addEventListener("scroll", () => {
if (window.scrollY > threshhold && !headerIsSmall) {
el.classList.add('small')
headerIsSmall = true
} else if (window.scrollY <= threshhold && headerIsSmall) {
el.classList.remove('small')
headerIsSmall = false
}
})
</script>
<script async data-goatcounter=https://koehr.goatcounter.com/count src=//gc.zgo.at/count.js></script>
</body>
</html>