0.3.0; remove files no longer needed

- docs for cli will be part of wren repo for now
- notes and stuff are vm side already
- the rest is unused
This commit is contained in:
underscorediscovery
2020-05-29 11:30:41 -07:00
parent fe186d2ea1
commit 7a6ff13290
98 changed files with 11 additions and 10568 deletions
-93
View File
@@ -1,93 +0,0 @@
#!/usr/bin/env python
# Runs GYP to generate the right project then uses that to build libuv.
from __future__ import print_function
import os
import platform
import shutil
import sys
from util import ensure_dir, python2_binary, run
LIB_UV_VERSION = "v1.10.0"
LIB_UV_DIR = "deps/libuv"
def build_libuv_mac():
# Create the XCode project.
run([
python2_binary(), LIB_UV_DIR + "/gyp_uv.py", "-f", "xcode"
])
# Compile it.
# TODO: Support debug builds too.
run([
"xcodebuild",
# Build a 32-bit + 64-bit universal binary:
"ARCHS=x86_64", "ONLY_ACTIVE_ARCH=NO",
"BUILD_DIR=out",
"-project", LIB_UV_DIR + "/uv.xcodeproj",
"-configuration", "Release",
"-target", "libuv"
])
def build_libuv_linux(arch):
# Set up the Makefile to build for the right architecture.
args = [python2_binary(), "gyp_uv.py", "-f", "make"]
if arch == "-32":
args.append("-Dtarget_arch=ia32")
elif arch == "-64":
args.append("-Dtarget_arch=x64")
run(args, cwd=LIB_UV_DIR)
run(["make", "-C", "out", "BUILDTYPE=Release", "libuv"], cwd=LIB_UV_DIR)
def build_libuv_windows(arch):
args = ["cmd", "/c", "vcbuild.bat", "release", "vs2017"]
if arch == "-32":
args.append("x86")
elif arch == "-64":
args.append("x64")
run(args, cwd=LIB_UV_DIR)
def build_libuv(arch, out):
if platform.system() == "Darwin":
build_libuv_mac()
elif platform.system() == "Linux":
build_libuv_linux(arch)
elif platform.system() == "Windows":
build_libuv_windows(arch)
else:
print("Unsupported platform: " + platform.system())
sys.exit(1)
# Copy the build library to the build directory for Mac and Linux where we
# support building for multiple architectures.
if platform.system() != "Windows":
ensure_dir(os.path.dirname(out))
shutil.copyfile(
os.path.join(LIB_UV_DIR, "out", "Release", "libuv.a"), out)
def main(args):
expect_usage(len(args) >= 1 and len(args) <= 2)
arch = "" if len(args) < 2 else args[1]
out = os.path.join("build", "libuv" + arch + ".a")
build_libuv(arch, out)
def expect_usage(condition):
if (condition): return
print("Usage: build_libuv.py [-32|-64]")
sys.exit(1)
main(sys.argv)
-33
View File
@@ -1,33 +0,0 @@
#!/bin/bash
set -e
# Install the Wren Pygments lexer.
cd util/pygments-lexer
sudo python3 setup.py develop
cd ../..
# Build the docs.
make gh-pages
# Clone the repo at the gh-pages branch.
git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG} gh-pages-repo \
--branch gh-pages --depth 1
cd gh-pages-repo
# Copy them into the gh-pages branch.
rm -rf *
cp -r ../build/gh-pages/* .
# Restore CNAME file that gets deleted by `rm -rf *`.
echo "wren.io" > "CNAME"
git status
ls
if ! $( git diff-index --quiet HEAD ) ; then
git config user.name "Travis CI"
git config user.email "$COMMIT_AUTHOR_EMAIL"
git add --all .
git commit -m "Deploy to GitHub Pages: ${SHA}"
git push
fi
-73
View File
@@ -1,73 +0,0 @@
#!/usr/bin/env python3
import sys
from os.path import basename, dirname, join, realpath, isfile
from glob import iglob
import re
INCLUDE_PATTERN = re.compile(r'^\s*#include "([\w.]+)"')
GUARD_PATTERN = re.compile(r'^#ifndef wren(_\w+)?_h$')
WREN_DIR = dirname(dirname(realpath(__file__)))
seen_files = set()
out = sys.stdout
# Find a file in the different folders of the src dir.
def find_file(filename):
names = [
join(WREN_DIR, 'src', 'include', filename),
join(WREN_DIR, 'src', 'vm', filename),
join(WREN_DIR, 'src', 'optional', filename),
]
for f in names:
if isfile(f):
return f
raise Exception('File "{0}" not found!'.format(filename))
# Prints a plain text file, adding comment markers.
def add_comment_file(filename):
with open(filename, 'r') as f:
for line in f:
out.write('// ')
out.write(line)
# Prints the given C source file, recursively resolving local #includes.
def add_file(filename):
bname = basename(filename)
# Only include each file at most once.
if bname in seen_files:
return
once = False
out.write('// Begin file "{0}"\n'.format(bname))
with open(filename, 'r') as f:
for line in f:
m = INCLUDE_PATTERN.match(line)
if m:
add_file(find_file(m.group(1)))
else:
out.write(line)
if GUARD_PATTERN.match(line):
once = True
out.write('// End file "{0}"\n'.format(bname))
# Only skip header files which use #ifndef guards.
# This is necessary because of the X Macro technique.
if once:
seen_files.add(bname)
# Print license on top.
add_comment_file(join(WREN_DIR, 'LICENSE'))
out.write('\n')
# Source files.
add_file(join(WREN_DIR, 'src', 'include', 'wren.h'))
# Must be included here because of conditional compilation.
add_file(join(WREN_DIR, 'src', 'vm', 'wren_debug.h'))
for f in iglob(join(WREN_DIR, 'src', 'vm', '*.c')):
add_file(f)
for f in iglob(join(WREN_DIR, 'src', 'optional', '*.c')):
add_file(f)
-224
View File
@@ -1,224 +0,0 @@
#!/usr/bin/env python3
import codecs
import glob
import fnmatch
import os
import posixpath
import shutil
import subprocess
import sys
import time
import re
import urllib
from datetime import datetime
from http.server import HTTPServer, SimpleHTTPRequestHandler
import markdown
# Match a "## " style header. We require a space after "#" to avoid
# accidentally matching "#include" in code samples.
MARKDOWN_HEADER = re.compile(r'#+ ')
# Clean up a header to be a valid URL.
FORMAT_ANCHOR = re.compile(r'\?|!|:|/|\*|`')
class RootedHTTPServer(HTTPServer):
"""Simple server that resolves paths relative to a given directory.
From: http://louistiao.me/posts/python-simplehttpserver-recipe-serve-specific-directory/
"""
def __init__(self, base_path, *args, **kwargs):
HTTPServer.__init__(self, *args, **kwargs)
self.RequestHandlerClass.base_path = base_path
class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
"""Simple handler that resolves paths relative to a given directory.
From: http://louistiao.me/posts/python-simplehttpserver-recipe-serve-specific-directory/
"""
def translate_path(self, path):
# Refresh files that are being requested.
format_files(True)
path = posixpath.normpath(urllib.parse.unquote(path))
words = path.split('/')
words = filter(None, words)
path = self.base_path
for word in words:
drive, word = os.path.splitdrive(word)
head, word = os.path.split(word)
if word in (os.curdir, os.pardir):
continue
path = os.path.join(path, word)
return path
def ensure_dir(path):
if not os.path.exists(path):
os.mkdir(path)
def is_up_to_date(path, out_path):
dest_mod = 0
if os.path.exists(out_path):
dest_mod = os.path.getmtime(out_path)
# See if it's up to date.
source_mod = os.path.getmtime(path)
return source_mod < dest_mod
def format_file(path, skip_up_to_date):
in_path = os.path.join('doc/site', path)
out_path = "build/docs/" + os.path.splitext(path)[0] + ".html"
template_path = os.path.join("doc/site", os.path.dirname(path),
"template.html")
if (skip_up_to_date and
is_up_to_date(in_path, out_path) and
is_up_to_date(template_path, out_path)):
# It's up to date.
return
title = ""
# Read the markdown file and preprocess it.
contents = ""
with codecs.open(in_path, "r", encoding="utf-8") as input:
# Read each line, preprocessing the special codes.
for line in input:
stripped = line.lstrip()
indentation = line[:len(line) - len(stripped)]
if stripped.startswith("^"):
command,_,args = stripped.rstrip("\n").lstrip("^").partition(" ")
args = args.strip()
if command == "title":
title = args
else:
print(' '.join(["UNKNOWN COMMAND:", command, args]))
elif MARKDOWN_HEADER.match(stripped):
# Add anchors to the headers.
index = stripped.find(" ")
headertype = stripped[:index]
header = stripped[index:].strip()
anchor = header.lower().replace(' ', '-')
anchor = FORMAT_ANCHOR.sub('', anchor)
contents += indentation + headertype
contents += '{1} <a href="#{0}" name="{0}" class="header-anchor">#</a>\n'.format(anchor, header)
else:
# Forcibly add a space to the end of each line. Works around a bug in
# the smartypants extension that removes some newlines that are needed.
# https://github.com/waylan/Python-Markdown/issues/439
if "//" not in line:
contents = contents + line.rstrip() + ' \n'
else:
# Don't add a trailing space on comment lines since they may be
# output lines which have a trailing ">" which makes the extra space
# visible.
contents += line
html = markdown.markdown(contents, extensions=['def_list', 'codehilite', 'smarty'])
# Use special formatting for example output and errors.
html = html.replace('<span class="c1">//&gt; ', '<span class="output">')
html = html.replace('<span class="c1">//&amp;gt; ', '<span class="output">')
html = html.replace('<span class="c1">//! ', '<span class="error">')
modified = datetime.fromtimestamp(os.path.getmtime(in_path))
mod_str = modified.strftime('%B %d, %Y')
with codecs.open(template_path, encoding="utf-8") as f:
page_template = f.read()
fields = {
'title': title,
'html': html,
'mod': mod_str
}
# Write the html output.
ensure_dir(os.path.dirname(out_path))
with codecs.open(out_path, "w", encoding="utf-8") as out:
out.write(page_template.format(**fields))
print("Built " + path)
def check_sass():
source_mod = os.path.getmtime('doc/site/style.scss')
dest_mod = 0
if os.path.exists('build/docs/style.css'):
dest_mod = os.path.getmtime('build/docs/style.css')
if source_mod < dest_mod:
return
subprocess.call(['sass', 'doc/site/style.scss', 'build/docs/style.css'])
print("Built build/docs/style.css")
def copy_static():
shutil.copy2("doc/site/blog/rss.xml", "build/docs/blog/rss.xml")
for root, dirnames, filenames in os.walk('doc/site/static'):
for filename in filenames:
source = os.path.join(root, filename)
source_mod = os.path.getmtime(source)
dest = os.path.join("build/docs", filename)
dest_mod = 0
if os.path.exists(dest):
dest_mod = os.path.getmtime('build/docs/style.css')
if source_mod < dest_mod:
return
shutil.copy2(source, dest)
print('Copied ' + filename)
def format_files(skip_up_to_date):
check_sass()
for root, dirnames, filenames in os.walk('doc/site'):
for filename in fnmatch.filter(filenames, '*.markdown'):
f = os.path.relpath(os.path.join(root, filename), 'doc/site')
format_file(f, skip_up_to_date)
copy_static()
def run_server():
port = 8000
handler = RootedHTTPRequestHandler
server = RootedHTTPServer("build/docs", ('localhost', port), handler)
print('Serving at port', port)
server.serve_forever()
# Clean the output directory.
if os.path.exists("build/docs"):
shutil.rmtree("build/docs")
ensure_dir("build/docs")
# Process each markdown file.
format_files(False)
# Watch and serve files.
if len(sys.argv) == 2 and sys.argv[1] == '--serve':
run_server()
# Watch files.
if len(sys.argv) == 2 and sys.argv[1] == '--watch':
while True:
format_files(True)
time.sleep(0.3)
+10 -3
View File
@@ -45,7 +45,7 @@ def c_metrics(label, directories):
for source_path in files:
num_files += 1
with open(source_path, "r") as input:
with open(source_path, "r", encoding="utf-8") as input:
for line in input:
num_semicolons += line.count(';')
match = TODO_PATTERN.match(line)
@@ -84,10 +84,17 @@ def wren_metrics(label, directories):
for directory in directories:
for dir_path, dir_names, file_names in os.walk(directory):
for file_name in fnmatch.filter(file_names, "*.wren"):
file_path = os.path.join(dir_path, file_name)
file_path = file_path.replace('\\', '/')
# print(file_path)
num_files += 1
with open(os.path.join(dir_path, file_name), "r") as input:
for line in input:
with open(file_path, "r", encoding="utf-8", newline='', errors='replace') as input:
data = input.read()
lines = re.split('\n|\r\n', data)
for line in lines:
if line.strip() == "":
num_empty += 1
continue
@@ -1,13 +0,0 @@
Metadata-Version: 1.0
Name: Wren
Version: 1.0
Summary:
A Pygments lexer for Wren.
Home-page: UNKNOWN
Author: Robert Nystrom
Author-email: UNKNOWN
License: UNKNOWN
Description-Content-Type: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN
@@ -1,7 +0,0 @@
setup.py
Wren.egg-info/PKG-INFO
Wren.egg-info/SOURCES.txt
Wren.egg-info/dependency_links.txt
Wren.egg-info/entry_points.txt
Wren.egg-info/top_level.txt
wren/__init__.py
@@ -1 +0,0 @@
@@ -1,4 +0,0 @@
[pygments.lexers]
wrenlexer = wren:WrenLexer
@@ -1 +0,0 @@
wren
-18
View File
@@ -1,18 +0,0 @@
"""
A Pygments lexer for Wren.
"""
from setuptools import setup
__author__ = 'Robert Nystrom'
setup(
name='Wren',
version='1.0',
description=__doc__,
author=__author__,
packages=['wren'],
entry_points='''
[pygments.lexers]
wrenlexer = wren:WrenLexer
'''
)
-82
View File
@@ -1,82 +0,0 @@
import re
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter
from pygments.lexer import RegexLexer
from pygments.token import *
class WrenLexer(RegexLexer):
name = 'Wren'
aliases = ['wren']
filenames = ['*.wren']
flags = re.MULTILINE | re.DOTALL
tokens = {
'root': [
# Whitespace.
(r'\s+', Text),
(r'[,\\\[\]{}]', Punctuation),
# Push a parenthesized state so that we know the corresponding ')'
# is for a parenthesized expression and not interpolation.
(r'\(', Punctuation, ('parenthesized', 'root')),
# In this state, we don't know whether a closing ')' is for a
# parenthesized expression or the end of an interpolation. So, do
# a non-consuming match and let the parent state (either
# 'parenthesized' or 'interpolation' decide.
(r'(?=\))', Text, '#pop'),
# Keywords.
(r'(break|class|construct|else|for|foreign|if|import|in|is|'
r'return|static|super|var|while)\b', Keyword),
(r'(true|false|null)\b', Keyword.Constant),
(r'this\b', Name.Builtin),
# Comments.
(r'/\*', Comment.Multiline, 'comment'),
(r'//.*?$', Comment.Single),
# Names and operators.
(r'[~!$%^&*\-=+\\|/?<>\.:]+', Operator),
(r'[A-Z][a-zA-Z_0-9]+', Name.Variable.Global),
(r'__[a-zA-Z_0-9]+', Name.Variable.Class),
(r'_[a-zA-Z_0-9]+', Name.Variable.Instance),
(r'[a-z][a-zA-Z_0-9]+', Name),
# Numbers.
(r'\d+\.\d+([eE]-?\d+)?', Number.Float),
(r'0x[0-9a-fA-F]+', Number.Hex),
(r'\d+', Number.Integer),
# Strings.
(r'L?"', String, 'string'),
],
'comment': [
(r'/\*', Comment.Multiline, '#push'),
(r'\*/', Comment.Multiline, '#pop'),
(r'.', Comment.Multiline), # All other characters.
],
'string': [
(r'"', String, '#pop'),
(r'\\[\\%0abfnrtv"\']', String.Escape), # Escape.
(r'\\x[a-fA-F0-9]{2}', String.Escape), # Byte escape.
(r'\\u[a-fA-F0-9]{4}', String.Escape), # Unicode escape.
(r'\\U[a-fA-F0-9]{8}', String.Escape), # Long Unicode escape.
(r'%\(', String.Interpol, ('interpolation', 'root')),
(r'.', String), # All other characters.
],
'parenthesized': [
# We only get to this state when we're at a ')'.
(r'\)', Punctuation, '#pop'),
],
'interpolation': [
# We only get to this state when we're at a ')'.
(r'\)', String.Interpol, '#pop'),
],
}
-73
View File
@@ -1,73 +0,0 @@
#!/usr/bin/env python
# Downloads GYP and libuv into deps/.
#
# Run this manually to update the vendored copies of GYP and libuv that are
# committed in the Wren repo.
from __future__ import print_function
import sys
from util import clean_dir, remove_dir, replace_in_file, run
LIB_UV_VERSION = "v1.10.0"
LIB_UV_DIR = "deps/libuv"
def main(args):
# Delete it if already there so we ensure we get the correct version if the
# version number in this script changes.
clean_dir("deps")
print("Cloning libuv...")
run([
"git", "clone", "--quiet", "--depth=1",
"https://github.com/libuv/libuv.git",
LIB_UV_DIR
])
print("Getting tags...")
run([
"git", "fetch", "--quiet", "--depth=1", "--tags"
], cwd=LIB_UV_DIR)
print("Checking out libuv " + LIB_UV_VERSION + "...")
run([
"git", "checkout", "--quiet", LIB_UV_VERSION
], cwd=LIB_UV_DIR)
# TODO: Pin gyp to a known-good commit. Update a previously downloaded gyp
# if it doesn't match that commit.
print("Downloading gyp...")
run([
"git", "clone", "--quiet", "--depth=1",
"https://chromium.googlesource.com/external/gyp.git",
LIB_UV_DIR + "/build/gyp"
])
# We don't need all of libuv and gyp's various support files.
print("Deleting unneeded files...")
remove_dir("deps/libuv/build/gyp/buildbot")
remove_dir("deps/libuv/build/gyp/infra")
remove_dir("deps/libuv/build/gyp/samples")
remove_dir("deps/libuv/build/gyp/test")
remove_dir("deps/libuv/build/gyp/tools")
remove_dir("deps/libuv/docs")
remove_dir("deps/libuv/img")
remove_dir("deps/libuv/samples")
remove_dir("deps/libuv/test")
# We are going to commit libuv and GYP in the main Wren repo, so we don't
# want them to be their own repos.
remove_dir("deps/libuv/.git")
remove_dir("deps/libuv/build/gyp/.git")
# Libuv's .gitignore ignores GYP, but we want to commit it.
replace_in_file("deps/libuv/.gitignore",
"/build/gyp",
"# /build/gyp (We do want to commit GYP in Wren's repo)")
main(sys.argv)
-77
View File
@@ -1,77 +0,0 @@
# Utility functions used by other Python files in this directory.
from __future__ import print_function
import os
import os.path
import platform
import shutil
import subprocess
import sys
def python2_binary():
"""Tries to find a python 2 executable."""
# Using [0] instead of .major here to support Python 2.6.
if sys.version_info[0] == 2:
return sys.executable or "python"
else:
return "python2"
def clean_dir(dir):
"""If dir exists, deletes it and recreates it, otherwise creates it."""
if os.path.isdir(dir):
remove_dir(dir)
os.makedirs(dir)
def ensure_dir(dir):
"""Creates dir if not already there."""
if os.path.isdir(dir):
return
os.makedirs(dir)
def remove_dir(dir):
"""Recursively removes dir."""
if platform.system() == "Windows":
# rmtree gives up on readonly files on Windows
# rd doesn't like paths with forward slashes
subprocess.check_call(
['cmd', '/c', 'rd', '/s', '/q', dir.replace('/', '\\')])
else:
shutil.rmtree(dir)
def replace_in_file(path, text, replace):
"""Replaces all occurrences of `text` in the file at `path` with `replace`."""
with open(path) as file:
contents = file.read()
contents = contents.replace(text, replace)
with open(path, "w") as file:
file.write(contents)
def run(args, cwd=None):
"""Spawn a process to invoke [args] and mute its output."""
try:
# check_output() was added in Python 2.7.
has_check_output = (sys.version_info[0] > 2 or
(sys.version_info[0] == 2 and sys.version_info[1] >= 7))
if has_check_output:
subprocess.check_output(args, cwd=cwd, stderr=subprocess.STDOUT)
else:
proc = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE)
proc.communicate()[0].split()
except subprocess.CalledProcessError as error:
print(error.output)
sys.exit(error.returncode)
-257
View File
@@ -1,257 +0,0 @@
# Makefile for building a single configuration of Wren. It allows the
# following variables to be passed to it:
#
# MODE - The build mode, "debug" or "release".
# If omitted, defaults to "release".
# LANG - The language, "c" or "cpp".
# If omitted, defaults to "c".
# ARCH - The processor architecture, "32", "64", or nothing, which indicates
# the compiler's default.
# If omitted, defaults to the compiler's default.
#
# It builds a static library, shared library, and command-line interpreter for
# the given configuration. Libraries are built to "lib", and the interpreter
# is built to "bin".
#
# The output file is initially "wren". If in debug mode, "d" is appended to it.
# If the language is "cpp", then "-cpp" is appended to that. If the
# architecture is not the default then "-32" or "-64" is appended to that.
# Then, for the libraries, the correct extension is added.
# Files.
OPT_HEADERS := $(wildcard src/optional/*.h) $(wildcard src/optional/*.wren.inc)
OPT_SOURCES := $(wildcard src/optional/*.c)
CLI_HEADERS := $(wildcard src/cli/*.h)
CLI_SOURCES := $(wildcard src/cli/*.c)
MODULE_HEADERS := $(wildcard src/module/*.h) $(wildcard src/module/*.wren.inc)
MODULE_SOURCES := $(wildcard src/module/*.c)
VM_HEADERS := $(wildcard src/vm/*.h) $(wildcard src/vm/*.wren.inc)
VM_SOURCES := $(wildcard src/vm/*.c)
API_TEST_HEADERS := $(wildcard test/api/*.h)
API_TEST_SOURCES := $(wildcard test/api/*.c)
UNIT_TEST_HEADERS := $(wildcard test/unit/*.h)
UNIT_TEST_SOURCES := $(wildcard test/unit/*.c)
BUILD_DIR := build
# Allows one to enable verbose builds with VERBOSE=1
V := @
ifeq ($(VERBOSE),1)
V :=
endif
C_OPTIONS := $(WREN_CFLAGS)
C_WARNINGS := -Wall -Wextra -Werror -Wno-unused-parameter
# Wren uses callbacks heavily, so -Wunused-parameter is too painful to enable.
# Mode configuration.
ifeq ($(MODE),debug)
WREN := wrend
C_OPTIONS += -O0 -DDEBUG -g
BUILD_DIR := $(BUILD_DIR)/debug
else
WREN += wren
C_OPTIONS += -O3
BUILD_DIR := $(BUILD_DIR)/release
endif
# Language configuration.
ifeq ($(LANG),cpp)
WREN := $(WREN)-cpp
C_OPTIONS += -std=c++98
FILE_FLAG := -x c++
BUILD_DIR := $(BUILD_DIR)-cpp
else
C_OPTIONS += -std=c99
endif
# Architecture configuration.
ifeq ($(ARCH),32)
C_OPTIONS += -m32
WREN := $(WREN)-32
BUILD_DIR := $(BUILD_DIR)-32
LIBUV_ARCH := -32
endif
ifeq ($(ARCH),64)
C_OPTIONS += -m64
WREN := $(WREN)-64
BUILD_DIR := $(BUILD_DIR)-64
LIBUV_ARCH := -64
endif
# Some platform-specific workarounds. Note that we use "gcc" explicitly in the
# call to get the machine name because one of these workarounds deals with $(CC)
# itself not working.
OS := $(lastword $(subst -, ,$(shell gcc -dumpmachine)))
# Don't add -fPIC on Windows since it generates a warning which gets promoted
# to an error by -Werror.
ifeq ($(OS),mingw32)
else ifeq ($(OS),cygwin)
# Do nothing.
else
C_OPTIONS += -fPIC
endif
# MinGW--or at least some versions of it--default CC to "cc" but then don't
# provide an executable named "cc". Manually point to "gcc" instead.
ifeq ($(OS),mingw32)
CC = GCC
endif
# Clang on Mac OS X has different flags and a different extension to build a
# shared library.
ifneq (,$(findstring darwin,$(OS)))
SHARED_EXT := dylib
else
SHARED_LIB_FLAGS := -Wl,-soname,libwren.so
SHARED_EXT := so
# Link in the right libraries needed by libuv on Windows and Linux.
ifeq ($(OS),mingw32)
LIBUV_LIBS := -lws2_32 -liphlpapi -lpsapi -luserenv
else
LIBUV_LIBS := -lpthread -lrt
endif
endif
CFLAGS := $(C_OPTIONS) $(C_WARNINGS)
OPT_OBJECTS := $(addprefix $(BUILD_DIR)/optional/, $(notdir $(OPT_SOURCES:.c=.o)))
CLI_OBJECTS := $(addprefix $(BUILD_DIR)/cli/, $(notdir $(CLI_SOURCES:.c=.o)))
MODULE_OBJECTS := $(addprefix $(BUILD_DIR)/module/, $(notdir $(MODULE_SOURCES:.c=.o)))
VM_OBJECTS := $(addprefix $(BUILD_DIR)/vm/, $(notdir $(VM_SOURCES:.c=.o)))
API_TEST_OBJECTS := $(patsubst test/api/%.c, $(BUILD_DIR)/test/api/%.o, $(API_TEST_SOURCES))
UNIT_TEST_OBJECTS := $(patsubst test/unit/%.c, $(BUILD_DIR)/test/unit/%.o, $(UNIT_TEST_SOURCES))
LIBUV_DIR := deps/libuv
LIBUV := build/libuv$(LIBUV_ARCH).a
# Flags needed to compile source files for the CLI, including the modules and
# API tests.
CLI_FLAGS := -D_XOPEN_SOURCE=600 -Isrc/include -I$(LIBUV_DIR)/include \
-Isrc/cli -Isrc/module
# Targets ---------------------------------------------------------------------
# Builds the VM libraries and CLI interpreter.
all: vm cli
# Builds just the VM libraries.
vm: shared static
# Builds the shared VM library.
shared: lib/lib$(WREN).$(SHARED_EXT)
# Builds the static VM library.
static: lib/lib$(WREN).a
# Builds just the CLI interpreter.
cli: bin/$(WREN)
# Builds the API test executable.
api_test: $(BUILD_DIR)/test/api_$(WREN)
# Builds the unit test executable.
unit_test: $(BUILD_DIR)/test/unit_$(WREN)
# Command-line interpreter.
bin/$(WREN): $(OPT_OBJECTS) $(CLI_OBJECTS) $(MODULE_OBJECTS) $(VM_OBJECTS) \
$(LIBUV)
@ printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS)"
$(V) mkdir -p bin
$(V) $(CC) $(CFLAGS) $^ -o $@ -lm $(LIBUV_LIBS)
# Static library.
lib/lib$(WREN).a: $(OPT_OBJECTS) $(VM_OBJECTS)
@ printf "%10s %-30s %s\n" $(AR) $@ "rcu"
$(V) mkdir -p lib
$(V) $(AR) rcu $@ $^
# Shared library.
lib/lib$(WREN).$(SHARED_EXT): $(OPT_OBJECTS) $(VM_OBJECTS)
@ printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS) $(SHARED_LIB_FLAGS)"
$(V) mkdir -p lib
$(V) $(CC) $(CFLAGS) -shared $(SHARED_LIB_FLAGS) -o $@ $^
# API test executable.
$(BUILD_DIR)/test/api_$(WREN): $(OPT_OBJECTS) $(MODULE_OBJECTS) $(API_TEST_OBJECTS) \
$(VM_OBJECTS) $(BUILD_DIR)/cli/modules.o $(BUILD_DIR)/cli/vm.o \
$(BUILD_DIR)/cli/path.o $(LIBUV)
@ printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS)"
$(V) mkdir -p $(BUILD_DIR)/test/api
$(V) $(CC) $(CFLAGS) $^ -o $@ -lm $(LIBUV_LIBS)
# Unit test executable.
$(BUILD_DIR)/test/unit_$(WREN): $(OPT_OBJECTS) $(MODULE_OBJECTS) $(UNIT_TEST_OBJECTS) \
$(VM_OBJECTS) $(BUILD_DIR)/cli/modules.o $(BUILD_DIR)/cli/vm.o \
$(BUILD_DIR)/cli/path.o $(LIBUV)
@ printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS)"
$(V) mkdir -p $(BUILD_DIR)/test/unit
$(V) $(CC) $(CFLAGS) $^ -o $@
# CLI object files.
$(BUILD_DIR)/cli/%.o: src/cli/%.c $(CLI_HEADERS) $(MODULE_HEADERS) \
$(VM_HEADERS) $(LIBUV)
@ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)"
$(V) mkdir -p $(BUILD_DIR)/cli
$(V) $(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $<
# Module object files.
$(BUILD_DIR)/module/%.o: src/module/%.c $(CLI_HEADERS) $(MODULE_HEADERS) \
$(VM_HEADERS) $(LIBUV)
@ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)"
$(V) mkdir -p $(BUILD_DIR)/module
$(V) $(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $<
# Optional object files.
$(BUILD_DIR)/optional/%.o: src/optional/%.c $(VM_HEADERS) $(OPT_HEADERS)
@ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)"
$(V) mkdir -p $(BUILD_DIR)/optional
$(V) $(CC) -c $(CFLAGS) -Isrc/include -Isrc/vm -o $@ $(FILE_FLAG) $<
# VM object files.
$(BUILD_DIR)/vm/%.o: src/vm/%.c $(VM_HEADERS)
@ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)"
$(V) mkdir -p $(BUILD_DIR)/vm
$(V) $(CC) -c $(CFLAGS) -Isrc/include -Isrc/optional -Isrc/vm -o $@ $(FILE_FLAG) $<
# API test object files.
$(BUILD_DIR)/test/api/%.o: test/api/%.c $(OPT_HEADERS) $(MODULE_HEADERS) \
$(VM_HEADERS) $(API_TEST_HEADERS) $(LIBUV)
@ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)"
$(V) mkdir -p $(dir $@)
$(V) $(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $<
# Unit test object files.
$(BUILD_DIR)/test/unit/%.o: test/unit/%.c $(OPT_HEADERS) $(MODULE_HEADERS) \
$(VM_HEADERS) $(UNIT_TEST_HEADERS) $(LIBUV)
@ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)"
$(V) mkdir -p $(dir $@)
$(V) $(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $<
# Build libuv to a static library.
$(LIBUV):
@ printf "%10s %-30s %s\n" run util/build_libuv.py
$(V) ./util/build_libuv.py $(LIBUV_ARCH)
# Wren modules that get compiled into the binary as C strings.
src/optional/wren_opt_%.wren.inc: src/optional/wren_opt_%.wren util/wren_to_c_string.py
@ printf "%10s %-30s %s\n" str $<
$(V) ./util/wren_to_c_string.py $@ $<
src/vm/wren_%.wren.inc: src/vm/wren_%.wren util/wren_to_c_string.py
@ printf "%10s %-30s %s\n" str $<
$(V) ./util/wren_to_c_string.py $@ $<
src/module/%.wren.inc: src/module/%.wren util/wren_to_c_string.py
@ printf "%10s %-30s %s\n" str $<
$(V) ./util/wren_to_c_string.py $@ $<
.PHONY: all api_test cli unit_test vm