Monday, 10 June 2019

MacOS Software Development Kit changes

This post is based on the README from the corresponding Github repository.

That repository attempts to cope with expected changes in Apple’s approach to software development kits, specifically where to find the system headers (you’d expect /usr/include).

Apple’s development environment is Xcode. They provide a cut-down version called the Command Line Tools for those of us who don’t need to develop for iPhone or Apple Watch. Xcode includes SDKs for those platforms, the Command Line Tools just for macOS (MacOSX, internally).

Up until Mojave, the Command Line Tools (which you get by xcode-select --install) automatically installed /usr/include. Apple’s developer tools (clang etc) know where to find the includes in the current SDK, but GCC doesn’t.

Apple say

As a workaround, an extra package is provided which will install the headers to the base system. In a future release, this package will no longer be provided.

You do the installation by

$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
Password:
installer: Package name is macOS_SDK_headers_for_macOS_10.14
installer: Installing at base path /
installer: The install was successful.

So, what to do about it?

GNAT CE 2019

AdaCore’s GNAT GE 2019 release anticipates the lack of /usr/include by building the compiler using a system root inside the Xcode SDK:

--with-specs='%{!sysroot=*:--sysroot=%:xcode-path(/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk)}'

The xcode-path() bit appended its argument to Xcode’s path on their development machine, /Applications/Xcode.app/Contents/Developer, which is OK so long as you actually have Xcode installed. It looks under that prefix for usr/include, usr/lib. But

  • If you only have the Command Line Tools, the prefix you actually need is /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk.
  • The compiler can’t find /usr/local/include or /usr/local/lib (because it’s looking under the Xcode SDK).

The first problem is fixable: install Xcode!
You can fix the second by -I/usr/local/include, -L/usr/local/lib.

An alternative (without installing Xcode) would be to copy ce2109-specs to $prefix/lib/gcc/x86_64-apple-darwin17.7.0/8.3.1/specs (ce2019-specs was generated by gcc -dumpspecs and judicious editing).

FSF GCC

A similar problem arises with FSF GCC, builds provided at Sourceforge.

The approach I’m planning to adopt for future releases is to disable System Integrity Protection (which prevents altering important system directories, and is normally Not Recommended) and copy usr/include from inside whichever SDK is installed to the normal place, then build the compiler as normal.

For users who haven’t done this (the majority, I expect and hope) I’ll provide a modified specs on the same lines. gcc9-specs is the version for GCC 9.1.0; it adds both possible SDKs to the include search path, GCC will take the first one it finds (absent /usr/include).

Sunday, 19 May 2019

Coding Guidelines

Coding_Guide

This is a rather self-satisfied document, written in the mid-1990’s, which may still have some relevance.

Coding Guide

Purpose and Scope

While it is hard to make a silk purse out of a sow’s ear (to create good code from a bad design), it is all too easy to do the reverse.

The principle that clear, readable, understandable source text eases program evolution, adaptation, and maintenance is not dependent on the programming language in which the text is written. The purpose of this document is to indicate those language-independent techniques which can help you to produce source text with these qualities.

Friday, 1 February 2019

Monday, 19 November 2018

Mojave vs. GCC

After you've installed Xcode (or, my preference, the Command Line Tools via xcode-select -install) so that you can install and use GNAT, you may expect to be able to compile C code too.

Mojave may surprise you with

$ gcc casing.c -o casing
casing.c:1:10: fatal error: stdio.h: No such file or directory
    1 | #include <stdio.h>
      |          ^~~~~~~~~
      compilation terminated.

The reason, according to this question and its answers, is that Apple's developer tools, in particular the clang compiler, know where to find the include files under /Library/Developer; GCC doesn't (I'm sure it could be made to, but ...) and so we have to add an extra step to install them in the normal place:

$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
Password:
installer: Package name is macOS_SDK_headers_for_macOS_10.14
installer: Installing at base path /
installer: The install was successful.
You may need to repeat this after macOS or Command Line Tools (or Xcode) updates.

Mojave vs. GDB

Apple's software development tools are based on LLVM, and Apple don't seem to feel it necessary to keep GCC and friends up to date with changes in the Apple tools or security policies.

GDB has been particularly affected by this. You can see why a tool which is capable of interacting with running programs would have to be treated with caution.

Thursday, 21 June 2018

VMWare shared drive vs Debian Stretch

This note is about problems with VMWare shared drives failing to mount.

My previous setup was VMWare Fusion 8 and Debian 8 (jessie), with the VMWare-recommended open-vm-tools. After upgrading to VMWare Fusion 10 and Debian 9 (stretch), the shared folder (~) on the Mac was no longer visible from Debian (~/mac, a symbolic link to /mnt/hgfs).

After looking here, I added this line to /etc/fstab:

vmhgfs-fuse /mnt/hgfs fuse defaults,allow_other 0 0

but rebooting hung, and invited me to log in as system to fix the problem.

Other posts in the reference stated that you need to mount to /mnt/hgfs/mac: so, edit the /etc/fstab line to

vmhgfs-fuse /mnt/hgfs/mac fuse defaults,allow_other 0 0

and the system rebooted OK.

Now, make ~/mac a link to /mnt/hgfs/mac:

ln -sf /mnt/hgfs/mac ~/mac

and all is well again.


Incidentally, I found that copy/paste between host and client no longer worked: another Google search led me to

sudo apt-get install open-vm-tools-desktop

Reboot, and on we go!

Thursday, 14 June 2018

Secondary Stack in Cortex GNAT RTS

In GNAT, the secondary stack is a construct used with indeterminate types. For example, if a function returns a String, it isn't possible for the caller to determine how much space to reserve for the result: instead, the called function allocates the amount of space required on the secondary stack, and on return the caller determines how much space to allocate on the normal (primary) stack, and pops the function's result from the secondary stack to there.

This note discusses how the secondary stack is managed in Cortex GNAT RTS for FSF GCC and GNAT Community Edition (was GNAT GPL).