Skip to content

Commit

Permalink
Add GNU make based build system
Browse files Browse the repository at this point in the history
Add a single makefile such that it will rarely need modifications
with regular source code changes.

The usual configure step for build environment detection is done
manually by editing config.mk, it is expected to be simple make
variable changes (mostly CFLAGS), later a simple configure script
can be added to generate config.mk if necessary.

Update the README.
  • Loading branch information
nsz-arm committed May 16, 2018
1 parent 1b94597 commit 7889228
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 62 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build/
.DS_Store
config.mk
142 changes: 142 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Makefile - requires GNU make
#
# Copyright (c) 2018, Arm Limited.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

srcdir = .
prefix = /usr
bindir = $(prefix)/bin
libdir = $(prefix)/lib
includedir = $(prefix)/include

HACK = $(srcdir)/math/s_sincosf.c

MATH_SRCS = $(filter-out $(HACK),$(wildcard $(srcdir)/math/*.[cS]))
MATH_BASE = $(basename $(MATH_SRCS))
MATH_OBJS = $(MATH_BASE:$(srcdir)/%=build/%.o)
RTEST_SRCS = $(wildcard $(srcdir)/test/rtest/*.[cS])
RTEST_BASE = $(basename $(RTEST_SRCS))
RTEST_OBJS = $(RTEST_BASE:$(srcdir)/%=build/%.o)
ALL_OBJS = $(MATH_OBJS) $(RTEST_OBJS) build/test/mathtest.o

INCLUDES = $(wildcard $(srcdir)/math/include/*.h)
ALL_INCLUDES = $(INCLUDES:$(srcdir)/math/%=build/%)

ALL_LIBS = \
build/lib/libmathlib.so \
build/lib/libmathlib.a \

ALL_TOOLS = \
build/bin/runtest.sh \
build/bin/rtest \
build/bin/mathtest \

TESTS = $(wildcard $(srcdir)/test/testcases/*/*.tst)
ALL_TESTS = $(TESTS:$(srcdir)/test/testcases/%=build/bin/%)

# Configure these in config.mk, do not make changes in this file.
HOST_CC = cc
EMULATOR =
CFLAGS = -std=c99 -O2
LDFLAGS =
CPPFLAGS =
AR = $(CROSS_COMPILE)ar
RANLIB = $(CROSS_COMPILE)ranlib
INSTALL = install

CFLAGS_ALL = -I$(srcdir)/math/include $(CPPFLAGS) $(CFLAGS)
LDFLAGS_ALL = $(LDFLAGS)

-include config.mk

all: $(ALL_LIBS) $(ALL_TOOLS) $(ALL_INCLUDES)

DIRS = $(dir $(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(ALL_INCLUDES) $(ALL_TESTS))
ALL_DIRS = $(sort $(DIRS:%/=%))

$(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(ALL_OBJS:%.o=%.os) $(ALL_INCLUDES) $(ALL_TESTS): | $(ALL_DIRS)

$(ALL_DIRS):
mkdir -p $@

$(ALL_OBJS:%.o=%.os): CFLAGS_ALL += -fPIC

$(RTEST_OBJS): CC = $(HOST_CC)

build/%.o: $(srcdir)/%.S
$(CC) $(CFLAGS_ALL) -c -o $@ $<

build/%.o: $(srcdir)/%.c
$(CC) $(CFLAGS_ALL) -c -o $@ $<

build/%.os: $(srcdir)/%.S
$(CC) $(CFLAGS_ALL) -c -o $@ $<

build/%.os: $(srcdir)/%.c
$(CC) $(CFLAGS_ALL) -c -o $@ $<

build/lib/libmathlib.so: $(MATH_OBJS:%.o=%.os)
$(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -shared -o $@ $^

build/lib/libmathlib.a: $(MATH_OBJS)
rm -f $@
$(AR) rc $@ $^
$(RANLIB) $@

build/bin/rtest: $(RTEST_OBJS)
$(HOST_CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -o $@ $^ -lm -lmpfr -lmpc

build/bin/mathtest: build/test/mathtest.o build/lib/libmathlib.a
$(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -static -o $@ $^ -lm

build/include/%.h: $(srcdir)/math/include/%.h
cp $< $@

build/bin/runtest.sh: $(srcdir)/test/runtest.sh
cp $< $@

build/bin/%.tst: $(srcdir)/test/testcases/%.tst
cp $< $@

clean:
rm -rf build

distclean: clean
rm -f config.mk

$(DESTDIR)$(bindir)/%: build/bin/%
$(INSTALL) -D $< $@

$(DESTDIR)$(libdir)/%.so: build/lib/%.so
$(INSTALL) -D $< $@

$(DESTDIR)$(libdir)/%: build/lib/%
$(INSTALL) -m 644 -D $< $@

$(DESTDIR)$(includedir)/%: build/include/%
$(INSTALL) -m 644 -D $< $@

install-tools: $(ALL_TOOLS:build/bin/%=$(DESTDIR)$(bindir)/%)

install-libs: $(ALL_LIBS:build/lib/%=$(DESTDIR)$(libdir)/%)

install-headers: $(ALL_INCLUDES:build/include/%=$(DESTDIR)$(includedir)/%)

install: install-libs install-headers

check: $(ALL_TOOLS) $(ALL_TESTS)
build/bin/runtest.sh $(EMULATOR) ./mathtest

.PHONY: all clean distclean install install-tools install-libs install-headers check
92 changes: 31 additions & 61 deletions README
Original file line number Diff line number Diff line change
@@ -1,73 +1,43 @@
ARM math library functions
----------------------------
Arm Optimized Routines
----------------------

This package contains a number of math functions from ARM's math library,
as well as a build system and a test suite. In addition to the source code,
there is also a script "remez.jl", which was used to generate coefficients
used in the implementation of these functions (see comments in the code).
This repository contains implementations of math library functions
provided by Arm under Apache License 2.0 (See LICENSE). Contributions
to this project are accepted, but the terms will need negotiation (so
relicensing and copyright assignment to the FSF is possible later).

Requirements: gcc >= 4.8, cmake >= 2.8, mpfr, mpc, qemu-user-static.
Source code layout:

For a native build on an AArch64 platform, everything (including tests) should
work out-of the box, assuming the system compiler is a recent gcc. Simply follow
the instructions below to configure the build using cmake (leaving out the
-DCMAKE_TOOLCHAIN_FILE argument).
auxiliary/ - design tools.
build/ - build directory (created by make).
math/ - math library source.
math/include/ - math library public headers.
math/single/ - code for cpu with only single precision support.
test/ - test related source.
test/rtest/ - test generator (requires mpfr and mpc).
test/testcases/ - test cases.

Cross builds are supported for Linux hosts. First, install the required
packages to build and run the tests on your distro of choice:
# apt-get install qemu-user-static gcc-aarch64-linux-gnu libmpfr-dev \
libmpc-dev cmake
The steps to build the library and run the tests:

You could also use a custom aarch64-linux-gnu-gcc cross toolchain, e.g. from
Linaro, if your system doesn't provide one:

https://releases.linaro.org/15.02/components/toolchain/binaries/

The build script will build both a shared and a static math library object
containing the ARM functions for the specified target, a host-side application
rtest that generates test cases, and a target-side application mathtest that is
linked against the math library and actually executes the tests.

Generally, the steps to build and run the tests are:

mkdir -p /my/build/folder && cd /my/build/folder
cmake /path/to/src -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain/file
cp config.mk.dist config.mk
# edit config.mk if necessary ...
make
make check

The toolchain file specifies the paths to the cross-compiler, i.e.
aarch64-linux-gnu-gcc, as well as the sysroot parameter for the build. An
example can be found in toolchain-gcc.cmake, which assumes that you have
the cross toolchain installed in /usr/bin and the sysroot is
/usr/aarch64-linux-gnu respectively. This should work with the Ubuntu packages
suggested above as-is. Edit the paths as necessary if your cross toolchain
lives somewhere else. Alternatively, you can specify the necessary parameters
from the toolchain file directly on the command line.
Or building outside of the source directory:

The files are built in the build directory as follows:
build/
bin/
rtest
mathtest
runtest.sh
lib/
libmathlib.so
libmathlib_static.a
include/
arm_math.h
ln -s path/to/src/Makefile Makefile
cp path/to/src/config.mk.dist config.mk
echo 'srcdir = path/to/src' >> config.mk
# further edits to config.mk
make
make check

It is possible to specify which emulator to use for the execution of the tests
in the cross compilation case by specifying the following option:
cmake (...) -DCMAKE_CROSSCOMPILING_EMULATOR=/path/to/your/emulator
By default, qemu-aarch64-static will be used, so this has to be on your path
if you want to cross-run the test suite.
The test system requires libmpfr and libmpc.

Whenever the CMake configuration is changed, it is wise to delete the whole
build folder instead of just rerunning CMake inside the existing folder.
For cross build, CROSS_COMPILE should be set in config.mk and EMULATOR
should be set for cross testing (e.g. using qemu-user or remote access
to a target machine), see the examples in config.mk.dist.

The build system also has experimental support for using clang as the cross
compiler.
!!!You need CMake >= 3.0 and clang >= 3.5.0 for this!!!
Before compilation, apply the source patch in the patches/ folder to make sure
everything works properly when compiled with clang. There is a sample toolchain
file for clang included as toolchain-clang.cmake.
The script "remez.jl" was used to generate some of the coefficients
(see comments in the code).
40 changes: 40 additions & 0 deletions config.mk.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Example config.mk
#
# Copyright (c) 2018, Arm Limited.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

HOST_CC = gcc
CC = $(CROSS_COMPILE)gcc
CFLAGS = -std=c99 -pipe -O3
CFLAGS += -Wall -Wno-missing-braces -Wno-strict-aliasing -Wno-unused-function

# Use if the target FPU only supports single precision.
#CFLAGS += WANT_SINGLEPREC

# Use with gcc.
CFLAGS += -frounding-math -fexcess-precision=standard -fno-stack-protector
CFLAGS += -ffp-contract=fast
CFLAGS += -Wno-maybe-uninitialized

# Use with clang.
#CFLAGS += -DCLANG_EXCEPTIONS
#CFLAGS += -ffp-contract=fast

# Use for cross compilation with gcc.
#CROSS_COMPILE = aarch64-none-linux-gnu-

# Use with cross testing.
#EMULATOR = qemu-aarch64-static
#EMULATOR = sh -c 'scp $$1 user@host:/dir && ssh user@host /dir/"$$@"' --
2 changes: 1 addition & 1 deletion test/runtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ cd "${0%/*}"
# For a cross-build, the actual tests have to be executed in QEMU or an emulator
# of choice. This is set in the CMake script and filled in here.

find . -iname "*.tst" -print0 | xargs -0 cat | ./rtest | @CMAKE_CROSSCOMPILING_EMULATOR@ "$@"
find . -iname "*.tst" -print0 | xargs -0 cat | ./rtest | "$@"

0 comments on commit 7889228

Please sign in to comment.