(λ (x) (create x) '(knowledge))

Pilot-Link Broke my C Compiler

Or was it actually my CFLAGS? · December 30th, 2023

Look at that, another post squeezed in right at the end of the year! Where is all of this blogging energy coming from?! I'm not going to complain though, I feel like I'm on a technical roll here. Lots of new aports, lots of updates to Verkos. Lots of changes to my homelab. I must be nesting waiting for my daughter to arrive, only it's manifesting in ways that aren't nearly as helpful as actual nesting. I'm just going to embrace it though.

So anyways, one of the things I've been doing a lot lately has been adding new aports to Alpine. It's sort of all over the place, but there's been a couple of SBC tools like sunxi-tools, and a couple of Palm PDA tools that I've been hoarding for personal use. Specifically PyPlucker and pilot-link are up on the docket. And this little post is about pilot-link. See if the output from ls -al is to be believed, I compiled and initially made a personal APKBUILD for pilot-link back in August of 2022. That roughly coincides with my review of the Palm T|x PDA and a little bit of a whirlwind tour of usage as I used it to plan and coordinate an entire install at $work. It was a great experience, but at the time I was too busy to be bothered to bring it into aports. Now I have this sudden burst of energy as I wait for a replacement battery to come in for my Palm Tungsten T, and so I'm clearing out my backlog of aports. Getting all of my tools in place so that everyone who uses Alpine can benefit from them!

So quick 15m aport right? Run a quick build test, make sure that it works on my chuwi since my droid is out of commission until I get a new battery for it, no big deal.

configure: error: C compiler cannot create executables

Well shit, what does that even mean? At least, that was my exact thought upon seeing the error message. I don't do a lot of C, but I maintain enough C based projects that I'm pretty used to debugging these things, but that's a new one for me. What do you mean my C compiler can't create executables? It 100% works, I can prove it.


#include 

int main() {
   printf("Hello, World!\n");
   return 0;
}

~|>> cc test.c
~|>> ./a.out 
Hello, World!
 

You're WRONG abuild, my C compiler works fine! So we run abuild -r again and get the same exact error, and nobody was surprised, but damn it I was frustrated. So I hippity hop onto IRC and start debugging with mio. We dive through everything we can think of. Can you run this APKBUILD and build it? They say, yes of course, it's simple, try these adjustments to the APKBUILD. I try them and get the same compiler issue. Maybe it's a difference in installed packages, maybe if I install everything in mio's world file it'll work. So we diff the worlds, apply everything relevant, the build still fails. Then I start poking the system manually. Clone the repo manually, run ./configure manually, and what do you know, it works! I can make build it too! Alright, obviously whatever we did work, hop back over to the abuild and fix it up with our changes.

And I get the same damn error. Cmon, this just isn't right. At this point I just make a draft MR on aports to use the CI/CD, I can't figure out why my Chuwi has this issue, my LXD containers have this issue. And as soon as it hits the CI, I reproduce the error. That's way too consistent for me. There's something different between my droid, my chuwi/lxd/aports CI, and mio's dev box. So I step back, and take a look at what other people are doing with this package, and find this great comment on the Arch Linux AUR.


Pulec commented on 2022-12-19 08:22 (UTC)

checking for gcc... gcc
checking whether the C compiler works... no
configure: error: in `/home/pulec/.cache/aurutils/sync/pilot-link/src/pilot-link-0.12.5':
configure: error: C compiler cannot create executables
See `config.log' for more details.

the config.log -> https://0x0.st/o58W.log
I tried doing pilot-link from https://github.com/desrod/pilot-link, just a few switches:
source=("$pkgname::git+https://github.com/desrod/pilot-link.git" skip MD5sum ${pkgname}-${pkgver} shorten to just ${pkgname} and replace configure with autogen.sh
still the same error and config.log https://0x0.st/o58V.log
I guess I'll just use kde-pim.
 
<>Hey! That's my issue too! Damn, that's also really shortly after I initially got this working too, weird. But giving up isn't the option I want.. Fortunately tons of time had passed and Jichu4n had wandered into the scene with some really useful information. This is pretty great if you ask me, Jich4n is a pretty big name in the Palm world, he maintains a ton of different libraries and useful palm tools. I knew immediately there were words of wisdom here.


jichu4n commented on 2023-04-16 03:47 (UTC) (edited on 2023-04-16 03:51 (UTC) by jichu4n)
I got the same error as @Pulec, but was able to get it to work after a little bit of poking around.
Looking through the errors I realized that this is related to the default CFLAGS settings in /etc/makepkg.conf . Specifically, it looks like the ./configure script is trying to parse -W flags but then messing up.

So I edited /etc/makepkg.conf:
    Comment out the existing CFLAGS= and CXXFLAGS= lines
    Create new CFLAGS= and CXXFLAGS= lines based on the existing ones but with all flags starting with "-W" removed

The end result:
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -fstack-clash-protection -fcf-protection"
CXXFLAGS="$CFLAGS"

After that building and installing using yay worked fine.
 

Okay CFLAGS, maybe that's worth looking into. There are no CFLAGS defined if I just run the build manually, but if I export $CFLAGS and $CXXFLAGS inside the apkbuild I can probably see if they match what they suggest. And lo and behold, the answer was right there before me.


CFLAGS
  -Os -fstack-clash-protection -Wformat -Werror=format-security -fno-plt

CXXFLAGS
  -Os -fstack-clash-protection -Wformat -Werror=format-security -D_GLIBCXX_ASSERTIONS=1 -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -D_LIBCPP_ENABLE_HARDENED_MODE=1 -fno-plt
 

So in Alpine we enforce a common set of C and C++ flags for all of our builds. It's a security measure, and it's a great idea. What I didn't know before today is that there are some flags that cause weird incompatibility errors like this one in pilot-link. Specifically -Werror=format-security breaks the entire build for pilot-link. That CFLAG didn't exist in the default Alpine configuration in August of 2022, nor did it exist on Mio's dev box because it was using an old version of the config. But it did happily manifest itself on new LXD containers, and my Chuwi which is a fairly recent installation.

The change is actually really recent to Alpine as well! So of course it worked fine earlier, and of course it would crop up now.

In the end the fix might not be acceptable by Alpine's standards, but I can confirm that this build block actually works to resolve the wonky C compiler issue.


build() {
	#-Werror=format-security causes the error
	#C compiler cannot create executables
	CFLAGS="-Os -fstack-clash-protection -Wformat -fno-plt"
	CXXFLAGS="-Os -fstack-clash-protection -Wformat -D_GLIBCXX_ASSERTIONS=1 -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -D_LIBCPP_ENABLE_HARDENED_MODE=1 -fno-plt"
	./configure --prefix=/usr --enable-conduits --enable-libusb \
				--with-libiconv --with-libpng

	make
}
  

The Eleventh Hour

And then, lo and behold as I diverted my attention to the fact that my ZFS NAS had decided to stop properly exporting its NFS configuration on boot, Mio swooped in with not only a logical explanation for my woes and tribulations, but several patches to fix everything up so that we can keep our CFLAGS in the package build.

4:57 <@mio> there were two issues: 1. ./configure does a check for c compiler (gcc) version, guessing a list of flags and throws an error because the -V and -qversion flags don't work 04:59 <@mio> and it sed-style tries to disable any -Werror flags, except it doesn't remove the entire flag 04:59 <@mio> so one of the $CFLAGS that got passed to gcc was `=format_security`, which obv gcc didn't like 05:01 <@mio> both things caused the check to fail, so no compiler, no build 05:03 <@mio> 2. there's some string literal thing where string literals were being passed to printf/fprintf and that caused the build to fail, so 2nd patch attempts to fix those also

It turns out that the CFLAGS were reported in the compilation error log, and I just missed it entirely. Removing the security option fixed the sed issue and allowed the program to compile and masking the actual issue, that malformed CFLAGS break compilation. The big take away here, always double check your error logging carefully, and if GCC says it isn't a valid compiler, your CFLAGS are probably broken!

Shout Out

A massive thank you goes out to Mio who helped me troubleshoot this issue in so many various ways, and actually found the git commit that held the CFLAG changes. I don't think I'd actually of gotten this figured out without their help.

Bio

(defparameter *Will_Sinatra* '((Age . 31) (Occupation . DevOps Engineer) (FOSS-Dev . true) (Locale . Maine) (Languages . ("Lisp" "Fennel" "Lua" "Go" "Nim")) (Certs . ("LFCS"))))

"Very little indeed is needed to live a happy life." - Aurelius