Merge branch 'rav/makefile'

This commit is contained in:
Richard van der Hoff 2016-05-20 16:52:01 +01:00
commit ff4d210d05
7 changed files with 139 additions and 155 deletions

119
Makefile Normal file
View file

@ -0,0 +1,119 @@
#!/usr/bin/make -f
BUILD_DIR := build
OPTIMIZE_FLAGS ?= -g -O3
TEST_OPTIMIZE_FLAGS ?= -g -O0
JS_OPTIMIZE_FLAGS ?= -O3
CC = gcc
EMCC = emcc
TARGET := $(BUILD_DIR)/libolm.so
JS_TARGET := javascript/olm.js
JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json
PUBLIC_HEADERS := include/olm/olm.hh
SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c)
OBJECTS := $(patsubst src/%,$(BUILD_DIR)/%,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES))))
TEST_SOURCES := $(wildcard tests/test_*.cpp) $(wildcard tests/test_*.c)
TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/%,$(patsubst %.c,%,$(patsubst %.cpp,%,$(TEST_SOURCES))))
JS_OBJECTS := $(patsubst %.o,%.js.bc,$(OBJECTS))
JS_PRE := $(wildcard javascript/*pre.js)
JS_POST := $(wildcard javascript/*post.js)
CPPFLAGS += -Iinclude -Ilib
CFLAGS += -Wall --std=c89 -fPIC
CXXFLAGS += -Wall --std=c++11 -fPIC
LDFLAGS += -Wall
EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0
# NO_BROWSER is kept for compatibility with emscripten 1.35.24, but is no
# longer needed.
EMCCFLAGS += -s NO_BROWSER=1
EMCC.c = $(EMCC) $(CFLAGS) $(CPPFLAGS) -c
EMCC.cc = $(EMCC) $(CXXFLAGS) $(CPPFLAGS) -c
EMCC_LINK = $(EMCC) $(LDFLAGS) $(EMCCFLAGS)
# generate .d files when compiling
CPPFLAGS += -MMD
### per-target variables
$(OBJECTS): CFLAGS += $(OPTIMIZE_FLAGS)
$(OBJECTS): CXXFLAGS += $(OPTIMIZE_FLAGS)
$(TARGET): LDFLAGS += $(OPTIMIZE_FLAGS)
$(TEST_BINARIES): CPPFLAGS += -Itests/include
$(TEST_BINARIES): LDFLAGS += $(TEST_OPTIMIZE_FLAGS) -L$(BUILD_DIR)
$(JS_OBJECTS): CFLAGS += $(JS_OPTIMIZE_FLAGS)
$(JS_OBJECTS): CXXFLAGS += $(JS_OPTIMIZE_FLAGS)
$(JS_TARGET): LDFLAGS += $(JS_OPTIMIZE_FLAGS)
### top-level targets
lib: $(TARGET)
.PHONY: lib
$(TARGET): $(OBJECTS)
$(CXX) $(LDFLAGS) --shared -fPIC \
-Wl,--version-script,version_script.ver \
$(OUTPUT_OPTION) $(OBJECTS)
js: $(JS_TARGET)
.PHONY: js
$(JS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS)
$(EMCC_LINK) \
--pre-js $(JS_PRE) --post-js $(JS_POST) \
-s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \
$(JS_OBJECTS) -o $@
clean:;
rm -rf $(OBJECTS) $(OBJECTS:.o=.d) \
$(TEST_BINARIES) $(TEST_BINARIES:=.d) \
$(JS_OBJECTS) $(JS_OBJECTS:=.d) $(JS_TARGET) \
$(JS_EXPORTED_FUNCTIONS) \
$(TARGET)
build_tests: $(TEST_BINARIES)
test: build_tests
for i in $(TEST_BINARIES); do \
echo $$i; \
$$i || exit $$?; \
done
$(JS_EXPORTED_FUNCTIONS): $(PUBLIC_HEADERS)
perl -MJSON -ne '/(olm_[^( ]*)\(/ && push @f, "_$$1"; END { print encode_json \@f }' $^ > $@.tmp
mv $@.tmp $@
all: test js lib
.PHONY: lib
### rules for building objects
$(BUILD_DIR)/%.o: src/%.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/%.o: src/%.cpp
$(COMPILE.cc) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/%.js.bc: src/%.c
$(EMCC.c) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/%.js.bc: src/%.cpp
$(EMCC.cc) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/%: tests/%.c $(OBJECTS)
$(LINK.c) $< $(OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@
$(BUILD_DIR)/%: tests/%.cpp $(OBJECTS)
$(LINK.cc) $< $(OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@
### dependencies
-include $(OBJECTS:.o=.d)
-include $(JS_OBJECTS:.bc=.d)
-include $(TEST_BINARIES:=.d)

View file

@ -14,20 +14,19 @@ To build olm as a shared library run:
.. code:: bash .. code:: bash
./build_shared_library.py make
To run the tests run: To run the tests run:
.. code:: bash .. code:: bash
./test.py make test
To build the javascript bindings, install emscripten from http://kripken.github.io/emscripten-site/ and then run: To build the javascript bindings, install emscripten from http://kripken.github.io/emscripten-site/ and then run:
.. code:: bash .. code:: bash
javascript/build.py # builds javascript/olm.js make js
npm pack javascript # packages olm.js into olm-x.y.z.tgz npm pack javascript # packages olm.js into olm-x.y.z.tgz
Remember to make a tag after releasing a tarball: Remember to make a tag after releasing a tarball:
@ -43,6 +42,11 @@ Design
Olm is designed to be easy port to different platforms and to be easy Olm is designed to be easy port to different platforms and to be easy
to write bindings for. to write bindings for.
It was originally implemented in C++, with a plain-C layer providing the public
API. As development has progressed, it has become clear that C++ gives little
advantage, and new functionality is being added in C, with C++ parts being
rewritten as the need ariases.
Error Handling Error Handling
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -78,13 +82,13 @@ the ratchet. While this decreases the performance it makes it much easier
to compile the library for different architectures. to compile the library for different architectures.
What's an olm? What's an olm?
~~~~~~~~~~~~~~ --------------
It's a really cool species of European troglodytic salamander. It's a really cool species of European troglodytic salamander.
http://www.postojnska-jama.eu/en/come-and-visit-us/vivarium-proteus/ http://www.postojnska-jama.eu/en/come-and-visit-us/vivarium-proteus/
Legal Notice Legal Notice
~~~~~~~~~~~~ ------------
The software may be subject to the U.S. export control laws and regulations The software may be subject to the U.S. export control laws and regulations
and by downloading the software the user certifies that he/she/it is and by downloading the software the user certifies that he/she/it is

View file

@ -1,36 +0,0 @@
#! /usr/bin/env python
# Copyright 2015 OpenMarket Ltd
#
# 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.
import subprocess
import glob
import os
import sys
if not os.path.exists("build"):
os.mkdir("build")
source_files = glob.glob("src/*.cpp")
compile_args = "g++ -Wall -O3 -Iinclude -Ilib --std=c++11 --shared -fPIC".split()
compile_args += source_files
compile_args += sys.argv[1:]
library = "build/libolm.so"
def run(args):
print " ".join(args)
subprocess.check_call(args)
run(compile_args + ["-o", library])

View file

@ -1,74 +0,0 @@
#! /usr/bin/env python
# Copyright 2015 OpenMarket Ltd
#
# 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.
import subprocess
import glob
import os
import sys
import re
import json
os.chdir(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
source_files = glob.glob("src/*.cpp")
pre_js, = glob.glob("javascript/*pre.js")
post_js, = glob.glob("javascript/*post.js")
functions = set()
RE_FUNCTION=re.compile("(olm_[^( ]*)\\(")
with open("include/olm/olm.hh") as header:
for line in header:
match = RE_FUNCTION.search(line)
if match:
functions.add(match.groups()[0])
exported_functions = os.path.abspath("javascript/exported_functions.json")
with open(exported_functions, "w") as json_file:
json.dump(["_" + function for function in functions], json_file)
emcc = os.environ.get("EMCC", "emcc")
optimize_opts = os.environ.get("OPTIMIZE_FLAGS", "-O3")
compile_args = [emcc]
compile_args += optimize_opts.split()
compile_args += ["-Wall"]
compile_args += """
-Iinclude
-Ilib
-std=c++11
--closure 1
--memory-init-file 0
-s NO_FILESYSTEM=1
-s INVOKE_RUN=0
""".split()
# NO_BROWSER is kept for compatibility with emscripten 1.35.24, but is no
# longer needed.
compile_args += ("-s","NO_BROWSER=1")
compile_args += source_files
compile_args += ("--pre-js", pre_js)
compile_args += ("--post-js", post_js)
compile_args += ("-s", "EXPORTED_FUNCTIONS=@" + exported_functions)
compile_args += sys.argv[1:]
library = "javascript/olm.js"
def run(args):
print args
print " ".join(args)
subprocess.check_call(args)
run(compile_args + ["-o", library])

View file

@ -8,7 +8,7 @@
"README.md" "README.md"
], ],
"scripts": { "scripts": {
"build": "./build.py", "build": "make -C .. js",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"repository": { "repository": {

38
test.py
View file

@ -1,38 +0,0 @@
#! /usr/bin/env python
# Copyright 2015 OpenMarket Ltd
#
# 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.
import glob
import os
import subprocess
import sys
if not os.path.exists("build/libolm.so"):
print >> sys.stderr, \
"libolm has not been built. Run ./build_shared_library.py first."
exit(1)
test_files = glob.glob("tests/test_*.cpp")
compile_args = ("g++ -g -O0 -Itests/include -Iinclude -Ilib --std=c++11 "+
"-L build").split()
def run(args, *xargs, **kwargs):
print " ".join(args)
subprocess.check_call(args, *xargs, **kwargs)
for test_file in test_files:
exe_file = "build/" + test_file[6:-4]
run(compile_args + [test_file, "-lolm", "-o", exe_file])
run([exe_file], env={'LD_LIBRARY_PATH':'./build'})

9
version_script.ver Normal file
View file

@ -0,0 +1,9 @@
# this is a 'version script' for the linker which tells it to only export
# symbols starting 'olm_'.
{
global:
olm_*;
local:
*;
};