@@ -1,3 +1,13 @@
test-ci-lib-llvm: &test-ci-lib-llvm
name: Run make lib-llvm
command: |
# When testing override CPUs in command line, such as:
# $ circleci build -e CPUs=11 --job ubuntu-debug
echo 'if [ "$CPUs" == "" ]; then cnt=$(nproc); if (( $cnt >= 4 )); then (( cnt=$cnt / 4 )); else cnt=1; fi; export CPUs=$cnt; fi;' >> $BASH_ENV
source $BASH_ENV
echo "make-llvm: CPUs=$CPUs test_ci_params='$test_ci_params'"
make -f Makefile-lib-llvm test-ci -j$CPUs $test_ci_params
version: 2
jobs:
verify-changelog:
@@ -19,6 +29,8 @@ jobs:
steps:
- checkout
- run: find . -name '*.bash' -exec shellcheck {} \;

# Jobs for building and testing with the system installed llvm
llvm-600-debug:
docker:
- image: ponylang/ponyc-ci:llvm-6.0.0
@@ -110,6 +122,125 @@ jobs:
steps:
- checkout
- run: make test-ci config=release default_pic=true use="llvm_link_static"
ubuntu-18.04-system-llvm-debug:
docker:
- image: ponylang/ponyc-ci:ubuntu-18.04
user: pony
steps:
- checkout
- run: make test-ci config=debug default_pic=true default_ssl=openssl_1.1.0
ubuntu-18.04-system-llvm-release:
docker:
- image: ponylang/ponyc-ci:ubuntu-18.04
user: pony
steps:
- checkout
- run: make test-ci config=release default_pic=true default_ssl=openssl_1.1.0

# Jobs for building and testing with ponyc vendor lib/llvm
ubuntu-default:
docker:
- image: ponylang/ponyc-ci:ubuntu
user: pony
steps:
- checkout
- run: *test-ci-lib-llvm
ubuntu-debug:
docker:
- image: ponylang/ponyc-ci:ubuntu
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=debug default_pic=true"' >> $BASH_ENV
- run: *test-ci-lib-llvm
ubuntu-release:
docker:
- image: ponylang/ponyc-ci:ubuntu
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=release default_pic=true"' >> $BASH_ENV
- run: *test-ci-lib-llvm
ubuntu-18.04-debug:
docker:
- image: ponylang/ponyc-ci:ubuntu-18.04
user: pony
steps:
- checkout
- run: echo 'export CC=clang CXX=clang++ test_ci_params="config=debug default_pic=true default_ssl=openssl_1.1.0"' >> $BASH_ENV
- run: *test-ci-lib-llvm
ubuntu-18.04-release:
docker:
- image: ponylang/ponyc-ci:ubuntu-18.04
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=release default_pic=true default_ssl=openssl_1.1.0"' >> $BASH_ENV
- run: *test-ci-lib-llvm
ubuntu-openssl-110-debug:
docker:
- image: ponylang/ponyc-ci:ubuntu-openssl-110
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=debug default_pic=true default_ssl=openssl_1.1.0"' >> $BASH_ENV
- run: *test-ci-lib-llvm
ubuntu-openssl-110-release:
docker:
- image: ponylang/ponyc-ci:ubuntu-openssl-110
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=release default_pic=true default_ssl=openssl_1.1.0"' >> $BASH_ENV
- run: *test-ci-lib-llvm
ubuntu-llvm-600-debug:
docker:
- image: ponylang/ponyc-ci:ubuntu
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=debug default_pic=true llvm_proj=llvm-6.0.0"' >> $BASH_ENV
- run: *test-ci-lib-llvm
ubuntu-llvm-600-release:
docker:
- image: ponylang/ponyc-ci:ubuntu
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=release default_pic=true llvm_proj=llvm-6.0.0"' >> $BASH_ENV
- run: *test-ci-lib-llvm
alpine-debug:
docker:
- image: ponylang/ponyc-ci:alpine
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=debug default_pic=true"' >> $BASH_ENV
- run: *test-ci-lib-llvm
alpine-release:
docker:
- image: ponylang/ponyc-ci:alpine
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=release default_pic=true"' >> $BASH_ENV
- run: *test-ci-lib-llvm
centos7-debug:
docker:
- image: ponylang/ponyc-ci:centos7
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=debug default_pic=true use=llvm_link_static"' >> $BASH_ENV
- run: *test-ci-lib-llvm
centos7-release:
docker:
- image: ponylang/ponyc-ci:centos7
user: pony
steps:
- checkout
- run: echo 'export test_ci_params="config=release default_pic=true use=llvm_link_static"' >> $BASH_ENV
- run: *test-ci-lib-llvm

workflows:
version: 2
@@ -118,6 +249,8 @@ workflows:
- verify-changelog
- validate-shell-scripts
- validate-docker-image-builds

# Run jobs building and testing with the system installed llvm
- llvm-600-debug
- llvm-600-release
- llvm-501-debug
@@ -131,3 +264,26 @@ workflows:
- alpine-llvm-391-release
- centos7-llvm-391-debug
- centos7-llvm-391-release
- ubuntu-18.04-system-llvm-debug
- ubuntu-18.04-system-llvm-release

# Jobs for building and testing with ponyc vendor lib/llvm
- ubuntu-llvm-600-debug
- ubuntu-llvm-600-release
- ubuntu-debug
- ubuntu-release
- ubuntu-18.04-debug
- ubuntu-18.04-release
- ubuntu-openssl-110-debug
- ubuntu-openssl-110-release
- centos7-debug
- centos7-release

# Alpine debug and release don't work because alpine linux
# patches llvm to make it work with musl c library.
# I've done preliminary testing using the patches found
# in the alpine aport repsitory but they don't apply cleanly.
# Apparently there version of llvm 3.9.1 is slightly different
# from what we have. For now skipping testing them.
#- alpine-debug
#- alpine-release
@@ -0,0 +1,4 @@
[submodule "lib/llvm/src"]
path = lib/llvm/src
url = https://github.com/winksaville/llvm.git
branch = release_39
1,084 Makefile

This file was deleted.

Oops, something went wrong.
@@ -0,0 +1,131 @@
# This makefile invokes lib/llvm/Makefile before invoking Makefile-ponyc.
# The reason for doing this is that Makefile-ponyc requires llvm-config to
# be present before it is invoked, thus the need to build lib/llvm/Makefile
# first.
#
# The default target of this makefile builds llvm defined by the submodule,
# which is currently llvm-3.9.1. You may also build lvm-6.0.0 by using
# llvm_proj=llvm-6.0.0. In addition, if you specify llvm_proj=llvm-current
# then lib/llvm/src will not be altered but will be built.
#
# In the future compiling lib/llvm will be incorporated into Makefile
# and Makefile-lib-llvm will be removed.

root_dir := $(shell pwd)
llvm_dir := $(root_dir)/lib/llvm
llvm_proj :=

pony_lib_llvm := $(llvm_dir)
llvm_config := $(pony_lib_llvm)/dist/bin/llvm-config
llvm_build_type := LLVM_BUID_TYPE=Debug
new_path := $(pony_lib_llvm)/dist/bin:$(PATH)

pony_targets := libponyc libponyrt libponyrt-pic libponyc.tests libponyrt.tests libponyc.benchmarks
pony_targets += libponyrt.benchmarks ponyc benchmark install uninstall stats test all
pony_targets += stdlib test-stdlib stdlib-debug test-stdlib-debug test-examples test-ci docs-online

.PHONY: $(pony_targets)
$(pony_targets): $(llvm_config)
@PATH=$(new_path) $(MAKE) -f Makefile-ponyc LLVM_CONFIG=$(llvm_config) $(MAKECMDGOALS) $(MAKEFLAGS)

$(llvm_config):
@$(MAKE) -C $(pony_lib_llvm) $(llvm_build_type) $(llvm_proj)

# Clean is needed otherwise the rebuild of llvm won't be linked
.PHONY: rebuild
rebuild: clean
@$(MAKE) -C $(pony_lib_llvm) $(llvm_build_type) rebuild
@PATH=$(new_path) $(MAKE) -f Makefile-ponyc LLVM_CONFIG=$(llvm_config) $(MAKEFLAGS)

# Clean is needed otherwise the rebuild of llvm won't be linked
.PHONY: rebuild-test
rebuild-test: clean
@$(MAKE) -C $(pony_lib_llvm) $(llvm_build_type) rebuild
@PATH=$(new_path) $(MAKE) -f Makefile-ponyc LLVM_CONFIG=$(llvm_config) test $(MAKEFLAGS)

# Rebuild and then run some tests as passed in the command line parameter gtest_filter.
# Note, the clean is needed otherwise the rebuild of llvm won't be linked.
#
# For example:
# $ time CC=clang CXX=clang++ make -j10 -f Makefile-lib-llvm \
# verbose=1 config=debug default_pic=true default_ssl=openssl_1.1.0 llvm_proj=llvm-current rebuild-some-tests \
# gtest_filter=--gtest_filter=CodegenOptimisationTest.MergeSendMessageReordering 2>&1 | tee clang-rebuild-some-tests.txt
.PHONY: rebuild-some-tests
rebuild-some-tests: clean
@$(MAKE) -C $(pony_lib_llvm) $(llvm_build_type) rebuild
@PATH=$(new_path) $(MAKE) -f Makefile-ponyc LLVM_CONFIG=$(llvm_config) $(MAKEFLAGS)
@$(MAKE) -f Makefile-lib-llvm some-tests

# Run the some passing gtest_filter on command line, for example:
# make -f Makefile-lib-llvm some-tests gtest_filter=--gtest_filter=CodegenOptimisationTest.MergeSendMessageReordering
.PHONY: some-tests
some-tests:
@PATH=$(new_path) ./build/debug/libponyc.tests $(gtest_filter)

# Clean just ponyc
.PHONY: clean
clean:
@PATH=$(new_path) $(MAKE) -f Makefile-ponyc clean

# Clean ponyc and lib/llvm
.PHONY: clean-all
clean-all: clean
@$(MAKE) -C lib/llvm clean

# Clean ponyc and distclean llvm
.PHONY: distclean
distclean: clean
@$(MAKE) -C lib/llvm distclean

.PHONY: help
help:
@echo 'Usage: make [config=name] [arch=name] [use=opt,...] [target]'
@echo
@echo 'CONFIGURATIONS:'
@echo ' debug'
@echo ' release (default)'
@echo
@echo 'ARCHITECTURE:'
@echo ' native (default)'
@echo ' [any compiler supported architecture]'
@echo
@echo 'Compile time default options:'
@echo ' default_pic=true Make --pic the default'
@echo ' default_ssl=Name Make Name the default ssl version'
@echo ' where Name is one of:'
@echo ' openssl_0.9.0 (default)'
@echo ' openssl_1.1.0'
@echo ' llvm_proj=Proj Make llvm where Proj is one of:'
@echo ' llvm-3.9.1 (default if not specified)'
@echo ' llvm-6.0.0'
@echo ' llvm-current'
@echo
@echo 'USE OPTIONS:'
@echo ' valgrind'
@echo ' pooltrack'
@echo ' dtrace'
@echo ' actor_continuations'
@echo ' coverage'
@echo ' scheduler_scaling_pthreads'
@echo ' llvm_link_static'
@echo
@echo 'TARGETS:'
@echo ' libponyc Pony compiler library'
@echo ' libponyrt Pony runtime'
@echo ' libponyrt-pic Pony runtime -fpic'
@echo ' libponyc.tests Test suite for libponyc'
@echo ' libponyrt.tests Test suite for libponyrt'
@echo ' libponyc.benchmarks Benchmark suite for libponyc'
@echo ' libponyrt.benchmarks Benchmark suite for libponyrt'
@echo ' ponyc Pony compiler executable'
@echo
@echo ' all Build all of the above (default)'
@echo ' test Run test suite'
@echo ' benchmark Build and run benchmark suite'
@echo ' install Install ponyc'
@echo ' uninstall Remove all versions of ponyc'
@echo ' stats Print Pony cloc statistics'
@echo ' clean Delete all build files but nothing in $(llvm_dir)'
@echo ' clean-all clean plus clean $(llvm_dir)'
@echo ' distclean clean plus distclean $(llvm_dir)'
@echo

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -245,9 +245,15 @@ First of all, you need a compiler with decent C11 support. The following compile
- MSVC >= 2015
- XCode Clang >= 6.0

Pony requires LLVM version 3.9.1.
When building from sources by default Pony uses LLVM as installed in you system or you may also build LLVM from sources. In either case the supported version of LLVM is 3.9.1 with experimental support for version 6.0.0. Versions other than LLVM 3.9.1 may result in decreased performance or crashes in generated applications.

There is experimental support for building with LLVM 4.0.1, 5.0.1 or 6.0.0, but this may result in decreased performance or crashes in generated applications.
To build the LLVM sources:

- git >= 2.17 to compile LLVM from sources, other versions may work but this is what has been tested.

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 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_proj=llvm-6.0.0` on the command line and those sources will be used. For example `make -f Makefile-lib-llvm llvm_proj=llvm-6.0.0`.

Typically you only need to build the LLVM sources once so 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`.
NOTE: If LLVM version < 5.0.0 is used, cpu feature `avx512f` is diabled automagically to avoid [LLVM bug 30542](https://bugs.llvm.org/show_bug.cgi?id=30542) otherwise the compiler crashes during the optimization phase.
@@ -275,7 +281,7 @@ To build ponyc and compile and helloworld:

```bash
cd ~/ponyc/
make default_pic=true default_ssl='openssl_1.1.0'
make default_pic=true default_ssl=openssl_1.1.0
./build/release/ponyc examples/helloworld
./helloworld
```
@@ -0,0 +1,5 @@
/build/
/dist/
/built-*
/installed-*
/get-*
@@ -0,0 +1,149 @@
# Build llvm library
#
# If target (aka. MAKECMDGOALS) is empty then llvm-default
# is assumed.
#
# A valid target is:
# clean
# distclean
# llvm-6.0.0
# llvm-3.9.1
# llvm-default
# llvm-current
#
# clean: Remove build/ and dist/
# distclean: remove build/, dist/ and src/
# llvm-6.0.0: Get, Build, Install llvm-6.0.0
# llvm-3.9.1: Get, Build, Install llvm-3.9.1
# llvm-default: Get, Build, Install the default which is llvm-3.9.1
# llvm-current: Build, Install what ever is in src/
#
# In the above Get, Build and Install are conditional
# based on a file created if the operation was previously
# successful.
#
# Based on [yurydelendik wasmllvm](https://gist.github.com/yurydelendik/4eeff8248aeb14ce763e)

ROOT_DIR := $(shell pwd)
LLVM_URL := https://github.com/ponylang/llvm.git

ifeq (,$(MAKECMDGOALS))
MAKECMDGOALS := llvm-default
endif

#$(warning MAKECMDGOALS=$(MAKECMDGOALS))

ifeq ($(MAKECMDGOALS),rebuild)
LLVM_PROJ := llvm-current
GET_LLVM_SRC_TARGET := get-nothing
LLVM_SRC_DEPTH :=
LLVM_BRANCH :=
else ifeq ($(MAKECMDGOALS),clean)
# Nothing to init
else ifeq ($(MAKECMDGOALS),distclean)
# Nothing to init
else ifeq ($(MAKECMDGOALS),llvm-6.0.0)
LLVM_PROJ := llvm-6.0.0
GET_LLVM_SRC_TARGET := get-llvm-src-$(LLVM_PROJ)
LLVM_SRC_DEPTH := --depth=1
LLVM_BRANCH := -b release_60
else ifeq ($(MAKECMDGOALS),llvm-3.9.1)
LLVM_PROJ := llvm-3.9.1
GET_LLVM_SRC_TARGET := get-llvm-src-$(LLVM_PROJ)
LLVM_SRC_DEPTH := --depth=1
LLVM_BRANCH := -b release_39
else ifeq ($(MAKECMDGOALS),llvm-current)
LLVM_PROJ := llvm-current
GET_LLVM_SRC_TARGET := get-nothing
LLVM_SRC_DEPTH :=
LLVM_BRANCH :=
else ifeq ($(MAKECMDGOALS),llvm-default)
LLVM_PROJ := llvm-default
GET_LLVM_SRC_TARGET := get-default-llvm-src
LLVM_SRC_DEPTH := --depth=1
LLVM_URL :=
LLVM_BRANCH :=
else
$(error Uknown target '$(MAKECMDGOALS)', someone did not pass a goal)
endif

LLVM_SRC_DIR := $(ROOT_DIR)/src
LLVM_BUILD_DIR := $(ROOT_DIR)/build

LLVM_BUILD_ENGINE := "Unix Makefiles"
LLVM_BUILD_TYPE := Release
LLVM_INSTALL_DIR := $(ROOT_DIR)/dist

LLVM_LINKER := bfd
ifeq (llvm-3.9.1,$(LLVM_PROJ))
# 3.9.1 doesn't supprot -DLLVM_USE_LINKER so make it empty to supress a warning
LLVM_USE_LINKER=
else
LLVM_USE_LINKER=-DLLVM_USE_LINKER=$(LLVM_LINKER)
endif

ifeq ($(LLVM_BUILD_ENGINE),Ninja)
MAKE := ninja
MAKEFILE := build.ninja
else
MAKE := make
MAKEFILE := Makefile
endif

ifneq (,$(verbose))
VERBOSE_CMAKE := -DCMAKE_VERBOSE_MAKEFILE=true
endif

$(LLVM_PROJ): built-llvm-$(LLVM_PROJ)

.PHONY: rebuild
rebuild: clean-built-installed
@echo building $(LLVM_PROJ) `git -C src log -1 --pretty="format:hash=%h ref=%d subject=%s"`
$(MAKE) -C $(LLVM_BUILD_DIR)
touch built-llvm-$(LLVM_PROJ)
@echo installing $(LLVM_PROJ)
$(MAKE) -C $(LLVM_BUILD_DIR) install
touch installed-llvm-$(LLVM_PROJ)

.PHONY: clean
clean: clean-except-get

.PHONY: distclean
distclean: clean-except-get
rm -rf $(LLVM_SRC_DIR)
rm -f get-*

.PHONY: clean-except-get
clean-except-get: clean-built-installed
rm -rf $(LLVM_BUILD_DIR) $(LLVM_INSTALL_DIR)

.PHONY: clean-built-installed
clean-built-installed:
rm -f built-* installed-*

built-llvm-$(LLVM_PROJ): $(LLVM_BUILD_DIR)/generated-llvm-makefile-$(LLVM_PROJ)
$(MAKE) rebuild

$(LLVM_BUILD_DIR)/generated-llvm-makefile-$(LLVM_PROJ): $(GET_LLVM_SRC_TARGET)
@echo generate $(LLVM_PROJ) `git -C src log -1 --pretty="format:hash=%h ref=%d subject=%s"`
mkdir -p $(LLVM_BUILD_DIR)
cd $(LLVM_BUILD_DIR); cmake -G $(LLVM_BUILD_ENGINE) $(VERBOSE_CMAKE) $(LLVM_USE_LINKER) -DCMAKE_INSTALL_PREFIX=$(LLVM_INSTALL_DIR) -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=$(LLVM_BUILD_TYPE) $(LLVM_SRC_DIR)
touch $(LLVM_BUILD_DIR)/generated-llvm-makefile-$(LLVM_PROJ)

get-nothing: clean

get-default-llvm-src:
@echo get-default-llvm-src
$(MAKE) clean
rm -rf $(LLVM_SRC_DIR)
mkdir $(LLVM_SRC_DIR)
git submodule init
git submodule update $(LLVM_SRC_DEPTH)
touch get-default-llvm-src

get-llvm-src-$(LLVM_PROJ):
@echo get-llvm-src-$(LLVM_PROJ)
$(MAKE) clean
rm -rf $(LLVM_SRC_DIR)
git clone $(LLVM_BRANCH) $(LLVM_SRC_DEPTH) $(LLVM_URL) $(LLVM_SRC_DIR)
touch get-llvm-src-$(LLVM_PROJ)
@@ -0,0 +1,37 @@
# Build llvm TODO: Update for submodule support ....

## Prerequesites
* Gcc 6+
* cmake
* ninja &| make
* gold &| bfd

## Building
Options:
- LLVM_BUILD_ENGINE=<Ninja|"Unix Makefiles"> the type of build to create (default "Unix Makefiles")
- LLVM_BUILD_TYPE=<Release|Debug> the type of build to create (default Release)
- LLVM_INSTALL_DIR=xxx where xxx is the path to the install directory (default ./dist)
- LINKER=<gold|bfd> the linker to use (default bfd)

Build using the defaults as defined by lib/llvm/src submodule:
```
make -j10
```
Example over riding the defaults for building llvm-6.0.0:
```
make llvm-6.0.0 -j12 LLVM_BUILD_ENGINE=Ninja BULID_TYPE=Debug LLVM_INSTALL_DIR=./bin LINKER=gold
```
Building has been tested on a 32G RAM desktop, 16G laptop and a 1G VM. Be careful
using -j for parallel build with the desktop -j10 wasn't a problem but with
the laptop I needed to use -j2 and the tiny VM -j1. YMMV.

## Install
You must use the same LLVM_BUILD_ENGINE and LLVM_INSTALL_DIR as used when building or none if not specified when building
```
make install
```
## Clean
Clean binaries
```
make clean
```
Submodule src added at a093ef