Skip to content

Commit

Permalink
Default to statically linking LLVM into ponyc (ponylang#3355)
Browse files Browse the repository at this point in the history
Prior to this commit, we previously built ponyc with LLVM dynamically linked by default. This PR changes to statically link LLVM- except on Windows which hasn't been addressed yet.

There are now 3 options that can be supplied to the Makefile via the `link` option

- static 
- llvm-static
- llvm-dynamic

### static

static will only work when using musl libc. it will attempt to statically link every related to ponyc .

### llvm-static

the new default, llvm-static, will statically link LLVM into ponyc. Additionally, it will statically link libstdc++ and if using gcc, libgcc

### llvm-dynamic

llvm-dynamic is the previous default where LLVM would be dynamically linked to ponyc.
  • Loading branch information
SeanTAllen authored Oct 30, 2019
1 parent ed5f22d commit a4dc299
Show file tree
Hide file tree
Showing 13 changed files with 64 additions and 63 deletions.
2 changes: 1 addition & 1 deletion .ci-scripts/x86-64-unknown-linux-gnu-nightly.bash
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ ASSET_DESCRIPTION="https://github.com/ponylang/ponyc"
# Build pony installation
echo "Building ponyc installation..."
make install prefix=${BUILD_PREFIX} default_pic=${PIC} arch=${ARCH} \
-j${MAKE_PARALLELISM} -f Makefile-lib-llvm symlink=no use=llvm_link_static \
-j${MAKE_PARALLELISM} -f Makefile-lib-llvm symlink=no \
version="${PONY_VERSION}"

# Package it all up
Expand Down
2 changes: 1 addition & 1 deletion .ci-scripts/x86-64-unknown-linux-gnu-release.bash
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ ASSET_DESCRIPTION="https://github.com/ponylang/ponyc"
# Build pony installation
echo "Building ponyc installation..."
make install prefix=${BUILD_PREFIX} default_pic=${PIC} arch=${ARCH} \
-j${MAKE_PARALLELISM} -f Makefile-lib-llvm symlink=no use=llvm_link_static
-j${MAKE_PARALLELISM} -f Makefile-lib-llvm symlink=no

# Package it all up
echo "Creating .tar.gz of ponyc installation..."
Expand Down
4 changes: 2 additions & 2 deletions .ci-scripts/x86-64-unknown-linux-musl-nightly.bash
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ ASSET_DESCRIPTION="https://github.com/ponylang/ponyc"

# Build pony installation
echo "Building ponyc installation..."
make install prefix=${BUILD_PREFIX} default_pic=${PIC} arch=${ARCH} \
-j${MAKE_PARALLELISM} -f Makefile-lib-llvm symlink=no use=llvm_link_static \
make install prefix=${BUILD_PREFIX} default_pic=${PIC} arch=${ARCH}\
link=static -j${MAKE_PARALLELISM} -f Makefile-lib-llvm symlink=no \
version="${PONY_VERSION}"

# Package it all up
Expand Down
2 changes: 1 addition & 1 deletion .ci-scripts/x86-64-unknown-linux-musl-release.bash
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ ASSET_DESCRIPTION="https://github.com/ponylang/ponyc"
# Build pony installation
echo "Building ponyc installation..."
make install prefix=${BUILD_PREFIX} default_pic=${PIC} arch=${ARCH} \
-j${MAKE_PARALLELISM} -f Makefile-lib-llvm symlink=no use=llvm_link_static
link=static -j${MAKE_PARALLELISM} -f Makefile-lib-llvm symlink=no

# Package it all up
echo "Creating .tar.gz of ponyc installation..."
Expand Down
8 changes: 4 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ jobs:
user: pony
steps:
- checkout
- run: make -f Makefile-lib-llvm all config=debug default_pic=true staticbuild=true -j3
- run: make -f Makefile-lib-llvm test-ci config=debug default_pic=true staticbuild=true
- run: make -f Makefile-lib-llvm all config=debug default_pic=true link=static -j3
- run: make -f Makefile-lib-llvm test-ci config=debug default_pic=true link=static
- zulip/status:
fail_only: true

Expand All @@ -86,8 +86,8 @@ jobs:
user: pony
steps:
- checkout
- run: make -f Makefile-lib-llvm all config=release default_pic=true staticbuild=true -j3
- run: make -f Makefile-lib-llvm test-ci config=release default_pic=true staticbuild=true
- run: make -f Makefile-lib-llvm all config=release default_pic=true link=static -j3
- run: make -f Makefile-lib-llvm test-ci config=release default_pic=true link=static
- zulip/status:
fail_only: true

Expand Down
6 changes: 3 additions & 3 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ task:
test_script:
- cd ponyc
- echo -e "\e[44m***** Building debug ponyc - includes building LLVM"
- make -f Makefile-lib-llvm default_pic=true arch=x86-64 use=llvm_link_static config=debug -j8
- make -f Makefile-lib-llvm default_pic=true arch=x86-64 use=llvm_link_static config=debug test-ci
- make -f Makefile-lib-llvm default_pic=true arch=x86-64 config=debug -j8
- make -f Makefile-lib-llvm default_pic=true arch=x86-64 config=debug test-ci
- echo -e "\e[44m***** Cleaning ponyc build in prep for release build tests"
- make config=debug clean
- echo -e "\e[44m***** Building release ponyc"
- make -f Makefile-lib-llvm default_pic=true arch=x86-64 use=llvm_link_static config=release test-ci
- make -f Makefile-lib-llvm default_pic=true arch=x86-64 config=release test-ci

only_if: $CIRRUS_BRANCH != 'master' && $CIRRUS_BRANCH != 'release'

Expand Down
2 changes: 1 addition & 1 deletion .dockerhub/alpine/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ RUN apk update \
&& apk add --update \
alpine-sdk \
binutils-gold \
llvm${LLVM_VERSION} \
llvm${LLVM_VERSION}-static \
llvm${LLVM_VERSION}-dev \
libexecinfo-dev \
coreutils \
Expand Down
4 changes: 2 additions & 2 deletions .packaging/rpm/ponyc.spec
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

%if 0%{?el7}
%global arch_build_args arch=x86-64 tune=generic
%global extra_build_args use="llvm_link_static" LLVM_CONFIG=/usr/lib64/llvm3.9/bin/llvm-config
%global extra_build_args LLVM_CONFIG=/usr/lib64/llvm3.9/bin/llvm-config
%else
%if %{?_vendor} != suse
%global extra_build_args LLVM_CONFIG=/usr/lib64/llvm3.9/bin/llvm-config
%global extra_build_args link=llvm-dynamic LLVM_CONFIG=/usr/lib64/llvm3.9/bin/llvm-config
%endif
%endif

Expand Down
2 changes: 1 addition & 1 deletion .travis_script.bash
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ then

"freebsd11-x86_64")
date
docker run --rm -u pony:2000 -v $(pwd):/home/pony ponylang/ponyc-ci:cross-llvm-3.9.1-freebsd11-x86_64 make arch=x86-64 config=${config} verbose=1 CC=clang CXX=clang++ CFLAGS="-target x86_64-unknown-freebsd11.1 --sysroot=/opt/cross-freebsd-11/ -isystem /opt/cross-freebsd-11/usr/local/llvm39/include/" CXXFLAGS="-target x86_64-unknown-freebsd11.1 --sysroot=/opt/cross-freebsd-11/ -isystem /opt/cross-freebsd-11/usr/local/llvm39/include/" LDFLAGS="-target x86_64-unknown-freebsd11.1 --sysroot=/opt/cross-freebsd-11/ -isystem /opt/cross-freebsd-11/usr/local/llvm39/include/ -L/opt/cross-freebsd-11/usr/local/llvm39/lib" OSTYPE=bsd use="llvm_link_static" CROSS_SYSROOT=/opt/cross-freebsd-11 -j$(nproc)
docker run --rm -u pony:2000 -v $(pwd):/home/pony ponylang/ponyc-ci:cross-llvm-3.9.1-freebsd11-x86_64 make arch=x86-64 config=${config} verbose=1 CC=clang CXX=clang++ CFLAGS="-target x86_64-unknown-freebsd11.1 --sysroot=/opt/cross-freebsd-11/ -isystem /opt/cross-freebsd-11/usr/local/llvm39/include/" CXXFLAGS="-target x86_64-unknown-freebsd11.1 --sysroot=/opt/cross-freebsd-11/ -isystem /opt/cross-freebsd-11/usr/local/llvm39/include/" LDFLAGS="-target x86_64-unknown-freebsd11.1 --sysroot=/opt/cross-freebsd-11/ -isystem /opt/cross-freebsd-11/usr/local/llvm39/include/ -L/opt/cross-freebsd-11/usr/local/llvm39/lib" OSTYPE=bsd CROSS_SYSROOT=/opt/cross-freebsd-11 -j$(nproc)
date
download_vagrant
qemu-system-x86_64 --version
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ All notable changes to the Pony compiler and standard library will be documented

- `--ponythreads` has been renamed to `--ponymaxthreads` ([PR #3334](https://github.com/ponylang/ponyc/pull/3334))
- All `--pony*` options that accept a value, will be checked for minimal values ([PR #3303](https://github.com/ponylang/ponyc/pull/3317))
- Default to statically linking LLVM into ponyc ([PR #3355](https://github.com/ponylang/ponyc/pull/3355))

## [0.32.0] - 2019-09-29

Expand Down
5 changes: 4 additions & 1 deletion Makefile-lib-llvm
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ help:
@echo ' llvm_target=Target Make llvm where Target is one of:'
@echo ' all (default if not specified)'
@echo ' rebuild'
@echo ' link=XXX ponyc linking strategy'
@echo ' static (completely static only works with musl)'
@echo ' llvm-static (default - statically link LLVM)'
@echo ' llvm-dynamic (dynamically link LLVM)'
@sh $(pony_lib_llvm_dir)/llvm-options.sh
@echo
@echo 'USE OPTIONS:'
Expand All @@ -109,7 +113,6 @@ help:
@echo ' actor_continuations'
@echo ' coverage'
@echo ' scheduler_scaling_pthreads'
@echo ' llvm_link_static'
@echo
@echo 'TARGETS:'
@echo ' libponyc Pony compiler library'
Expand Down
79 changes: 38 additions & 41 deletions Makefile-ponyc
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,11 @@ tune ?= generic
cpu ?= $(arch)
fpu ?=
bits ?= $(shell getconf LONG_BIT)
static ?= false

# Set static building if requested
ifdef static
ifeq (,$(filter $(static), true false))
$(error static must be true or false)
endif
endif

ifeq ($(static),true)
use += llvm_link_static
endif
# linking strategy (static, llvm-static, llvm-dynamic)
# static links everything statically (only works with musl libc)
# llvm-static links llvm statically
# llvm-dynamic links llvm dynamically
link ?= llvm-static

ifndef verbose
SILENT = @
Expand Down Expand Up @@ -163,6 +156,28 @@ ifneq ($(fpu),)
LINKER_FLAGS += -mfpu=$(fpu)
endif

ifdef link
ifeq (,$(filter $(link),static llvm-static llvm-dynamic))
$(error Unknown linking strategy "$(link)")
endif
endif

ifneq (,$(filter $(link),static llvm-static))
LLVM_LINKING =--link-static
LINKER_FLAGS += -static-libstdc++
ifneq (,$(shell $(CC) -v 2>&1 | grep gcc))
LINKER_FLAGS += -static-libgcc
endif
$(info "linking llvm statically")
else ifeq ($(link),llvm-dynamic)
ifneq ($(LLVM_VENDOR),true)
LLVM_LINKING =--link-shared
$(info "linking llvm dynamically")
else
$(error "Can't use llvm-dynamic with vendored LLVM at this time")
endif
endif

PONY_BUILD_DIR ?= build/$(config)
PONY_SOURCE_DIR ?= src
PONY_TEST_DIR ?= test
Expand Down Expand Up @@ -225,17 +240,6 @@ define USE_CHECK
else ifeq ($1,scheduler_scaling_pthreads)
ALL_CFLAGS += -DUSE_SCHEDULER_SCALING_PTHREADS
PONY_BUILD_DIR := $(PONY_BUILD_DIR)-scheduler_scaling_pthreads
else ifeq ($1,llvm_link_static)
ifeq (,$(LLVM_LINK_STATIC))
LLVM_LINK_STATIC=--link-static
LINKER_FLAGS += -static-libstdc++
ifneq (,$(shell $(CC) -v 2>&1 | grep gcc))
LINKER_FLAGS += -static-libgcc
endif
$$(info "linking llvm statically")
else
$$(warning LLVM_LINK_STATIC already set to '$(LLVM_LINK_STATIC)'; using pre-existing value)
endif
else ifeq ($1,memtrack)
ALL_CFLAGS += -DUSE_MEMTRACK
ALL_CXXFLAGS += -DUSE_MEMTRACK
Expand Down Expand Up @@ -343,23 +347,14 @@ ifneq ($(MAKECMDGOALS),clean)
# (2) the linker flags necessary to link against the prebuilt libraries
# (3) a list of include directories for a set of libraries
# (4) a list of the libraries to link against
llvm.libdir := $(CROSS_SYSROOT)$(subst -L,,$(shell $(LLVM_CONFIG) --ldflags $(LLVM_LINK_STATIC)))
llvm.libdir := $(CROSS_SYSROOT)$(subst -L,,$(shell $(LLVM_CONFIG) --ldflags $(LLVM_LINKING)))
llvm.ldflags := -L$(llvm.libdir)

# Set rpath for ponyc if we're dynamically linking LLVM_VENDOR
ifeq (,$(LLVM_LINK_STATIC))
# We're linking dynamically as "LLVM_LINK_STATIC" is empty.
ifeq ($(LLVM_VENDOR),true)
# LLVM_VENDOR is true, so have linker set rpath.
llvm.ldflags += -Wl,-rpath,$(llvm.libdir)
endif
endif

#$(info llvm.libdir="$(llvm.libdir)")
#$(info llvm.ldflags="$(llvm.ldflags)")

# Get cflags using llvm-config
llvm.get_cflags := $(LLVM_CONFIG) --cflags $(LLVM_LINK_STATIC)
llvm.get_cflags := $(LLVM_CONFIG) --cflags $(LLVM_LINKING)
#$(info llvm.get_cflags="$(llvm.get_cflags)")
llvm.cflags := $(shell sh -c "$(llvm.get_cflags)")
#$(info llvm.cflags="$(llvm.cflags)")
Expand Down Expand Up @@ -406,7 +401,7 @@ ifneq ($(MAKECMDGOALS),clean)
llvm.include = $(shell $(loopit))
#$(info llvm.include="$(llvm.include)")

llvm.libs := $(shell $(LLVM_CONFIG) --libs $(LLVM_LINK_STATIC)) $(shell $(LLVM_CONFIG) --system-libs $(LLVM_LINK_STATIC))
llvm.libs := $(shell $(LLVM_CONFIG) --libs $(LLVM_LINKING)) $(shell $(LLVM_CONFIG) --system-libs $(LLVM_LINKING))
endif

compiler_version := "$(shell $(CC) --version | sed -n 1p)"
Expand Down Expand Up @@ -563,7 +558,7 @@ ifneq ($(ALPINE),)
endif

# link statically
ifeq (true,$(static))
ifeq ($(link),static)
libponyrt.tests.linkoptions += -static
endif

Expand All @@ -588,7 +583,7 @@ endif

# link statically
# TODO: uncomment when this is fixed
#ifeq (true,$(static))
#ifeq ($(link),static)
# libponyc.tests.linkoptions += -static
#endif

Expand All @@ -608,7 +603,7 @@ ifneq ($(ALPINE),)
endif

# link statically
ifeq (true,$(static))
ifeq ($(link),static)
libponyc.benchmarks.linkoptions += -static
libponyrt.benchmarks.linkoptions += -static
endif
Expand All @@ -623,7 +618,7 @@ ifneq ($(ALPINE),)
endif

# link statically
ifeq (true,$(static))
ifeq ($(link),static)
ponyc.linkoptions += -static
endif

Expand Down Expand Up @@ -1150,15 +1145,17 @@ help:
@echo 'options:'
@echo ' arch=Name Architecture if Name not specified then host name'
@echo ' default_pic=true Make --pic the default'
@echo ' static=true Link ponyc statically'
@echo ' link=XXX ponyc linking strategy'
@echo ' static (completely static only works with musl)'
@echo ' llvm-static (statically link LLVM)'
@echo ' llvm-dynamic (dynamically link LLVM)'
@echo
@echo 'USE OPTIONS:'
@echo ' valgrind'
@echo ' pooltrack'
@echo ' dtrace'
@echo ' actor_continuations'
@echo ' coverage'
@echo ' llvm_link_static'
@echo ' scheduler_scaling_pthreads'
@echo ' thread_sanitizer'
@echo ' address_sanitizer'
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,9 @@ When building ponyc from sources the LLVM installed on your system is used by de

### Instructions:

To compile Pony using LLVM sources on Linux add `-f Makefile-lib-llvm` to any of the examples below. For instance on Ubuntu the standard command line is simply `make`, to build ponyc using LLVM from sources the command line is `make -f Makefile-lib-llvm use=llvm_link_static`. Alternatively you can create a symlink from Makefile to Makefile-lib-llvm, `ln -sf Makefile-lib-llvm Makefile`, and no changes would be needed to the commands. You can specify `llvm_target=llvm-6.0.0` on the command line and those sources will be used. For example `make -f Makefile-lib-llvm llvm_target=llvm-6.0.0 use=llvm_link_static`.
To compile Pony using LLVM sources on Linux add `-f Makefile-lib-llvm` to any of the examples below. For instance on Ubuntu the standard command line is simply `make`, to build ponyc using LLVM from sources the command line is `make -f Makefile-lib-llvm`. Alternatively you can create a symlink from Makefile to Makefile-lib-llvm, `ln -sf Makefile-lib-llvm Makefile`, and no changes would be needed to the commands. You can specify `llvm_target=llvm-6.0.0` on the command line and those sources will be used. For example `make -f Makefile-lib-llvm llvm_target=llvm-6.0.0`.

Typically you only need to build the LLVM sources once, as the `make clean` target does not cause the LLVM sources to be rebuilt. To rebuild everything use `make -f Makefile-lib-llvm clean-all && make -f Makefile-lib-llvm use=llvm_link_static`. There is also a distclean target, `make -f Makefle-lib-llvm distclean`, which will remove the llvm sources and they will be retrieved from the ponylang/llvm repo.
Typically you only need to build the LLVM sources once, as the `make clean` target does not cause the LLVM sources to be rebuilt. To rebuild everything use `make -f Makefile-lib-llvm clean-all && make -f Makefile-lib-llvm`. There is also a distclean target, `make -f Makefle-lib-llvm distclean`, which will remove the llvm sources and they will be retrieved from the ponylang/llvm repo.

NOTE: If LLVM version < 5.0.0 is used, cpu feature `avx512f` is disabled automagically to avoid [LLVM bug 30542](https://bugs.llvm.org/show_bug.cgi?id=30542) otherwise the compiler crashes during the optimization phase.

Expand All @@ -338,7 +338,7 @@ cd ../../../
#### Debug/test ....
Now build and test using `LLVM_CFG=llvm-default.cfg` and any other appropriate parameters:
```
make -j12 LLVM_CFG=llvm-default.cfg default_pic=true use=llvm_link_static -f Makefile-lib-llvm
make -j12 LLVM_CFG=llvm-default.cfg default_pic=true -f Makefile-lib-llvm
```
When satisfied create a commit pushing to your repo:
```
Expand Down Expand Up @@ -558,7 +558,7 @@ scl enable llvm-toolset-7 bash

```bash
cd ~/ponyc/
make use="llvm_link_static"
make
./build/release/ponyc examples/helloworld
./helloworld
```
Expand Down Expand Up @@ -605,7 +605,7 @@ make
Install build tools/dependencies:

```bash
apk add --update alpine-sdk binutils-gold llvm3.9 llvm3.9-dev \
apk add --update alpine-sdk binutils-gold llvm3.9-static llvm3.9-dev \
libexecinfo-dev coreutils linux-headers zlib-dev ncurses-dev
```

Expand Down

0 comments on commit a4dc299

Please sign in to comment.