It looks like the install -D command is actually what I want.
Manpage:
-D create all leading components of DEST except the last, then copy SOURCE to DEST
Works great, except you have to specify every file individually.
Answer from ashgromnies on Stack ExchangeVideos
It looks like the install -D command is actually what I want.
Manpage:
-D create all leading components of DEST except the last, then copy SOURCE to DEST
Works great, except you have to specify every file individually.
install -d is just used to create directories. You told it to create two directories, test and test2. test already existed, so all it needed to do was make test2. I don't think install supports copying entire directory trees; it's normally used on files. You probably need to use cp
There’s no magic incantation to make install install files recursively. install might not be the best tool in this scenario: you might be better off using cp to copy the files and directory structure, and then chmod to fix up the modes.
I first create the directory tree and afterwards copy the files as shown in this function:
#!/usr/bin/env bash
# Install directory
# returns 1 on error
# $1: Source directory
# $2: Target directory
_install_directory() {
local _src="${1}" \
_dest="${2}" \
_path=()
# Directory does not exist
[ ! -d "${_src}" ] && \
return 1
while IFS="" \
read -r \
_path; do
[ -d "${_dest}/${path}" ] || \
mkdir -m 0755 \
-p \
"${_dest}/${path}" || \
return 1
done <<<$(find "${_src}" \
-type d \
-printf '%P\n')
# files
while IFS="" \
read -r \
_path; do
[ -z "${_path}" ] && \
continue
install -m 0644 \
"${_src}/${_path}" \
"${_dest}/${_path}" || \
return 1
done <<<$(find "${_src}" \
-type f \
-printf '%P\n')
# symlinks
while IFS= \
read -r \
_path; do
[ -z "${_path}" ] && \
continue
cp -fPT \
"${_dir}/${_path}" \
"${_dest}/${_path}" || \
return 1
done <<<$(find "${_src}" \
-type l \
-printf '%P\n')
}
_src="${1}"
_dest="${2}"
_install_directory "${_src}" \
"${_dest}"
Homebrew now has the GCC package so you can install it with this command:
brew install gcc
The way I do it is:
- Download the source for GCC and numerous supporting packages. The instructions are in the
gcc-4.x.y/INSTALL/index.htmlfile in the GCC source code, or online at http://gcc.gnu.org/install/.
- GNU Multiple Precision Library (GMP) version 4.3.2 (or later) from http://gmplib.org/.
- MPFR Library version 2.4.2 (or later) from http://www.mpfr.org/.
- MPC Library version 0.8.1 (or later) from http://www.multiprecision.org/.
- ISL Library version 0.11.1 from ftp://gcc.gnu.org/pub/gcc/infrastructure/.
- CLooG 0.18.0 from ftp://gcc.gnu.org/pub/gcc/infrastructure/.
- Use a script to extract the source for GCC and the support libraries into a directory, create the object directory, and run the build.
This is the script I used for GCC 4.8.2:
GCC_VER=gcc-4.8.2
tar -xf ${GCC_VER}.tar.bz2 || exit 1
(
cd ${GCC_VER} || exit
cat <<EOF |
cloog 0.18.0 tar.gz
gmp 5.1.3 tar.xz
isl 0.11.1 tar.bz2
mpc 1.0.1 tar.gz
mpfr 3.1.2 tar.xz
EOF
while read file vrsn extn
do
(
set -x
tar -xf "../$file-$vrsn.$extn" &&
ln -s "$file-$vrsn" "$file"
)
done
)
mkdir ${GCC_VER}-obj
cd ${GCC_VER}-obj
../${GCC_VER}/configure --prefix=$HOME/gcc/gcc-4.8.2
make -j8 bootstrap
When that finishes, run the install too. Then add $HOME/gcc/gcc-4.8.2/bin (the name you specify in --prefix plus /bin) to your PATH ahead of /usr/bin.
With a decent MacBook Pro with a 5400 rpm spinning disk, it takes an hour or two to compile everything (using the -j8 option to make), and requires multiple gigabytes of disk space while compiling. SSD is nice when doing this (definitely faster)!
GCC 4.9.0 was released on 2014-04-22. I've installed it using basically the same process, but with CLooG 0.18.1 and ISL 0.12.2 (required updates) and GMP 5.1.3 (and 6.0.0a), MPC 1.0.2 (or 1.0.1) and MPFR 3.1.2 on Mac OS X 10.9.2 Mavericks and an Ubuntu 12.04 (Precise Pangolin) derivative. Beware that the gmp-6.0.0a.tar.xz extracts into directory gmp-6.0.0 (not gmp-6.0.0a as you might expect).
Between 2014 and 2017-09-27, I've built GCC versions 4.9.0, 4.9.1, 5.1.0, 5.2.0, 5.3.0, 6.1.0, 6.2.0, 6.3.0, 7.1.0 with only minor variations in the build script shown below for GCC 7.2.0 on macOS v10.12 (Sierra). The versions of the auxiliary libraries changed reasonably often.
macOS Sierra and High Sierra
On 2017-08-14, I used a minor variant of the script above to build GCC 7.2.0 on macOS v10.12 (Sierra) (using Xcode 8 as the bootstrap compiler). One change is that CLooG doesn't seem to be needed any more (I stopped adding it with GCC 6.2.0). This is my current script:
#!/bin/bash
#export DYLD_LIBRARY_PATH=$(clnpath $(dirname $(dirname $(which g++)))/lib:$DYLD_LIBRARY_PATH)
unset DYLD_LIBRARY_PATH
TAR=/opt/gnu/bin/tar
VER_NUM=7.2.0
GCC_VER=gcc-${VER_NUM}
TGT_BASE=/opt/gcc
TGT_DIR=${TGT_BASE}/v${VER_NUM}
CC=/usr/bin/clang
CXX=/usr/bin/clang++
extract() {
echo "Extract $1"
$TAR -xf $1
}
if [ ! -d "$GCC_VER" ]
then extract ${GCC_VER}.tar.xz || exit 1
fi
(
cd ${GCC_VER} || exit
nbncl <<EOF |
gmp 6.1.2 tar.lz
isl 0.16.1 tar.bz2
mpc 1.0.3 tar.gz
mpfr 3.1.5 tar.xz
EOF
while read file vrsn extn
do
tarfile="../$file-$vrsn.$extn"
if [ ! -f "$tarfile" ]
then echo "Cannot find $tarfile" >&2; exit 1;
fi
if [ ! -d "$file-$vrsn" ]
then
(
set -x
extract "$tarfile" &&
ln -s "$file-$vrsn" "$file"
) || exit 1
fi
done
)
if [ $? = 0 ]
then
mkdir ${GCC_VER}-obj
cd ${GCC_VER}-obj
../${GCC_VER}/configure --prefix="${TGT_DIR}" \
CC="${CC}" \
CXX="${CXX}"
make -j8 bootstrap
fi
Make sure your version of tar supports all four different compressed file formats (.lz, .gz, .xz, .bz2), but since the standard Mac version of tar does that for me, it'll probably work for you too.
On 2017-09-27, I failed to build GCC 7.2.0 on macOS v10.13 (High Sierra) (using Xcode 9 for the bootstrap compiler) using the same script as worked on v10.12 (Sierra). The immediate error was a missing header <stack>; I'll need to track down whether my Xcode 9 installation is correct — or, more accurately, why it isn't correct since <stack> is a standard header in C++98 onwards. There's probably an easy fix; I just haven't spent the time chasing it yet. (Yes, I've run xcode-select --install multiple times; the fact that I had to run it multiple times because of network glitches may be part of the trouble.) (I got GCC 7.2.0 to compile successfully on 2017-12-02; I don't recall what gymnastics — if any — were required to get this to work.)
Time passes; version numbers increase. However, the basic recipe has worked for me with more recent versions of GCC. I have 7.3.0 (installed 2018-01-2), 8.1.0 (installed 2018-05-02), 8.2.0 (installed 2018-07-26), 8.3.0 (installed 2019-03-01) and now 9.1.0 (installed today, 2019-05-03). Each of these versions was built and installed on the current version of macOS at the time, using the current version of Xcode for the bootstrap phase (so using macOS v10.14.4 (Mojave) and Xcode 10.2.1 when building GCC 9.1.0).
GNU assembler, AKA as, is installed by default on Ubuntu. It is in the package binutils.
Build from source and use it
#!/usr/bin/env bash
set -eux
# Build.
sudo apt-get build-dep binutils
git clone git://sourceware.org/git/binutils-gdb.git
cd binutils-gdb
git checkout binutils-2_31
./configure --target x86_64-elf --prefix "$(pwd)/install"
make -j `nproc`
make install
# Test it out.
cat <<'EOF' > hello.S
.data
s:
.ascii "hello world\n"
len = . - s
.text
.global _start
_start:
mov $4, %eax
mov $1, %ebx
mov $s, %ecx
mov $len, %edx
int $0x80
mov $1, %eax
mov $0, %ebx
int $0x80
EOF
./install/bin/x86_64-elf-as -o hello.o hello.S
./install/bin/x86_64-elf-ld -o hello hello.o
./hello
GitHub upstream.
TODO: how to configure as specific options? We have used the ./configure from the binutils-gdb top-level, but that contains options from multiple projects such as gdb I believe, and not as specific ones?
Tested on Ubuntu 18.04.
as is the GNU Assembler. It's found in binutils but if you do:
sudo apt-get install build-essential
You will get gas along with gcc (which default uses gas for assembling on the back end).
For a 'tutorial' about using gas, you probably want to read Programming From the Ground Up, which uses it.
To build a static executable from a .s file,
#!/bin/bash
f="${1:-}"
as "${f}" -o "${f%%.s}.o" && ld "${f%%.s}.0" -o "${f%%.s}"
gcc -nostdlib -static "${f}" -o "${f%%.s}"
If you want to link with libraries, it's normally easiest to let gcc use the right command line options for as and ld when building an executable from an asm source file.
gcc foo.s -o foo will work if your foo.s defines a main function.
Also related: Assembling 32-bit binaries on a 64-bit system (GNU toolchain) if you're writing 32-bit programs on an x86-64 system.
It's in the binutils package.