11 Commits

Author SHA1 Message Date
0cbf66c007 build: Let's try to artifact the x86_64 + ARM linux executables.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 21m30s
2024-12-24 10:31:09 -05:00
cd378b721d build: Support and test cross-compiling for linux-aarch64.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 22m13s
2024-12-24 10:01:14 -05:00
547d38d1ef ssb: Put the database in (ie, ~/.local/share/tildefriends/db.sqlite) by default. Unless it already exists in the working directory, so that nobody worries they've lost it. #91
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 17m48s
2024-12-23 16:32:30 -05:00
dca56af5b9 build: Let's go static openssl on macos, too.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 18m0s
2024-12-23 14:41:31 -05:00
224442772e build: Let's try a thing. Use our own static openssl libraries built in-tree.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 17m49s
2024-12-23 14:22:27 -05:00
003951fdf7 ssb: Load more context for mentions.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 16m39s
2024-12-23 13:32:36 -05:00
d51b3da1b4 ssb: Fix channel cycling key shortcut.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2024-12-23 13:18:30 -05:00
69f4af84db ssb: Fix weird sidebar sizing.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2024-12-23 13:07:33 -05:00
771759b252 ssb: Show drafts in the sidebar.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 16m22s
2024-12-23 12:25:52 -05:00
20c7a71db6 ssb: Add a checkbox to reply in a new thread. #47 Also, it's crab time. I'm sorry it took me so long.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 16m53s
2024-12-23 12:06:32 -05:00
8475ee0985 build: Let's start work on 0.0.27. 2024-12-23 11:23:51 -05:00
13 changed files with 378 additions and 60 deletions

38
' Normal file
View File

@ -0,0 +1,38 @@
name: Build Tilde Friends
run-name: ${{ gitea.actor }} running 🚀
on: [push]
jobs:
Build-All:
runs-on: ubuntu-latest
container:
valid_volumes: ['/opt/keys']
volumes:
- /opt/keys:/opt/keys
steps:
- name: check out code
uses: actions/checkout@v4
with:
submodules: true
- run: ln -s /opt/keys .keys
- name: Setup JDK
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264'
- run: sudo apt update && sudo apt install -y doxygen graphviz mingw-w64 libgpgme11 gcc-aarch64-linux-gnu
- run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all docs
- run: docker build .
- uses: actions/upload-artifact@v3
with:
path: out/TildeFriends-release.fdroid.apk
- uses: actions/upload-artifact@v3
with:
path: out/winrelease/tildefriends.exe
- uses: actions/upload-artifact@v3
with:
path: out/tildefriends-x86_64.AppImage

View File

@ -24,15 +24,14 @@ jobs:
uses: android-actions/setup-android@v3 uses: android-actions/setup-android@v3
with: with:
packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264' packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264'
- run: sudo apt update && sudo apt install -y doxygen graphviz mingw-w64 libgpgme11 - run: sudo apt update && sudo apt install -y doxygen graphviz mingw-w64 libgpgme11 gcc-aarch64-linux-gnu
- run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all docs - run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all docs
- run: docker build . - run: docker build .
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v3
with: with:
path: out/TildeFriends-release.fdroid.apk path: |
- uses: actions/upload-artifact@v3 out/TildeFriends-release.fdroid.apk
with: out/winrelease/tildefriends.exe
path: out/winrelease/tildefriends.exe out/tildefriends-x86_64.AppImage
- uses: actions/upload-artifact@v3 out/release/tildefriends.standalone
with: out/armrelease/tildefriends.standalone
path: out/tildefriends-x86_64.AppImage

View File

@ -16,8 +16,8 @@ MAKEFLAGS += --no-builtin-rules
## LD := Linker. ## LD := Linker.
## ANDROID_SDK := Path to the Android SDK. ## ANDROID_SDK := Path to the Android SDK.
VERSION_CODE := 31 VERSION_CODE := 32
VERSION_NUMBER := 0.0.26 VERSION_NUMBER := 0.0.27-wip
VERSION_NAME := This program kills fascists. VERSION_NAME := This program kills fascists.
SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3470200.zip SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3470200.zip
@ -34,6 +34,7 @@ ANDROID_SDK ?= ~/Android/Sdk
BUNDLETOOL = out/bundletool.jar BUNDLETOOL = out/bundletool.jar
HAVE_WIN := 0 HAVE_WIN := 0
HAVE_CROSS_AARCH64 := 0
export SOURCE_DATE_EPOCH=1 export SOURCE_DATE_EPOCH=1
export TZ=UTC export TZ=UTC
@ -45,6 +46,9 @@ BUILD_TYPES := debug release
HAVE_ANDROID = $(if $(shell which $(ANDROID_SDK)/platform-tools/adb),1,0) HAVE_ANDROID = $(if $(shell which $(ANDROID_SDK)/platform-tools/adb),1,0)
HAVE_LINUX_IOS = $(if $(shell which deps/ios_toolchain/target/bin deps/ios_toolchain/target/bin/arm-apple-darwin11-clang),1,0) HAVE_LINUX_IOS = $(if $(shell which deps/ios_toolchain/target/bin deps/ios_toolchain/target/bin/arm-apple-darwin11-clang),1,0)
HAVE_WIN = $(if $(shell which x86_64-w64-mingw32-gcc-win32),1,0) HAVE_WIN = $(if $(shell which x86_64-w64-mingw32-gcc-win32),1,0)
ifneq ($(UNAME_M),aarch64)
HAVE_CROSS_AARCH64 = $(if $(shell which aarch64-linux-gnu-gcc),1,0)
endif
else ifeq ($(UNAME_S),Haiku) else ifeq ($(UNAME_S),Haiku)
BUILD_TYPES := debug release BUILD_TYPES := debug release
CFLAGS += -Dstatic_assert=_Static_assert CFLAGS += -Dstatic_assert=_Static_assert
@ -125,6 +129,13 @@ ifeq ($(HAVE_WIN),1)
BUILD_TYPES += windebug winrelease BUILD_TYPES += windebug winrelease
endif endif
AARCH64_TARGETS := \
out/armdebug/tildefriends \
out/armrelease/tildefriends
ifeq ($(HAVE_CROSS_AARCH64),1)
BUILD_TYPES += armdebug armrelease
endif
LINUX_TARGETS := \ LINUX_TARGETS := \
out/debug/tildefriends \ out/debug/tildefriends \
out/release/tildefriends out/release/tildefriends
@ -149,6 +160,9 @@ all: $(IOS_APPS) \
out/tildefriends-iossimdebug.app/tildefriends \ out/tildefriends-iossimdebug.app/tildefriends \
out/tildefriends-iossimrelease.app/tildefriends out/tildefriends-iossimrelease.app/tildefriends
endif endif
ifeq ($(HAVE_CROSS_AARCH64),1)
all: out/armrelease/tildefriends.standalone
endif
DEBUG_TARGETS := \ DEBUG_TARGETS := \
out/debug/tildefriends \ out/debug/tildefriends \
@ -159,7 +173,8 @@ DEBUG_TARGETS := \
out/androiddebug/tildefriends \ out/androiddebug/tildefriends \
out/androiddebug-armv7a/tildefriends \ out/androiddebug-armv7a/tildefriends \
out/androiddebug-x86_64/tildefriends \ out/androiddebug-x86_64/tildefriends \
out/androiddebug-x86/tildefriends out/androiddebug-x86/tildefriends \
out/armdebug/tildefriends
RELEASE_TARGETS := \ RELEASE_TARGETS := \
out/release/tildefriends \ out/release/tildefriends \
out/winrelease/tildefriends.exe \ out/winrelease/tildefriends.exe \
@ -169,7 +184,8 @@ RELEASE_TARGETS := \
out/androidrelease/tildefriends \ out/androidrelease/tildefriends \
out/androidrelease-armv7a/tildefriends \ out/androidrelease-armv7a/tildefriends \
out/androidrelease-x86_64/tildefriends \ out/androidrelease-x86_64/tildefriends \
out/androidrelease-x86/tildefriends out/androidrelease-x86/tildefriends \
out/armrelease/tildefriends
ALL_TARGETS = $(DEBUG_TARGETS) $(RELEASE_TARGETS) ALL_TARGETS = $(DEBUG_TARGETS) $(RELEASE_TARGETS)
ANDROID_RELEASE_TARGETS := $(filter-out $(DEBUG_TARGETS),$(ANDROID_TARGETS)) ANDROID_RELEASE_TARGETS := $(filter-out $(DEBUG_TARGETS),$(ANDROID_TARGETS))
NONANDROID_RELEASE_TARGETS := $(filter-out $(ANDROID_ARM64_TARGETS),$(RELEASE_TARGETS)) NONANDROID_RELEASE_TARGETS := $(filter-out $(ANDROID_ARM64_TARGETS),$(RELEASE_TARGETS))
@ -208,6 +224,10 @@ $(WINDOWS_TARGETS): LDFLAGS += \
-static \ -static \
-lm \ -lm \
-Ldeps/openssl/mingw64/usr/local/lib -Ldeps/openssl/mingw64/usr/local/lib
$(AARCH64_TARGETS): CC = aarch64-linux-gnu-gcc
$(AARCH64_TARGETS): AS = $(CC)
$(AARCH64_TARGETS): CFLAGS += -Ideps/openssl/Linux/aarch64/usr/local/include
$(AARCH64_TARGETS): LDFLAGS += -Ldeps/openssl/Linux/aarch64/usr/local/lib
ifeq ($(UNAME_S),Darwin) ifeq ($(UNAME_S),Darwin)
$(MACOS_TARGETS): CC = xcrun clang $(MACOS_TARGETS): CC = xcrun clang
$(IOS_TARGETS): IOS_SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path) $(IOS_TARGETS): IOS_SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path)
@ -242,10 +262,12 @@ $(IOS_TARGETS): CFLAGS += -miphoneos-version-min=9.0 -Ideps/openssl/ios/ios64-xc
$(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=9.0 -Ldeps/openssl/ios/ios64-xcrun/usr/local/lib $(IOS_TARGETS): LDFLAGS += -miphoneos-version-min=9.0 -Ldeps/openssl/ios/ios64-xcrun/usr/local/lib
$(IOSSIM_TARGETS): CFLAGS += -Ideps/openssl/ios/iossimulator-xcrun/usr/local/include $(IOSSIM_TARGETS): CFLAGS += -Ideps/openssl/ios/iossimulator-xcrun/usr/local/include
$(IOSSIM_TARGETS): LDFLAGS += -Ldeps/openssl/ios/iossimulator-xcrun/usr/local/lib $(IOSSIM_TARGETS): LDFLAGS += -Ldeps/openssl/ios/iossimulator-xcrun/usr/local/lib
$(LINUX_TARGETS) $(MACOS_TARGETS): CFLAGS += -Ideps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/include
$(LINUX_TARGETS) $(MACOS_TARGETS): LDFLAGS += -Ldeps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib
ifeq ($(UNAME_M),x86_64) ifeq ($(UNAME_M),x86_64)
ifeq ($(UNAME_S),Linux) ifeq ($(UNAME_S),Linux)
all: appimage all: appimage out/release/tildefriends.standalone
endif endif
ifneq ($(UNAME_S),Haiku) ifneq ($(UNAME_S),Haiku)
out/debug/tildefriends: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common out/debug/tildefriends: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
@ -260,7 +282,7 @@ endif
get_objs = \ get_objs = \
$(foreach build_type,$(BUILD_TYPES),$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)))))) \ $(foreach build_type,$(BUILD_TYPES),$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)))))) \
$(foreach build_type,debug release,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \ $(foreach build_type,debug release armdebug armrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
$(foreach build_type,windebug winrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_win))))) \ $(foreach build_type,windebug winrelease,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_win))))) \
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androiddebug-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_android))))) \ $(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androiddebug-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_android))))) \
$(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androidrelease-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \ $(foreach build_type,androiddebug androidrelease androiddebug-x86 androidrelease-x86 androiddebug-x86_64 androidrelease-x86_64 androiddebug-armv7a androidrelease-armv7a,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
@ -725,7 +747,7 @@ $(MINIUNZIP_OBJS): CFLAGS += \
LDFLAGS += \ LDFLAGS += \
-pthread \ -pthread \
-lm -lm
$(LINUX_TARGETS) $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \ $(LINUX_TARGETS) $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS) $(AARCH64_TARGETS): LDFLAGS += \
-lssl \ -lssl \
-lcrypto -lcrypto
ifneq ($(UNAME_S),Haiku) ifneq ($(UNAME_S),Haiku)
@ -1106,6 +1128,27 @@ $(ANDROID_DEPS):
+@ANDROID_NDK_ROOT=$(ANDROID_NDK) tools/ssl-android +@ANDROID_NDK_ROOT=$(ANDROID_NDK) tools/ssl-android
$(filter $(BUILD_DIR)/android%,$(APP_OBJS)): | $(ANDROID_DEPS) $(filter $(BUILD_DIR)/android%,$(APP_OBJS)): | $(ANDROID_DEPS)
ifeq ($(UNAME_S),Linux)
LOCAL_DEPS := deps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
$(LOCAL_DEPS):
+@tools/ssl-local
$(filter $(BUILD_DIR)/debug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/release/%,$(APP_OBJS)): | $(LOCAL_DEPS)
ifeq ($(HAVE_CROSS_AARCH64),1)
LOCAL_DEPS := deps/openssl/$(UNAME_S)/aarch64/usr/local/lib/libssl.a
$(LOCAL_DEPS):
+@OPTIONS=--cross-compile-prefix=aarch64-linux-gnu- BUILD_TARGET=aarch64 tools/ssl-local
$(filter $(BUILD_DIR)/armdebug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/armrelease/%,$(APP_OBJS)): | $(LOCAL_DEPS)
endif
endif
ifeq ($(UNAME_S),Darwin)
LOCAL_DEPS := deps/openssl/$(UNAME_S)/$(UNAME_M)/usr/local/lib/libssl.a
$(LOCAL_DEPS):
+@tools/ssl-local
$(filter $(BUILD_DIR)/macosdebug/%,$(APP_OBJS)) $(filter $(BUILD_DIR)/macosrelease/%,$(APP_OBJS)): | $(LOCAL_DEPS)
endif
ifeq ($(HAVE_WIN),1) ifeq ($(HAVE_WIN),1)
WINDOWS_DEPS := deps/openssl/mingw64/usr/local/lib/libssl.a WINDOWS_DEPS := deps/openssl/mingw64/usr/local/lib/libssl.a
$(WINDOWS_DEPS): $(WINDOWS_DEPS):
@ -1198,7 +1241,7 @@ tarball: ## Build an all-inclusive source tarball (.tar.xz).
.PHONY: tarball .PHONY: tarball
dist: ## Build versions of all distributables for release. dist: ## Build versions of all distributables for release.
dist: release-apk iosrelease-ipa aab $(if $(HAVE_WIN), out/winrelease/tildefriends.standalone.exe) out/TildeFriends-release.fdroid.apk appimage tarball dist: release-apk iosrelease-ipa aab $(if $(HAVE_WIN), out/winrelease/tildefriends.standalone.exe) out/TildeFriends-release.fdroid.apk appimage tarball out/release/tildefriends.standalone $(if $(HAVE_CROSS_AARCH64), out/armrelease/tildefriends.standalone)
@mkdir -p dist/ @mkdir -p dist/
@echo "[cp] tildefriends-$(VERSION_NUMBER).tar.xz" @echo "[cp] tildefriends-$(VERSION_NUMBER).tar.xz"
@cp out/tildefriends-$(VERSION_NUMBER).tar.xz dist/tildefriends-$(VERSION_NUMBER).tar.xz @cp out/tildefriends-$(VERSION_NUMBER).tar.xz dist/tildefriends-$(VERSION_NUMBER).tar.xz
@ -1216,6 +1259,10 @@ dist: release-apk iosrelease-ipa aab $(if $(HAVE_WIN), out/winrelease/tildefrien
@cp out/TildeFriends-release.fdroid.apk dist/TildeFriends-$(VERSION_NUMBER).fdroid.apk @cp out/TildeFriends-release.fdroid.apk dist/TildeFriends-$(VERSION_NUMBER).fdroid.apk
@echo "[cp] TildeFriends-x86_64-$(VERSION_NUMBER).AppImage" @echo "[cp] TildeFriends-x86_64-$(VERSION_NUMBER).AppImage"
@cp out/tildefriends-x86_64.AppImage dist/TildeFriends-x86_64-$(VERSION_NUMBER).AppImage @cp out/tildefriends-x86_64.AppImage dist/TildeFriends-x86_64-$(VERSION_NUMBER).AppImage
@echo "[cp] tildefriends-linux-$(UNAME_M)-$(VERSION_NUMBER)"
@cp out/release/tildefriends.standalone dist/tildefriends-linux-$(UNAME_M)-$(VERSION_NUMBER)
@test $(HAVE_CROSS_AARCH64) && echo "[cp] tildefriends-linux-aarch64-$(VERSION_NUMBER)"
@test $(HAVE_CROSS_AARCH64) && cp out/armrelease/tildefriends.standalone dist/tildefriends-linux-aarch64-$(VERSION_NUMBER)
.PHONY: dist .PHONY: dist
dist-test: dist ## Exercise some built distributable files, making sure they work as intended. dist-test: dist ## Exercise some built distributable files, making sure they work as intended.

View File

@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🐌", "emoji": "🦀",
"previous": "&q/1uGp0jMvsYGW7Gj8E33kf6UFo/uNYDXg3zo1sVKQg=.sha256" "previous": "&PP5y+K7wgLxdkeeb4iqyK1Fb+vwS9LjLJDt2FPrVlpo=.sha256"
} }

View File

@ -112,26 +112,24 @@ class TfElement extends LitElement {
keydown(event) { keydown(event) {
if (event.altKey && event.key == 'ArrowUp') { if (event.altKey && event.key == 'ArrowUp') {
this.next_channel(1); this.next_channel(-1);
event.preventDefault(); event.preventDefault();
} else if (event.altKey && event.key == 'ArrowDown') { } else if (event.altKey && event.key == 'ArrowDown') {
this.next_channel(-1); this.next_channel(1);
event.preventDefault(); event.preventDefault();
} }
} }
next_channel(delta) { next_channel(delta) {
let channel_names = ['', '@'].concat(this.channels); let channel_names = ['', '@', '🔐', ...this.channels.map(x => '#' + x)];
let index = channel_names.indexOf(this.hash.substring(1)); let index = channel_names.indexOf(this.hash.substring(1));
if (index != -1) { index = index != -1 ? index + delta : 0;
index += delta; tfrpc.rpc.setHash(
this.set_hash( '#' +
'#' + encodeURIComponent(
encodeURIComponent( channel_names[(index + channel_names.length) % channel_names.length]
channel_names[(index + channel_names.length) % channel_names.length] )
) );
);
}
} }
set_hash(hash) { set_hash(hash) {

View File

@ -15,6 +15,7 @@ class TfComposeElement extends LitElement {
drafts: {type: Object}, drafts: {type: Object},
author: {type: String}, author: {type: String},
channel: {type: String}, channel: {type: String},
new_thread: {type: Boolean},
}; };
} }
@ -28,6 +29,7 @@ class TfComposeElement extends LitElement {
this.apps = undefined; this.apps = undefined;
this.drafts = {}; this.drafts = {};
this.author = undefined; this.author = undefined;
this.new_thread = false;
} }
process_text(text) { process_text(text) {
@ -200,7 +202,7 @@ class TfComposeElement extends LitElement {
channel: this.channel, channel: this.channel,
}; };
if (this.root || this.branch) { if (this.root || this.branch) {
message.root = this.root; message.root = this.new_thread ? this.branch ?? this.root : this.root;
message.branch = this.branch; message.branch = this.branch;
} }
if (Object.values(draft.mentions || {}).length) { if (Object.values(draft.mentions || {}).length) {
@ -469,6 +471,16 @@ class TfComposeElement extends LitElement {
} }
} }
render_new_thread() {
let self = this;
if (this.root !== undefined && this.branch !== undefined && this.root != this.branch) {
return html`
<input type="checkbox" class="w3-check w3-theme-d1" id="new_thread" @change=${() => self.new_thread = !self.new_thread} ?checked=${self.new_thread}></input>
<label for="new_thread">New Thread</label>
`;
}
}
get_draft() { get_draft() {
return this.drafts[this.branch || ''] || {}; return this.drafts[this.branch || ''] || {};
} }
@ -562,7 +574,9 @@ class TfComposeElement extends LitElement {
${Object.values(draft.mentions || {}).map((x) => ${Object.values(draft.mentions || {}).map((x) =>
self.render_mention(x) self.render_mention(x)
)} )}
${this.render_attach_app()} ${this.render_content_warning()} ${this.render_attach_app()}
${this.render_content_warning()}
${this.render_new_thread()}
<button class="w3-button w3-theme-d1" id="submit" @click=${this.submit}> <button class="w3-button w3-theme-d1" id="submit" @click=${this.submit}>
Submit Submit
</button> </button>

View File

@ -51,15 +51,21 @@ class TfTabNewsFeedElement extends LitElement {
if (this.hash == '#@') { if (this.hash == '#@') {
result = await tfrpc.rpc.query( result = await tfrpc.rpc.query(
` `
WITH mentions AS (SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
FROM messages_fts(?1)
JOIN messages ON messages.rowid = messages_fts.rowid
JOIN json_each(?2) AS following ON messages.author = following.value
WHERE
messages.author != ?1 AND
messages.timestamp >= ?3 AND
messages.timestamp < ?4
ORDER BY timestamp DESC limit 20)
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
FROM messages_fts(?1) FROM mentions
JOIN messages ON messages.rowid = messages_fts.rowid JOIN messages_refs ON mentions.id = messages_refs.ref
JOIN json_each(?2) AS following ON messages.author = following.value JOIN messages ON messages_refs.message = messages.id
WHERE UNION
messages.author != ?1 AND SELECT * FROM mentions
messages.timestamp >= ?3 AND
messages.timestamp < ?4
ORDER BY timestamp DESC limit 20
`, `,
[ [
'"' + this.whoami.replace('"', '""') + '"', '"' + this.whoami.replace('"', '""') + '"',

View File

@ -176,7 +176,7 @@ class TfTabNewsElement extends LitElement {
return html` return html`
<div <div
class="w3-sidebar w3-bar-block w3-theme-d1 w3-collapse w3-animate-left" class="w3-sidebar w3-bar-block w3-theme-d1 w3-collapse w3-animate-left"
style="width: 2in; left: 0; z-index: 5" style="width: 2in; left: 0; z-index: 5; box-sizing: border-box"
id="sidebar" id="sidebar"
> >
<div <div
@ -216,6 +216,13 @@ class TfTabNewsElement extends LitElement {
style=${this.hash == '#🔐' ? 'font-weight: bold' : undefined} style=${this.hash == '#🔐' ? 'font-weight: bold' : undefined}
>🔐private ${this.unread_status('🔐')}</a >🔐private ${this.unread_status('🔐')}</a
> >
${Object.keys(this.drafts).sort().map(x => html`
<a
href=${'#' + encodeURIComponent(x)}
class="w3-bar-item w3-button"
style="text-wrap: nowrap; text-overflow: ellipsis">📝 ${this.drafts[x]?.text ?? x}</a
>
`)}
${this.channels.map( ${this.channels.map(
(x) => html` (x) => html`
<a <a

View File

@ -21,14 +21,14 @@
}: }:
pkgs.stdenv.mkDerivation rec { pkgs.stdenv.mkDerivation rec {
pname = "tildefriends"; pname = "tildefriends";
version = "0.0.25"; version = "0.0.26";
src = pkgs.fetchFromGitea { src = pkgs.fetchFromGitea {
domain = "dev.tildefriends.net"; domain = "dev.tildefriends.net";
owner = "cory"; owner = "cory";
repo = "tildefriends"; repo = "tildefriends";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-Rfk+CUhi+Ss0z70CCgmtVM/w4nCL1GX/MsD4sPYIa5s="; hash = "sha256-XJ7M++risfsRn9GkS1zjTQpqqV5S09uyimeVzU9hGGg=";
fetchSubmodules = true; fetchSubmodules = true;
}; };

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unprompted.tildefriends" package="com.unprompted.tildefriends"
android:versionCode="31" android:versionCode="32"
android:versionName="0.0.26"> android:versionName="0.0.27-wip">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<application <application

View File

@ -25,6 +25,7 @@
#if defined(__linux__) #if defined(__linux__)
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/stat.h>
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
@ -41,7 +42,102 @@
struct backtrace_state* g_backtrace_state; struct backtrace_state* g_backtrace_state;
const char* k_db_path_default = "db.sqlite"; #if !defined(TARGET_OS_IPHONE)
static const char* _get_db_path()
{
const char* k_db_path_default = "db.sqlite";
#if defined(__linux__)
if (stat(k_db_path_default, &(struct stat) { 0 }) == 0)
{
return tf_strdup(k_db_path_default);
}
else
{
char buffer[32];
char* data_home = NULL;
size_t size = sizeof(buffer);
int r = uv_os_getenv("XDG_DATA_HOME", buffer, &size);
if (r == 0 || r == UV_ENOBUFS)
{
size++;
data_home = alloca(size);
if (uv_os_getenv("XDG_DATA_HOME", data_home, &size) != 0)
{
data_home = NULL;
}
}
if (!data_home)
{
size = sizeof(buffer);
r = uv_os_getenv("HOME", buffer, &size);
if (r == 0 || r == UV_ENOBUFS)
{
size++;
char* home = alloca(size);
r = uv_os_getenv("HOME", home, &size);
if (r == 0)
{
size = snprintf(NULL, 0, "%s/.local/share", home) + 1;
data_home = alloca(size);
snprintf(data_home, size, "%s/.local/share", home);
}
}
}
if (data_home)
{
size = snprintf(NULL, 0, "%s/tildefriends/db.sqlite", data_home) + 1;
char* path = alloca(size);
snprintf(path, size, "%s/tildefriends/db.sqlite", data_home);
return tf_strdup(path);
}
}
#endif
return tf_strdup(k_db_path_default);
}
static void _create_directories_for_file(const char* path, int mode)
{
if (stat(path, &(struct stat) { 0 }) == 0)
{
/* It already exists. OK. */
return;
}
size_t length = strlen(path) + 1;
char* copy = alloca(length);
memcpy(copy, path, length);
#if defined(_WIN32)
for (char* c = copy; *c; c++)
{
if (*c == '\\')
{
*c = '/';
}
}
#endif
char* slash = copy;
while (slash)
{
slash = strchr(slash + 1, '/');
if (slash)
{
*slash = '\0';
#if defined(_WIN32)
if (mkdir(copy) == 0)
#else
if (mkdir(copy, mode) == 0)
#endif
{
tf_printf("Created directory %s.\n", copy);
}
*slash = '/';
}
}
}
#endif
#if !TARGET_OS_IPHONE && !defined(__ANDROID__) #if !TARGET_OS_IPHONE && !defined(__ANDROID__)
static int _tf_command_export(const char* file, int argc, char* argv[]); static int _tf_command_export(const char* file, int argc, char* argv[]);
@ -131,7 +227,8 @@ static int _tf_command_test(const char* file, int argc, char* argv[])
static int _tf_command_import(const char* file, int argc, char* argv[]) static int _tf_command_import(const char* file, int argc, char* argv[])
{ {
const char* user = "import"; const char* user = "import";
const char* db_path = k_db_path_default; const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
bool show_usage = false; bool show_usage = false;
while (!show_usage) while (!show_usage)
@ -169,11 +266,13 @@ static int _tf_command_import(const char* file, int argc, char* argv[])
tf_printf("\n%s import [options] [paths...]\n\n", file); tf_printf("\n%s import [options] [paths...]\n\n", file);
tf_printf("options:\n"); tf_printf("options:\n");
tf_printf(" -u, --user user User into whose account apps will be imported (default: \"import\").\n"); tf_printf(" -u, --user user User into whose account apps will be imported (default: \"import\").\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default); tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -h, --help Show this usage information.\n"); tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
_create_directories_for_file(db_path, 0700);
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL); tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
if (optind < argc) if (optind < argc)
{ {
@ -189,13 +288,15 @@ static int _tf_command_import(const char* file, int argc, char* argv[])
tf_ssb_import(ssb, user, "apps"); tf_ssb_import(ssb, user, "apps");
} }
tf_ssb_destroy(ssb); tf_ssb_destroy(ssb);
tf_free((void*)default_db_path);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static int _tf_command_export(const char* file, int argc, char* argv[]) static int _tf_command_export(const char* file, int argc, char* argv[])
{ {
const char* user = "core"; const char* user = "core";
const char* db_path = k_db_path_default; const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
bool show_usage = false; bool show_usage = false;
while (!show_usage) while (!show_usage)
@ -233,10 +334,11 @@ static int _tf_command_export(const char* file, int argc, char* argv[])
tf_printf("\n%s export [options] [paths...]\n\n", file); tf_printf("\n%s export [options] [paths...]\n\n", file);
tf_printf("options:\n"); tf_printf("options:\n");
tf_printf(" -u, --user user User from whose account apps will be exported (default: \"core\").\n"); tf_printf(" -u, --user user User from whose account apps will be exported (default: \"core\").\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default); tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -h, --help Show this usage information.\n"); tf_printf(" -h, --help Show this usage information.\n");
tf_printf("\n"); tf_printf("\n");
tf_printf("paths Paths of apps to export (example: /~core/ssb /~user/app).\n"); tf_printf("paths Paths of apps to export (example: /~core/ssb /~user/app).\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -271,6 +373,7 @@ static int _tf_command_export(const char* file, int argc, char* argv[])
} }
} }
tf_ssb_destroy(ssb); tf_ssb_destroy(ssb);
tf_free((void*)default_db_path);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@ -298,7 +401,8 @@ static int _tf_command_publish(const char* file, int argc, char* argv[])
{ {
const char* user = NULL; const char* user = NULL;
const char* identity = NULL; const char* identity = NULL;
const char* db_path = k_db_path_default; const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
const char* content = NULL; const char* content = NULL;
bool show_usage = false; bool show_usage = false;
@ -346,14 +450,16 @@ static int _tf_command_publish(const char* file, int argc, char* argv[])
tf_printf("options:\n"); tf_printf("options:\n");
tf_printf(" -u, --user user User owning identity with which to publish.\n"); tf_printf(" -u, --user user User owning identity with which to publish.\n");
tf_printf(" -i, --id identity Identity with which to publish message.\n"); tf_printf(" -i, --id identity Identity with which to publish message.\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default); tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -c, --content json JSON content of message to publish.\n"); tf_printf(" -c, --content json JSON content of message to publish.\n");
tf_printf(" -h, --help Show this usage information.\n"); tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
int result = EXIT_FAILURE; int result = EXIT_FAILURE;
tf_printf("Posting %s as account %s belonging to %s...\n", content, identity, user); tf_printf("Posting %s as account %s belonging to %s...\n", content, identity, user);
_create_directories_for_file(db_path, 0700);
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL); tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
uint8_t private_key[512] = { 0 }; uint8_t private_key[512] = { 0 };
if (tf_ssb_db_identity_get_private_key(ssb, user, identity, private_key, sizeof(private_key))) if (tf_ssb_db_identity_get_private_key(ssb, user, identity, private_key, sizeof(private_key)))
@ -386,12 +492,14 @@ static int _tf_command_publish(const char* file, int argc, char* argv[])
tf_printf("Did not find private key for identity %s belonging to %s.\n", identity, user); tf_printf("Did not find private key for identity %s belonging to %s.\n", identity, user);
} }
tf_ssb_destroy(ssb); tf_ssb_destroy(ssb);
tf_free((void*)default_db_path);
return result; return result;
} }
static int _tf_command_store_blob(const char* file, int argc, char* argv[]) static int _tf_command_store_blob(const char* file, int argc, char* argv[])
{ {
const char* db_path = k_db_path_default; const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
const char* file_path = NULL; const char* file_path = NULL;
bool show_usage = false; bool show_usage = false;
@ -429,9 +537,10 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
{ {
tf_printf("\n%s store_blob [options]\n\n", file); tf_printf("\n%s store_blob [options]\n\n", file);
tf_printf("options:\n"); tf_printf("options:\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default); tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -f, --file file_path Path to file to add to the blob store.\n"); tf_printf(" -f, --file file_path Path to file to add to the blob store.\n");
tf_printf(" -h, --help Show this usage information.\n"); tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -441,6 +550,7 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
if (!blob_file) if (!blob_file)
{ {
tf_printf("Failed to open %s: %s.\n", file_path, strerror(errno)); tf_printf("Failed to open %s: %s.\n", file_path, strerror(errno));
tf_free((void*)default_db_path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -464,11 +574,13 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
tf_printf("Failed to read %s: %s.\n", file_path, strerror(errno)); tf_printf("Failed to read %s: %s.\n", file_path, strerror(errno));
fclose(blob_file); fclose(blob_file);
tf_free(data); tf_free(data);
tf_free((void*)default_db_path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
fclose(blob_file); fclose(blob_file);
char id[256]; char id[256];
_create_directories_for_file(db_path, 0700);
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL); tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
if (tf_ssb_db_blob_store(ssb, (const uint8_t*)data, size, id, sizeof(id), NULL)) if (tf_ssb_db_blob_store(ssb, (const uint8_t*)data, size, id, sizeof(id), NULL))
{ {
@ -476,13 +588,15 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
} }
tf_ssb_destroy(ssb); tf_ssb_destroy(ssb);
tf_free(data); tf_free(data);
tf_free((void*)default_db_path);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static int _tf_command_verify(const char* file, int argc, char* argv[]) static int _tf_command_verify(const char* file, int argc, char* argv[])
{ {
const char* identity = NULL; const char* identity = NULL;
const char* db_path = k_db_path_default; const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
bool show_usage = false; bool show_usage = false;
while (!show_usage) while (!show_usage)
@ -520,8 +634,9 @@ static int _tf_command_verify(const char* file, int argc, char* argv[])
tf_printf("\n%s import [options] [paths...]\n\n", file); tf_printf("\n%s import [options] [paths...]\n\n", file);
tf_printf("options:\n"); tf_printf("options:\n");
tf_printf(" -i, --identity identity Identity to verify.\n"); tf_printf(" -i, --identity identity Identity to verify.\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default); tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -h, --help Show this usage information.\n"); tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -529,6 +644,7 @@ static int _tf_command_verify(const char* file, int argc, char* argv[])
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL); tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
bool verified = tf_ssb_db_verify(ssb, identity); bool verified = tf_ssb_db_verify(ssb, identity);
tf_ssb_destroy(ssb); tf_ssb_destroy(ssb);
tf_free((void*)default_db_path);
return verified ? EXIT_SUCCESS : EXIT_FAILURE; return verified ? EXIT_SUCCESS : EXIT_FAILURE;
} }
#endif #endif
@ -673,13 +789,14 @@ static void _shed_privileges()
static int _tf_command_run(const char* file, int argc, char* argv[]) static int _tf_command_run(const char* file, int argc, char* argv[])
{ {
const char* default_db_path = _get_db_path();
tf_run_args_t args = { tf_run_args_t args = {
.count = 1, .count = 1,
.script = "core/core.js", .script = "core/core.js",
.http_port = 12345, .http_port = 12345,
.https_port = 12346, .https_port = 12346,
.ssb_port = 8008, .ssb_port = 8008,
.db_path = k_db_path_default, .db_path = default_db_path,
}; };
bool show_usage = false; bool show_usage = false;
@ -764,7 +881,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
tf_printf(" -b, --ssb-port port Port on which to run SSB (default: 8008, 0 disables).\n"); tf_printf(" -b, --ssb-port port Port on which to run SSB (default: 8008, 0 disables).\n");
tf_printf(" -p, --http-port port Port on which to run Tilde Friends web server (default: 12345).\n"); tf_printf(" -p, --http-port port Port on which to run Tilde Friends web server (default: 12345).\n");
tf_printf(" -q, --https-port port Port on which to run secure Tilde Friends web server (default: 12346).\n"); tf_printf(" -q, --https-port port Port on which to run secure Tilde Friends web server (default: 12346).\n");
tf_printf(" -d, --db-path path SQLite database path (default: %s).\n", k_db_path_default); tf_printf(" -d, --db-path path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -k, --ssb-network-key key SSB network key to use.\n"); tf_printf(" -k, --ssb-network-key key SSB network key to use.\n");
tf_printf(" -n, --count count Number of instances to run.\n"); tf_printf(" -n, --count count Number of instances to run.\n");
tf_printf(" -a, --args args Arguments of the format key=value,foo=bar,verbose=true.\n"); tf_printf(" -a, --args args Arguments of the format key=value,foo=bar,verbose=true.\n");
@ -772,6 +889,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
tf_printf(" -z, --zip path Zip archive from which to load files.\n"); tf_printf(" -z, --zip path Zip archive from which to load files.\n");
tf_printf(" -v, --verbose Log raw messages.\n"); tf_printf(" -v, --verbose Log raw messages.\n");
tf_printf(" -h, --help Show this usage information.\n"); tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -780,6 +898,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
setpgid(0, 0); setpgid(0, 0);
#endif #endif
_create_directories_for_file(args.db_path, 0700);
if (args.count == 1) if (args.count == 1)
{ {
result = _tf_run_task(&args, 0); result = _tf_run_task(&args, 0);
@ -807,6 +926,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
tf_free(data); tf_free(data);
tf_free(threads); tf_free(threads);
} }
tf_free((void*)default_db_path);
return result; return result;
} }
@ -1088,7 +1208,7 @@ void tf_run_thread_start(const char* zip_path)
.http_port = 12345, .http_port = 12345,
.https_port = 12346, .https_port = 12346,
.ssb_port = 8008, .ssb_port = 8008,
.db_path = k_db_path_default, .db_path = "db.sqlite",
.one_proc = true, .one_proc = true,
.zip = zip_path, .zip = zip_path,
}; };

View File

@ -1,2 +1,2 @@
#define VERSION_NUMBER "0.0.26" #define VERSION_NUMBER "0.0.27-wip"
#define VERSION_NAME "This program kills fascists." #define VERSION_NAME "This program kills fascists."

89
tools/ssl-local Executable file
View File

@ -0,0 +1,89 @@
#!/bin/bash
BUILD_PLATFORM=$(uname -s)
if [[ -z $BUILD_TARGET ]]; then
BUILD_TARGET=$(uname -m)
WORK_DIR=out/openssl-local
else
WORK_DIR=out/openssl-$BUILD_TARGET
SSL_TARGET=linux-$BUILD_TARGET
fi
rm -rf $WORK_DIR
cp -aRf deps/openssl_src/ $WORK_DIR
echo "Building"
pwd
pushd $WORK_DIR || exit 128
rm -rf $DESTDIR
echo $PATH
export GLOBAL_OPTIONS="
no-apps
no-asm
no-async
no-autoerrinit
no-autoload-config
no-cmp
no-cms
no-comp
no-deprecated
no-dgram
no-docs
no-dsa
no-dso
no-dtls
no-dtls1
no-dtls1-method
no-dynamic-engine
no-ec2m
no-egd
no-engine
no-err
no-filenames
no-gost
no-http
no-idea
no-legacy
no-md2
no-md4
no-module
no-multiblock
no-nextprotoneg
no-ocsp
no-psk
no-shared
no-sock
no-srp
no-ssl
no-ssl3
no-ssl-trace
no-stdio
no-tests
no-thread-pool
no-threads
no-tls1
no-tls1-method
no-trace
no-ui-console
no-uplink
no-whirlpool
no-weak-ssl-ciphers
no-zlib
-Os
-DOPENSSL_SMALL_FOOTPRINT
-flto"
pwd
echo "./Configure $SSL_TARGET $OPTIONS $GLOBAL_OPTIONS" && \
./Configure $SSL_TARGET $OPTIONS $GLOBAL_OPTIONS && \
make -s clean && \
make -s build_generated && \
make -s libcrypto.a libssl.a || exit 128
popd
echo WORK_DIR=$WORK_DIR
rm -rf deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/
mkdir -p deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/include/
mkdir -p deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/lib/
cp -R $WORK_DIR/include/* deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/include/
cp $WORK_DIR/*.a deps/openssl/$BUILD_PLATFORM/$BUILD_TARGET/usr/local/lib/
echo Success