Skip to content

Commit

Permalink
Add amalgamation script
Browse files Browse the repository at this point in the history
Sources are #included instead of inlined by default.
  • Loading branch information
glebm committed Aug 28, 2019
1 parent 9013ce7 commit 5ea4f68
Show file tree
Hide file tree
Showing 8 changed files with 5,533 additions and 2 deletions.
45 changes: 43 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,27 @@ ifneq (Cygwin,$(UNAME))
endif
endif

AMALGAM ?= 0
AMALGAM_INLINE ?= 0
AMALGAM_SOURCE_INCLUDE := build/libsass-amalgam-include.cpp
AMALGAM_SOURCE_INLINE := build/libsass-amalgam-inline.cpp

ifeq (1,$(AMALGAM_INLINE))
AMALGAM_SOURCE := $(AMALGAM_SOURCE_INLINE)
else
AMALGAM_SOURCE := $(AMALGAM_SOURCE_INCLUDE)
endif

AMALGAM_SOURCE_DIR := $(abspath $(dir $(AMALGAM_SOURCE)))

include Makefile.conf
OBJECTS = $(addprefix src/,$(SOURCES:.cpp=.o))
COBJECTS = $(addprefix src/,$(CSOURCES:.c=.o))
ifeq (1,$(AMALGAM))
OBJECTS = $(AMALGAM_SOURCE:.cpp=.o)
COBJECTS =
else
OBJECTS = $(addprefix src/,$(SOURCES:.cpp=.o))
COBJECTS = $(addprefix src/,$(CSOURCES:.c=.o))
endif
RCOBJECTS = $(RESOURCES:.rc=.o)

DEBUG_LVL ?= NONE
Expand All @@ -184,6 +202,7 @@ CLEANUPS += $(RCOBJECTS)
CLEANUPS += $(COBJECTS)
CLEANUPS += $(OBJECTS)
CLEANUPS += $(LIBSASS_LIB)
CLEANUPS += $(AMALGAM_SOURCE_INCLUDE) $(AMALGAM_SOURCE_INLINE)

all: $(BUILD)

Expand All @@ -199,6 +218,28 @@ debug-shared: CFLAGS := -g -DDEBUG -DDEBUG_LVL="$(DEBUG_LVL)" $(filter-out -O2,$
debug-shared: CXXFLAGS := -g -DDEBUG -DDEBUG_LVL="$(DEBUG_LVL)" $(filter-out -O2,$(CXXFLAGS))
debug-shared: shared

AMALGAMATE_BIN := script/amalgamate/build/amalgamate

$(AMALGAMATE_BIN): script/amalgamate/amalgamate.cpp
$(MAKE) -C script/amalgamate build/amalgamate

$(AMALGAM_SOURCE_DIR):
$(MKDIR) $(AMALGAM_SOURCE_DIR)

ifeq (1,$(AMALGAM_INLINE))
AMALGAM_INLINE_FLAG := true
else
AMALGAM_INLINE_FLAG := false
endif

$(AMALGAM_SOURCE): $(AMALGAMATE_BIN) $(addprefix src/,$(SOURCES)) $(addprefix src/,$(CSOURCES)) | $(AMALGAM_SOURCE_DIR)
$(AMALGAMATE_BIN) --out=$(AMALGAM_SOURCE) --inline=$(AMALGAM_INLINE_FLAG)

ifneq (1,$(AMALGAM_INLINE))
$(AMALGAM_SOURCE:.cpp=.o): $(AMALGAM_SOURCE)
$(CXX) $(CXXFLAGS) -I src -c -o $@ $<
endif

lib:
$(MKDIR) lib

Expand Down
1 change: 1 addition & 0 deletions script/amalgamate/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BasedOnStyle: Google
17 changes: 17 additions & 0 deletions script/amalgamate/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CXX ?= c++

CXXFLAGS := -std=c++11
CXXFLAGS_OPT := $(CXXFLAGS) -O2 -s
CXXFLAGS_DBG := $(CXXFLAGS) -fsanitize=address -g -O1 -fno-omit-frame-pointer
CXXFLAGS_FASTBUILD := $(CXXFLAGS) -O0 -s

build/amalgamate: amalgamate.cpp | build
$(CXX) $(CXXFLAGS_FASTBUILD) -o build/amalgamate amalgamate.cpp

build:
@mkdir build

clean: | build
rm -rf build

.PHONY: amalgamate clean
44 changes: 44 additions & 0 deletions script/amalgamate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# LibSass amalgamation script

This script concatenates LibSass sources into a single file.

This reduces single-core compilation time by 50% and the output shared library size by 10%.

SQLite has a great writeup on amalgamation here:
<https://www.sqlite.org/amalgamation.html>.

## Options

* `--inline`. Default: `false`\
When `true`, all sources are inlined into the amalgam file (including headers.\
When `false`, the amalgam file instead contains `#include` statements for each `.c,.cpp` file.
* `--root`. Default: `$PWD`.\
The root directory.
By default, the `src/` subdirectory of root is searched and includes are
resolved relative to it.
* `--out`. Default: `/dev/stdout`.\
Path to the amalgamated source output.

## Benchmarks

With amalgamation:

~~~bash
rm -f script/amalgamate/build/amalgamate && make clean AMALGAM=1 && \
time make lib/libsass.so AMALGAM=1 && du -sh lib/libsass.so
~~~

Compilation time (1 core): 30s
`lib/libsass.so` size: 3.0M

These numbers are the same affected for both inline and include-style amalgamation.

Without amalgamation:

~~~bash
make clean AMALGAM=0 && time make -j`nproc` lib/libsass.so AMALGAM=0 && du -sh lib/libsass.so
~~~

Compilation time (1 core): 60s
Compilation time (8 cores): 16s
`lib/libsass.so` size: 3.3M
Loading

0 comments on commit 5ea4f68

Please sign in to comment.