diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8a9b99f76..583fb00fc 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -19,11 +19,11 @@ jobs: include: - name: linux-amd64 cmd: >- - make && (make test || make test) && make check && make ci-lexicons + make linux-amd64 && make test && make check && make ci-lexicons - name: linux-arm64 - cmd: "make app && make linux-arm64" + cmd: "make linux-arm64" - name: windows-amd64 - cmd: "make app && make windows-amd64 && make desktop-windows-amd64" + cmd: "make windows-amd64 && make desktop-windows-amd64" - name: android cmd: "make app && make android-release" steps: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 86ad488b4..02591d5d3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -71,7 +71,7 @@ builder-rebuild: script: - rm -rf /usr/x86_64-w64-mingw32/include/d3dcompiler.h /usr/share/mingw-w64/include/d3dcompiler.h /usr/lib/gcc/x86_64-w64-mingw32/10-posix/libssp.dll.a /usr/lib/gcc/x86_64-w64-mingw32/10-posix/libssp-0.dll /usr/lib/gcc/x86_64-w64-mingw32/10-win32/libssp-0.dll /usr/lib/gcc/x86_64-w64-mingw32/10-win32/libssp.dll.a - git fetch --unshallow || echo 'already unshallow' - - bash -c "make version && make app && make $TARGET && make desktop-$TARGET && make pkg-$TARGET && make ci-upload-node-$TARGET -j$(nproc)" + - bash -c "make version && make $TARGET && make desktop-$TARGET && make pkg-$TARGET && make ci-upload-node-$TARGET -j$(nproc)" artifacts: reports: dotenv: .ci/build.env diff --git a/Makefile b/Makefile index 54bdc89be..5330957b5 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ OUT_DIR?="bin" $(shell mkdir -p $(OUT_DIR)) .PHONY: default -default: app node +default: streamplace VERSION?=$(shell go run ./pkg/config/git/git.go -v) VERSION_NO_V=$(subst v,,$(VERSION)) @@ -23,241 +23,39 @@ ifeq ($(BUILDOS),darwin) MACOS_VERSION_FLAG=-mmacosx-version-min=$(shell sw_vers -productVersion) endif BUILDDIR?=build-$(BUILDOS)-$(BUILDARCH) -SHARED_PKG_CONFIG_PATH=$(shell pwd)/$(BUILDDIR)/lib/pkgconfig +PKG_CONFIG_PATH=$(shell pwd)/$(BUILDDIR)/lib/pkgconfig:$(shell pwd)/$(BUILDDIR)/lib/gstreamer-1.0/pkgconfig:$(shell pwd)/$(BUILDDIR)/meson-uninstalled .PHONY: version version: @go run ./pkg/config/git/git.go -v \ && go run ./pkg/config/git/git.go --env -o .ci/build.env +# _____ _____ +# /\ | __ \| __ \ +# / \ | |__) | |__) | +# / /\ \ | ___/| ___/ +# / ____ \| | | | +# /_/ \_\_| |_| + +# front-end stuff innit + .PHONY: install install: pnpm install -.PHONY: app-and-node -app-and-node: - $(MAKE) app - $(MAKE) node - -.PHONY: app-and-node-and-test -app-and-node-and-test: - $(MAKE) app - $(MAKE) node - $(MAKE) test .PHONY: app -app: schema install - pnpm run build - -.PHONY: node -node: schema - $(MAKE) meson-setup - meson compile -C $(BUILDDIR) streamplace - meson install --no-rebuild -C $(BUILDDIR) - -js/app/dist/index.html: install +app: install pnpm run build -.PHONY: dev-setup -dev-setup: schema install js/app/dist/index.html - $(MAKE) dev-setup-meson - $(MAKE) dev - -.PHONY: dev-setup-meson -dev-setup-meson: - $(MAKE) dev-setup-meson-configure - $(MAKE) dev-setup-meson-compile - -.PHONY: dev-setup-meson-configure -dev-setup-meson-configure: - if ! which uniffi-bindgen-go; then cargo install uniffi-bindgen-go --git https://github.com/NordSecurity/uniffi-bindgen-go --tag v0.3.0+v0.28.3; fi - meson setup --default-library=shared $(BUILDDIR) $(SHARED_OPTS) - meson configure --default-library=shared $(BUILDDIR) $(SHARED_OPTS) - -.PHONY: dev-setup-meson-compile -dev-setup-meson-compile: - meson install -C $(BUILDDIR) - -.PHONY: dev-rust -dev-rust: - cargo build - EXT=so; \ - if [ "$(BUILDOS)" = "darwin" ]; then EXT=dylib; fi; \ - uniffi-bindgen-go --out-dir pkg/iroh/generated --library ./target/debug/libiroh_streamplace.$$EXT \ - && cp ./target/debug/libiroh_streamplace.$$EXT $(BUILDDIR)/rust/iroh-streamplace/libiroh_streamplace.$$EXT \ - && cp ./target/debug/libiroh_streamplace.$$EXT $(BUILDDIR)/lib/libiroh_streamplace.$$EXT - -.PHONY: dev -dev: - cp ./util/streamplace-dev.sh $(BUILDDIR)/streamplace - $(MAKE) dev-rust - PKG_CONFIG_PATH=$(SHARED_PKG_CONFIG_PATH) \ - CGO_LDFLAGS="$(MACOS_VERSION_FLAG)" go build -o $(BUILDDIR)/libstreamplace ./cmd/libstreamplace/... - -.PHONY: golangci-lint -golangci-lint: - @PKG_CONFIG_PATH=$(SHARED_PKG_CONFIG_PATH) \ - go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint run -c ./.golangci.yaml - -.PHONY: dev-test -dev-test: - PKG_CONFIG_PATH=$(SHARED_PKG_CONFIG_PATH) \ - go test -p 1 -timeout 300s ./... - -.PHONY: schema -schema: - mkdir -p js/app/generated \ - && go run pkg/crypto/signers/eip712/export-schema/export-schema.go > js/app/generated/eip712-schema.json - -.PHONY: lexicons -lexicons: - $(MAKE) go-lexicons \ - && $(MAKE) js-lexicons \ - && $(MAKE) md-lexicons \ - && make fix - -.PHONY: go-lexicons -go-lexicons: - rm -rf ./pkg/streamplace \ - && mkdir -p ./pkg/streamplace \ - && rm -rf ./pkg/streamplace/cbor_gen.go \ - && $(MAKE) lexgen \ - && sed -i.bak 's/\tutil/\/\/\tutil/' $$(find ./pkg/streamplace -type f) \ - && go run golang.org/x/tools/cmd/goimports@latest -w $$(find ./pkg/streamplace -type f) \ - && go run ./pkg/gen/gen.go \ - && $(MAKE) lexgen \ - && find . | grep bak$$ | xargs rm \ - && rm -rf api - -.PHONY: js-lexicons -js-lexicons: - node_modules/.bin/lex gen-api ./js/streamplace/src/lexicons $$(find ./lexicons -type f -name '*.json') --yes \ - && rm -rf ./js/streamplace/src/lexicons/types/com ./js/streamplace/src/lexicons/types/app \ - && sed -i.bak "s/^..port.*app\/bsky.*//g" $$(find ./js/streamplace/src/lexicons -type f) \ - && sed -i.bak "s/^..port.*com\/atproto.*//g" $$(find ./js/streamplace/src/lexicons -type f) \ - && sed -i.bak "s/\(..port .*\)\.js\(.*\)/\1\2/g" $$(find ./js/streamplace/src/lexicons -type f) \ - && sed -i.bak 's/AppBskyGraphBlock\.Main/AppBskyGraphBlock\.Record/' $$(find ./js/streamplace/src/lexicons/types/place/stream -type f) \ - && sed -i.bak 's/PlaceStreamChatProfile\.Main/PlaceStreamChatProfile\.Record/' $$(find ./js/streamplace/src/lexicons/types/place/stream -type f) \ - && for x in $$(find ./js/streamplace/src/lexicons -type f -name '*.ts'); do \ - echo 'import { AppBskyRichtextFacet, AppBskyGraphBlock, ComAtprotoRepoStrongRef, AppBskyActorDefs, ComAtprotoSyncListRepos, AppBskyActorGetProfile, AppBskyFeedGetFeedSkeleton, ComAtprotoIdentityResolveHandle, ComAtprotoModerationCreateReport, ComAtprotoRepoCreateRecord, ComAtprotoRepoDeleteRecord, ComAtprotoRepoDescribeRepo, ComAtprotoRepoGetRecord, ComAtprotoRepoListRecords, ComAtprotoRepoPutRecord, ComAtprotoRepoUploadBlob, ComAtprotoServerDescribeServer, ComAtprotoSyncGetRecord, ComAtprotoSyncListReposComAtprotoRepoCreateRecord, ComAtprotoRepoDeleteRecord, ComAtprotoRepoGetRecord, ComAtprotoRepoListRecords } from "@atproto/api"' >> $$x; \ - done \ - && npx prettier --write $$(find ./js/streamplace/src/lexicons -type f -name '*.ts') \ - && find . | grep bak$$ | xargs rm - - -.PHONY: md-lexicons -md-lexicons: - pnpm exec lexmd \ - ./lexicons \ - .build/temp \ - subprojects/atproto/lexicons \ - js/docs/src/content/docs/lex-reference/openapi.json \ - && ls -R .build/temp \ - && cp -rf .build/temp/place/stream/* js/docs/src/content/docs/lex-reference/ \ - && rm -rf .build/temp \ - && $(MAKE) fix - -.PHONY: lexgen -lexgen: - $(MAKE) lexgen-types - $(MAKE) lexgen-server - -.PHONY: lexgen-types -lexgen-types: - go run github.com/bluesky-social/indigo/cmd/lexgen \ - -outdir ./pkg/spxrpc \ - --build-file util/lexgen-types.json \ - --external-lexicons subprojects/atproto/lexicons \ - lexicons/place/stream \ - ./subprojects/atproto/lexicons - -.PHONY: lexgen-server -lexgen-server: - mkdir -p ./pkg/spxrpc \ - && go run github.com/bluesky-social/indigo/cmd/lexgen \ - --gen-server \ - --types-import place.stream:stream.place/streamplace/pkg/streamplace \ - --types-import app.bsky:github.com/bluesky-social/indigo/api/bsky \ - --types-import com.atproto:github.com/bluesky-social/indigo/api/atproto \ - --types-import chat.bsky:github.com/bluesky-social/indigo/api/chat \ - --types-import tools.ozone:github.com/bluesky-social/indigo/api/ozone \ - -outdir ./pkg/spxrpc \ - --build-file util/lexgen-types.json \ - --external-lexicons subprojects/atproto/lexicons \ - --package spxrpc \ - lexicons/place/stream \ - lexicons/app/bsky \ - lexicons/com/atproto - -.PHONY: ci-lexicons -ci-lexicons: - $(MAKE) lexicons \ - && if ! git diff --exit-code >/dev/null; then echo "lexicons are out of date, run 'make lexicons' to fix"; exit 1; fi - -.PHONY: test -test: - meson test -C $(BUILDDIR) go-tests - -# test to make sure we haven't added any more dynamic dependencies -LINUX_LINK_COUNT=5 -.PHONY: link-test-linux -link-test-linux: - count=$(shell ldd ./build-linux-amd64/streamplace | wc -l) \ - && echo $$count \ - && if [ "$$count" != "$(LINUX_LINK_COUNT)" ]; then echo "ldd reports new libaries linked! want $(LINUX_LINK_COUNT) got $$count" \ - && ldd ./build-linux-amd64/streamplace \ - && exit 1; \ - fi - -MACOS_LINK_COUNT=10 -.PHONY: link-test-macos -link-test-macos: - count=$(shell otool -L ./build-darwin-arm64/streamplace | wc -l | xargs) \ - && echo $$count \ - && if [ "$$count" != "$(MACOS_LINK_COUNT)" ]; then echo "otool -L reports new libaries linked! want $(MACOS_LINK_COUNT) got $$count" \ - && otool -L ./build-darwin-arm64/streamplace \ - && exit 1; \ - fi - -WINDOWS_LINK_COUNT=19 -.PHONY: link-test-windows -link-test-windows: - count=$(shell x86_64-w64-mingw32-objdump -p ./build-windows-amd64/streamplace.exe | grep "DLL Name" | tr '[:upper:]' '[:lower:]' | sort | uniq | wc -l | xargs) \ - && echo $$count \ - && if [ "$$count" != "$(WINDOWS_LINK_COUNT)" ]; then echo "x86_64-w64-mingw32-objdump -p reports new libaries linked! want $(WINDOWS_LINK_COUNT) got $$count" \ - && x86_64-w64-mingw32-objdump -p ./build-windows-amd64/streamplace.exe | grep "DLL Name" \ - && exit 1; \ - fi - -.PHONY: all -all: version install app test node-all-platforms android - -.PHONY: ci -ci: version install app node-all-platforms ci-upload-node +.PHONY: app-cached +app-cached: + if [ ! -f js/app/dist/index.html ]; then $(MAKE) app; else echo "js/app/dist/index.html exists, not rebuilding, run make app to rebuild"; fi .PHONY: ci-ios ci-ios: version install app $(MAKE) ios $(MAKE) ci-upload-ios -.PHONY: ci-desktop-darwin -ci-desktop-darwin: version install - ./util/mac-codesign.sh \ - && for arch in amd64 arm64; do \ - curl -v --fail-with-body -O "$$CI_API_V4_URL/projects/$$CI_PROJECT_ID/packages/generic/$(BRANCH)/$(VERSION)/streamplace-$(VERSION)-darwin-$$arch.tar.gz" || exit 1 \ - && tar -xzvf streamplace-$(VERSION)-darwin-$$arch.tar.gz \ - && ./streamplace --version \ - && ./streamplace self-test \ - && mkdir -p build-darwin-$$arch \ - && mv ./streamplace ./build-darwin-$$arch/streamplace; \ - done \ - && $(MAKE) desktop-darwin \ - && for arch in amd64 arm64; do \ - export file=streamplace-desktop-$(VERSION)-darwin-$$arch.zip \ - && $(MAKE) ci-upload-file upload_file=$$file \ - && export file=streamplace-desktop-$(VERSION)-darwin-$$arch.dmg \ - && $(MAKE) ci-upload-file upload_file=$$file; \ - done - .PHONY: ci-android ci-android: version install android ci-upload-android @@ -273,15 +71,6 @@ ci-android-release: version install $(MAKE) android-release $(MAKE) ci-upload-android-release -.PHONY: ci-test -ci-test: app - meson setup $(BUILDDIR) $(OPTS) - meson test -C $(BUILDDIR) go-tests - -.PHONY: ci-npm-release -ci-npm-release: install - echo //registry.npmjs.org/:_authToken=$$NPM_TOKEN > ~/.npmrc \ - && npx lerna publish from-package --yes ANDROID_KEYSTORE_PASSWORD?=streamplace ANDROID_KEYSTORE_ALIAS?=alias_name @@ -339,11 +128,23 @@ ios: app && cd bin \ && tar -czvf streamplace-$(VERSION)-ios-release.xcarchive.tar.gz streamplace-$(VERSION)-ios-release.xcarchive -# xcodebuild -exportArchive -archivePath ./bin/streamplace-$(VERSION)-ios-release.xcarchive -exportOptionsPlist ./js/app/exportOptions.plist -exportPath ./bin/streamplace-$(VERSION)-ios-release.ipa +# _____ ____ +# / ____|/ __ \ +# | | __| | | | +# | | |_ | | | | +# | |__| | |__| | +# \_____|\____/ -.build/bundletool.jar: - mkdir -p .build \ - && curl -L -o ./.build/bundletool.jar https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar +.PHONY: rtcrec +rtcrec: + go build -o $(BUILDDIR)/rtcrec ./pkg/rtcrec/cmd/... + +# __ __ ______ _____ ____ _ _ +# | \/ | ____|/ ____|/ __ \| \ | | +# | \ / | |__ | (___ | | | | \| | +# | |\/| | __| \___ \| | | | . ` | +# | | | | |____ ____) | |__| | |\ | +# |_| |_|______|_____/ \____/|_| \_| BASE_OPTS = \ --buildtype=debugoptimized \ @@ -400,20 +201,317 @@ BASE_OPTS = \ -D "gst-libav:glib_assert=false" \ -D "gst-plugins-good:adaptivedemux2=disabled" -OPTS = \ - $(BASE_OPTS) \ - -D "gstreamer-full:gst-full-target-type=static_library" \ - -D "gstreamer:registry=false" +STATIC_OPTS = \ + $(BASE_OPTS) \ + -D "gstreamer-full:gst-full-target-type=static_library" \ + -D "gstreamer:registry=false" + +SHARED_OPTS = \ + $(BASE_OPTS) \ + -D "FFmpeg:default_library=shared" \ + -D "gstreamer:registry=true" + +.PHONY: meson +meson: + $(MAKE) meson-setup + $(MAKE) meson-compile + +MESON_SETUP_OPTS?= +.PHONY: meson-setup +meson-setup: + @meson setup $(BUILDDIR) $(MESON_SETUP_OPTS) + @meson configure $(BUILDDIR) $(OPTS) + +.PHONY: meson-setup-static +meson-setup-static: + @meson setup $(BUILDDIR) $(MESON_SETUP_OPTS) $(STATIC_OPTS) + @meson configure $(BUILDDIR) $(STATIC_OPTS) + +.PHONY: meson-compile +meson-compile: + meson install -C $(BUILDDIR) + + +# _____ _______ _______ _____ _____ +# / ____|__ __|/\|__ __|_ _/ ____| +# | (___ | | / \ | | | || | +# \___ \ | | / /\ \ | | | || | +# ____) | | |/ ____ \| | _| || |____ +# |_____/ |_/_/ \_\_| |_____\_____| + +# Production distributions of Streamplace with bundled node and app. + +static: + $(MAKE) meson-setup meson-compile app OPTS=$(STATIC_OPTS) -j16 + $(MAKE) streamplace + +.PHONY: static-test +static-test: + meson test -C $(BUILDDIR) go-tests + +# _____ ________ __ +# | __ \| ____\ \ / / +# | | | | |__ \ \ / / +# | | | | __| \ \/ / +# | |__| | |____ \ / +# |_____/|______| \/ + +# Local builds of Streamplace with node and app. + +.PHONY: dev-setup +dev-setup: + $(MAKE) -j16 app-cached dev-setup-meson + +.PHONY: dev +dev: app-cached + if [ ! -d $(BUILDDIR) ]; then $(MAKE) dev-setup; fi + cp ./util/streamplace-dev.sh $(BUILDDIR)/streamplace + $(MAKE) dev-rust + PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) \ + CGO_LDFLAGS="$(MACOS_VERSION_FLAG)" \ + LD_LIBRARY_PATH=$(BUILDDIR)/lib go build -o $(BUILDDIR)/libstreamplace ./cmd/libstreamplace/... + +.PHONY: dev-setup-meson +dev-setup-meson: + $(MAKE) dev-setup-meson-configure + $(MAKE) meson-compile + +.PHONY: dev-setup-meson-configure +dev-setup-meson-configure: + if ! which uniffi-bindgen-go; then cargo install uniffi-bindgen-go --git https://github.com/NordSecurity/uniffi-bindgen-go --tag v0.3.0+v0.28.3; fi + meson setup --default-library=shared $(BUILDDIR) $(SHARED_OPTS) + meson configure --default-library=shared $(BUILDDIR) $(SHARED_OPTS) + +.PHONY: dev-rust +dev-rust: + cargo build + EXT=so; \ + if [ "$(BUILDOS)" = "darwin" ]; then EXT=dylib; fi; \ + uniffi-bindgen-go --out-dir pkg/iroh/generated --library ./target/debug/libiroh_streamplace.$$EXT \ + && cp ./target/debug/libiroh_streamplace.$$EXT $(BUILDDIR)/rust/iroh-streamplace/libiroh_streamplace.$$EXT \ + && cp ./target/debug/libiroh_streamplace.$$EXT $(BUILDDIR)/lib/libiroh_streamplace.$$EXT + +.PHONY: dev-test +dev-test: + PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) \ + LD_LIBRARY_PATH=$(shell realpath $(BUILDDIR))/lib \ + go test -p 1 -timeout 300s ./... + +# _ _____ _ _ _______ _____ _ _ _____ +# | | |_ _| \ | |__ __|_ _| \ | |/ ____| +# | | | | | \| | | | | | | \| | | __ +# | | | | | . ` | | | | | | . ` | | |_ | +# | |____ _| |_| |\ | | | _| |_| |\ | |__| | +# |______|_____|_| \_| |_| |_____|_| \_|\_____| + +.PHONY: check +check: install + $(MAKE) golangci-lint + pnpm run check + if [ "`gofmt -l . | wc -l`" -gt 0 ]; then echo 'gofmt failed, run make fix'; exit 1; fi + +.PHONY: fix +fix: + pnpm run fix + gofmt -w . + +.PHONY: golangci-lint +golangci-lint: + @PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) \ + go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint run -c ./.golangci.yaml + +# _ ________ _______ _____ ____ _ _ _____ +# | | | ____\ \ / /_ _/ ____/ __ \| \ | |/ ____| +# | | | |__ \ V / | || | | | | | \| | (___ +# | | | __| > < | || | | | | | . ` |\___ \ +# | |____| |____ / . \ _| || |___| |__| | |\ |____) | +# |______|______/_/ \_\_____\_____\____/|_| \_|_____/ + +# Mostly codegen for lexicons. + +.PHONY: lexicons +lexicons: + $(MAKE) go-lexicons \ + && $(MAKE) js-lexicons \ + && $(MAKE) md-lexicons \ + && make fix + +.PHONY: go-lexicons +go-lexicons: + rm -rf ./pkg/streamplace \ + && mkdir -p ./pkg/streamplace \ + && rm -rf ./pkg/streamplace/cbor_gen.go \ + && $(MAKE) lexgen \ + && sed -i.bak 's/\tutil/\/\/\tutil/' $$(find ./pkg/streamplace -type f) \ + && go run golang.org/x/tools/cmd/goimports@latest -w $$(find ./pkg/streamplace -type f) \ + && go run ./pkg/gen/gen.go \ + && $(MAKE) lexgen \ + && find . | grep bak$$ | xargs rm \ + && rm -rf api + +.PHONY: js-lexicons +js-lexicons: + node_modules/.bin/lex gen-api ./js/streamplace/src/lexicons $$(find ./lexicons -type f -name '*.json') --yes \ + && rm -rf ./js/streamplace/src/lexicons/types/com ./js/streamplace/src/lexicons/types/app \ + && sed -i.bak "s/^..port.*app\/bsky.*//g" $$(find ./js/streamplace/src/lexicons -type f) \ + && sed -i.bak "s/^..port.*com\/atproto.*//g" $$(find ./js/streamplace/src/lexicons -type f) \ + && sed -i.bak "s/\(..port .*\)\.js\(.*\)/\1\2/g" $$(find ./js/streamplace/src/lexicons -type f) \ + && sed -i.bak 's/AppBskyGraphBlock\.Main/AppBskyGraphBlock\.Record/' $$(find ./js/streamplace/src/lexicons/types/place/stream -type f) \ + && sed -i.bak 's/PlaceStreamChatProfile\.Main/PlaceStreamChatProfile\.Record/' $$(find ./js/streamplace/src/lexicons/types/place/stream -type f) \ + && for x in $$(find ./js/streamplace/src/lexicons -type f -name '*.ts'); do \ + echo 'import { AppBskyRichtextFacet, AppBskyGraphBlock, ComAtprotoRepoStrongRef, AppBskyActorDefs, ComAtprotoSyncListRepos, AppBskyActorGetProfile, AppBskyFeedGetFeedSkeleton, ComAtprotoIdentityResolveHandle, ComAtprotoModerationCreateReport, ComAtprotoRepoCreateRecord, ComAtprotoRepoDeleteRecord, ComAtprotoRepoDescribeRepo, ComAtprotoRepoGetRecord, ComAtprotoRepoListRecords, ComAtprotoRepoPutRecord, ComAtprotoRepoUploadBlob, ComAtprotoServerDescribeServer, ComAtprotoSyncGetRecord, ComAtprotoSyncListReposComAtprotoRepoCreateRecord, ComAtprotoRepoDeleteRecord, ComAtprotoRepoGetRecord, ComAtprotoRepoListRecords } from "@atproto/api"' >> $$x; \ + done \ + && npx prettier --write $$(find ./js/streamplace/src/lexicons -type f -name '*.ts') \ + && find . | grep bak$$ | xargs rm + +.PHONY: md-lexicons +md-lexicons: + pnpm exec lexmd \ + ./lexicons \ + .build/temp \ + subprojects/atproto/lexicons \ + js/docs/src/content/docs/lex-reference/openapi.json \ + && ls -R .build/temp \ + && cp -rf .build/temp/place/stream/* js/docs/src/content/docs/lex-reference/ \ + && rm -rf .build/temp \ + && $(MAKE) fix + +.PHONY: lexgen +lexgen: + $(MAKE) lexgen-types + $(MAKE) lexgen-server + +.PHONY: lexgen-types +lexgen-types: + go run github.com/bluesky-social/indigo/cmd/lexgen \ + -outdir ./pkg/spxrpc \ + --build-file util/lexgen-types.json \ + --external-lexicons subprojects/atproto/lexicons \ + lexicons/place/stream \ + ./subprojects/atproto/lexicons + +.PHONY: lexgen-server +lexgen-server: + mkdir -p ./pkg/spxrpc \ + && go run github.com/bluesky-social/indigo/cmd/lexgen \ + --gen-server \ + --types-import place.stream:stream.place/streamplace/pkg/streamplace \ + --types-import app.bsky:github.com/bluesky-social/indigo/api/bsky \ + --types-import com.atproto:github.com/bluesky-social/indigo/api/atproto \ + --types-import chat.bsky:github.com/bluesky-social/indigo/api/chat \ + --types-import tools.ozone:github.com/bluesky-social/indigo/api/ozone \ + -outdir ./pkg/spxrpc \ + --build-file util/lexgen-types.json \ + --external-lexicons subprojects/atproto/lexicons \ + --package spxrpc \ + lexicons/place/stream \ + lexicons/app/bsky \ + lexicons/com/atproto + +.PHONY: ci-lexicons +ci-lexicons: + $(MAKE) lexicons \ + && if ! git diff --exit-code >/dev/null; then echo "lexicons are out of date, run 'make lexicons' to fix"; exit 1; fi + +# _______ ______ _____ _______ _____ _ _ _____ +# |__ __| ____|/ ____|__ __|_ _| \ | |/ ____| +# | | | |__ | (___ | | | | | \| | | __ +# | | | __| \___ \ | | | | | . ` | | |_ | +# | | | |____ ____) | | | _| |_| |\ | |__| | +# |_| |______|_____/ |_| |_____|_| \_|\_____| + +# test to make sure we haven't added any more dynamic dependencies +LINUX_LINK_COUNT=5 +.PHONY: link-test-linux +link-test-linux: + count=$(shell ldd ./build-linux-amd64/streamplace | wc -l) \ + && echo $$count \ + && if [ "$$count" != "$(LINUX_LINK_COUNT)" ]; then echo "ldd reports new libaries linked! want $(LINUX_LINK_COUNT) got $$count" \ + && ldd ./build-linux-amd64/streamplace \ + && exit 1; \ + fi + +MACOS_LINK_COUNT=10 +.PHONY: link-test-macos +link-test-macos: + count=$(shell otool -L ./build-darwin-arm64/streamplace | wc -l | xargs) \ + && echo $$count \ + && if [ "$$count" != "$(MACOS_LINK_COUNT)" ]; then echo "otool -L reports new libaries linked! want $(MACOS_LINK_COUNT) got $$count" \ + && otool -L ./build-darwin-arm64/streamplace \ + && exit 1; \ + fi + +WINDOWS_LINK_COUNT=19 +.PHONY: link-test-windows +link-test-windows: + count=$(shell x86_64-w64-mingw32-objdump -p ./build-windows-amd64/streamplace.exe | grep "DLL Name" | tr '[:upper:]' '[:lower:]' | sort | uniq | wc -l | xargs) \ + && echo $$count \ + && if [ "$$count" != "$(WINDOWS_LINK_COUNT)" ]; then echo "x86_64-w64-mingw32-objdump -p reports new libaries linked! want $(WINDOWS_LINK_COUNT) got $$count" \ + && x86_64-w64-mingw32-objdump -p ./build-windows-amd64/streamplace.exe | grep "DLL Name" \ + && exit 1; \ + fi -SHARED_OPTS = \ - $(BASE_OPTS) \ - -D "FFmpeg:default_library=shared" \ - -D "gstreamer:registry=true" +.PHONY: ci +ci: version install app node-all-platforms ci-upload-node -.PHONY: meson-setup -meson-setup: - @meson setup $(BUILDDIR) $(OPTS) - @meson configure $(BUILDDIR) $(OPTS) + +.PHONY: ci-desktop-darwin +ci-desktop-darwin: version install + ./util/mac-codesign.sh \ + && for arch in amd64 arm64; do \ + curl -v --fail-with-body -O "$$CI_API_V4_URL/projects/$$CI_PROJECT_ID/packages/generic/$(BRANCH)/$(VERSION)/streamplace-$(VERSION)-darwin-$$arch.tar.gz" || exit 1 \ + && tar -xzvf streamplace-$(VERSION)-darwin-$$arch.tar.gz \ + && ./streamplace --version \ + && ./streamplace self-test \ + && mkdir -p build-darwin-$$arch \ + && mv ./streamplace ./build-darwin-$$arch/streamplace; \ + done \ + && $(MAKE) desktop-darwin \ + && for arch in amd64 arm64; do \ + export file=streamplace-desktop-$(VERSION)-darwin-$$arch.zip \ + && $(MAKE) ci-upload-file upload_file=$$file \ + && export file=streamplace-desktop-$(VERSION)-darwin-$$arch.dmg \ + && $(MAKE) ci-upload-file upload_file=$$file; \ + done + +.PHONY: ci-test +ci-test: app + meson setup $(BUILDDIR) $(OPTS) + meson test -C $(BUILDDIR) go-tests + +.PHONY: ci-npm-release +ci-npm-release: install + echo //registry.npmjs.org/:_authToken=$$NPM_TOKEN > ~/.npmrc \ + && npx lerna publish from-package --yes + +.build/bundletool.jar: + mkdir -p .build \ + && curl -L -o ./.build/bundletool.jar https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar + +.PHONY: selftest-macos +selftest-macos: + js/desktop/out/Streamplace-darwin-arm64/Streamplace.app/Contents/MacOS/Streamplace -- --self-test + +# _____ _____ ____ _____ _____ +# / ____| __ \ / __ \ / ____/ ____| +# | | | |__) | | | | (___| (___ +# | | | _ /| | | |\___ \\___ \ +# | |____| | \ \| |__| |____) |___) | +# \_____|_| \_\\____/|_____/_____/ +# _____ ____ __ __ _____ _____ _ _____ _ _ _____ +# / ____/ __ \| \/ | __ \_ _| | |_ _| \ | |/ ____| +# | | | | | | \ / | |__) || | | | | | | \| | | __ +# | | | | | | |\/| | ___/ | | | | | | | . ` | | |_ | +# | |___| |__| | | | | | _| |_| |____ _| |_| |\ | |__| | +# \_____\____/|_| |_|_| |_____|______|_____|_| \_|\_____| + +# Cross-compiling is exclusively right now from linux-amd64 to: + +# linux-amd64 (native) +# linux-arm64 +# windows-amd64 +# darwin-amd64 +# darwin-arm64 .PHONY: node-all-platforms node-all-platforms: app @@ -455,32 +553,39 @@ desktop-windows-amd64: && mv "js/desktop/out/make/squirrel.windows/x64/streamplace_desktop-$(VERSION_ELECTRON)-full.nupkg" ./bin/streamplace-desktop-$(VERSION)-windows-amd64.$$SUM.nupkg \ && mv "js/desktop/out/make/squirrel.windows/x64/Streamplace-$(VERSION_ELECTRON) Setup.exe" ./bin/streamplace-desktop-$(VERSION)-windows-amd64.exe +.PHONY: streamplace +streamplace: app-cached meson-setup-static + meson compile -C $(BUILDDIR) streamplace | grep -v drectve + +.PHONY: archive +archive: app-cached meson-setup-static + meson compile -C $(BUILDDIR) archive | grep -v drectve + .PHONY: linux-amd64 linux-amd64: - meson setup --buildtype debugoptimized build-linux-amd64 $(OPTS) - meson compile -C build-linux-amd64 archive + $(MAKE) -j $(shell nproc) archive + $(MAKE) link-test-linux .PHONY: linux-arm64 linux-arm64: - rustup target add aarch64-unknown-linux-gnu - meson setup --cross-file util/linux-arm64-gnu.ini --buildtype debugoptimized build-linux-arm64 $(OPTS) - meson compile -C build-linux-arm64 archive + rustup target add aarch64-unknown-linux-gnu \ + && CC=aarch64-linux-gnu-gcc \ + LD=aarch64-linux-gnu-ld \ + CROSS_COMPILE=1 \ + MESON_SETUP_OPTS="--cross-file util/linux-arm64-gnu.ini" \ + BUILDDIR=build-linux-arm64 \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \ + $(MAKE) -j $(shell nproc) archive .PHONY: windows-amd64 windows-amd64: - rustup target add x86_64-pc-windows-gnu - $(MAKE) windows-amd64-meson-setup - meson compile -C build-windows-amd64 archive 2>&1 | grep -v drectve - $(MAKE) link-test-windows - -.PHONY: windows-amd64-meson-setup -windows-amd64-meson-setup: - meson setup --cross-file util/windows-amd64-gnu.ini --buildtype debugoptimized build-windows-amd64 $(OPTS) - -# unbuffer here is a workaround for wine trying to pop up a terminal window and failing -.PHONY: windows-amd64-startup-test -windows-amd64-startup-test: - bash -c 'set -euo pipefail && unbuffer wine64 ./build-windows-amd64/streamplace.exe self-test | cat' + rustup target add x86_64-pc-windows-gnu \ + && CC=x86_64-w64-mingw32-gcc \ + LD=x86_64-w64-mingw32-ld \ + CROSS_COMPILE=1 \ + MESON_SETUP_OPTS="--cross-file util/windows-amd64-gnu.ini" \ + BUILDDIR=build-windows-amd64 \ + $(MAKE) -j $(shell nproc) archive .PHONY: darwin-amd64 darwin-amd64: @@ -491,20 +596,16 @@ darwin-amd64: && export CARGO_TARGET_X86_64_APPLE_DARWIN_LINKER=x86_64-apple-darwin24.4-clang \ && export LD=x86_64-apple-darwin24.4-ld \ && export CROSS_COMPILE=1 \ - && meson setup --buildtype debugoptimized --cross-file util/osxcross-darwin-amd64.ini build-darwin-amd64 $(OPTS) \ - && meson compile -C build-darwin-amd64 subprojects/glib-2.82.4/gio/gioenumtypes_h \ - && meson compile -C build-darwin-amd64 streamplace \ + && export MESON_SETUP_OPTS="--cross-file util/osxcross-darwin-amd64.ini" \ + && export BUILDDIR=build-darwin-amd64 \ + && $(MAKE) -j $(shell nproc) streamplace \ && ./util/osxcross-codesign.sh ./build-darwin-amd64/streamplace \ && mkdir -p bin \ && cd build-darwin-amd64 \ && tar -czvf ../bin/streamplace-$(VERSION)-darwin-amd64.tar.gz ./streamplace \ && cd - -.PHONY: desktop-darwin-amd64 -desktop-darwin-amd64: - echo "TODO" - -.PHONY: darwin-amd64 +.PHONY: darwin-arm64 darwin-arm64: export CC=aarch64-apple-darwin24.4-clang \ && export CC_AARCH64_APPLE_DARWIN=aarch64-apple-darwin24.4-clang \ @@ -513,14 +614,24 @@ darwin-arm64: && export CARGO_TARGET_AARCH64_APPLE_DARWIN_LINKER=aarch64-apple-darwin24.4-clang \ && export LD=aarch64-apple-darwin24.4-ld \ && export CROSS_COMPILE=1 \ - && meson setup --buildtype debugoptimized --cross-file util/osxcross-darwin-arm64.ini build-darwin-arm64 $(OPTS) \ - && meson compile -C build-darwin-arm64 streamplace \ + && export MESON_SETUP_OPTS="--cross-file util/osxcross-darwin-arm64.ini" \ + && export BUILDDIR=build-darwin-arm64 \ + && $(MAKE) -j $(shell nproc) streamplace \ && ./util/osxcross-codesign.sh ./build-darwin-arm64/streamplace \ && mkdir -p bin \ && cd build-darwin-arm64 \ && tar -czvf ../bin/streamplace-$(VERSION)-darwin-arm64.tar.gz ./streamplace \ && cd - +# unbuffer here is a workaround for wine trying to pop up a terminal window and failing +.PHONY: windows-amd64-startup-test +windows-amd64-startup-test: + bash -c 'set -euo pipefail && unbuffer wine64 ./build-windows-amd64/streamplace.exe self-test | cat' + +.PHONY: desktop-darwin-amd64 +desktop-darwin-amd64: + echo "TODO" + .PHONY: desktop-darwin-arm64 desktop-darwin-arm64: echo "TODO" @@ -537,10 +648,6 @@ desktop-darwin: && mv js/desktop/out/make/zip/darwin/x64/Streamplace-darwin-x64-$(VERSION_ELECTRON).zip ./bin/streamplace-desktop-$(VERSION)-darwin-amd64.zip \ && mv js/desktop/out/make/zip/darwin/arm64/Streamplace-darwin-arm64-$(VERSION_ELECTRON).zip ./bin/streamplace-desktop-$(VERSION)-darwin-arm64.zip -.PHONY: selftest-macos -selftest-macos: - js/desktop/out/Streamplace-darwin-arm64/Streamplace.app/Contents/MacOS/Streamplace -- --self-test - # link your local version of mist for dev .PHONY: link-mist link-mist: @@ -565,6 +672,15 @@ link-ffmpeg: rm -rf subprojects/FFmpeg ln -s $$(realpath ../ffmpeg) ./subprojects/FFmpeg +# _____ ____ _____ _ ________ _____ +# | __ \ / __ \ / ____| |/ / ____| __ \ +# | | | | | | | | | ' /| |__ | |__) | +# | | | | | | | | | < | __| | _ / +# | |__| | |__| | |____| . \| |____| | \ \ +# |_____/ \____/ \_____|_|\_\______|_| \_\ + +# Actually, Podman. I'm not sure if these commands will actually run on Docker, untested. + .PHONY: docker docker: docker build -f docker/local.Dockerfile -t dist.stream.place/streamplace/streamplace:local . @@ -581,6 +697,15 @@ BUILDER_TARGET?=builder docker-build-builder: podman build --target=$(BUILDER_TARGET) --os=linux --arch=amd64 -f docker/build.Dockerfile -t dist.stream.place/streamplace/streamplace:$(BUILDER_TARGET) $(DOCKER_BUILD_OPTS) . +.PHONY: precommit +precommit: dockerfile-hash-precommit + +.PHONY: dockefile-hash-precommit +dockerfile-hash-precommit: + @bash -c 'printf "variables:\n DOCKERFILE_HASH: `git hash-object docker/build.Dockerfile`" > .ci/dockerfile-hash.yaml' \ + && git add .ci/dockerfile-hash.yaml + +# tricks the github action for golangci-lint to run inside a container .PHONY: golangci-lint-container golangci-lint-container: docker-build-builder podman run \ @@ -592,17 +717,10 @@ golangci-lint-container: docker-build-builder dist.stream.place/streamplace/streamplace:$(BUILDER_TARGET) \ tail -f /dev/null podman exec golangci-lint mkdir -p js/app/dist - podman exec golangci-lint touch js/app/dist/skip-build.txt - podman exec golangci-lint make node - -.PHONY: docker-build-in-container -docker-build-in-container: - podman run -v $$(pwd):$$(pwd) -w $$(pwd) --rm -it dist.stream.place/streamplace/streamplace:$(BUILDER_TARGET) make app-and-node - -.PHONY: docker-test-in-container -docker-test-in-container: - podman run -v $$(pwd):$$(pwd) -w $$(pwd) --rm -it dist.stream.place/streamplace/streamplace:$(BUILDER_TARGET) make app-and-node-and-test + podman exec golangci-lint touch js/app/dist/index.html + podman exec golangci-lint make dev +# runs a command in the build container, building if necessary IN_CONTAINER_CMD?=echo 'usage: make in-container IN_CONTAINER_CMD=\"\"' DOCKER_BIN?=podman DOCKER_REF?=dist.stream.place/streamplace/streamplace:$(BUILDER_TARGET) @@ -611,6 +729,10 @@ DOCKER_OPTS?= in-container: docker-build-builder $(DOCKER_BIN) run $(DOCKER_OPTS) -v $$(pwd):$$(pwd) -w $$(pwd) --rm $(DOCKER_REF) bash -c "$(IN_CONTAINER_CMD)" +.PHONY: docker-shell +docker-shell: + $(MAKE) in-container IN_CONTAINER_CMD="bash" DOCKER_OPTS="-it -v $$(pwd):$$(pwd) -w $$(pwd)" + STREAMPLACE_URL?=https://git.stream.place/streamplace/streamplace/-/package_files/10122/download .PHONY: docker-release docker-release: @@ -628,7 +750,53 @@ docker-mistserver: --build-arg TARGETARCH=$(BUILDARCH) \ --build-arg STREAMPLACE_URL=$(STREAMPLACE_URL) \ -t dist.stream.place/streamplace/streamplace:mistserver \ - . + +# _____ _____ _____ _______ _____ ____ +# | __ \_ _|/ ____|__ __| __ \ / __ \ +# | | | || | | (___ | | | |__) | | | | +# | | | || | \___ \ | | | _ /| | | | +# | |__| || |_ ____) | | | | | \ \| |__| | +# |_____/_____|_____/ |_| |_| \_\\____/ + +# distro: cut new versions, build apt and brew packages, upload to S3/gitlab + +.PHONY: release +release: install + $(MAKE) lexicons + pnpm run release + +.PHONY: ci-release +ci-release: + go install gitlab.com/gitlab-org/release-cli/cmd/release-cli + go run ./pkg/config/git/git.go -release -o release.yml + release-cli create-from-file --file release.yml + +.PHONY: homebrew +homebrew: + $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-linux-amd64.tar.gz + $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-linux-arm64.tar.gz + $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-darwin-amd64.tar.gz + $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-darwin-arm64.tar.gz + git clone git@github.com:streamplace/homebrew-streamplace.git /tmp/homebrew-streamplace + go run ./pkg/config/git/git.go -homebrew -o /tmp/homebrew-streamplace/Formula/streamplace.rb + +.PHONY: ci-homebrew +ci-homebrew: + git config --global user.name "Streamplace Homebrew Robot" + git config --global user.email support@stream.place + mkdir -p ~/.ssh + echo "Host * \n\ + StrictHostKeyChecking no \n\ + UserKnownHostsFile=/dev/null" > ~/.ssh/config + echo "$$CI_HOMEBREW_KEY_BASE64" | base64 -d > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + + chmod 600 ~/.ssh/config + $(MAKE) homebrew + cd /tmp/homebrew-streamplace \ + && git add . \ + && git commit -m "Update streamplace $(VERSION)" \ + && git push FPM_BASE_OPTS= \ -s dir \ @@ -681,6 +849,40 @@ pkg-darwin-arm64: pkg-windows-amd64: echo todo +.PHONY: deb-release +deb-release: + aptly repo create -distribution=all -component=main streamplace-releases + aptly mirror create old-version $$S3_PUBLIC_URL/debian all + aptly mirror update old-version + aptly repo import old-version streamplace-releases streamplace streamplace-default-http + aptly repo add streamplace-releases \ + bin/streamplace-default-http-$(VERSION)-linux-arm64.deb \ + bin/streamplace-$(VERSION)-linux-arm64.deb \ + bin/streamplace-default-http-$(VERSION)-linux-amd64.deb \ + bin/streamplace-$(VERSION)-linux-amd64.deb + aptly snapshot create streamplace-$(VERSION) from repo streamplace-releases + aptly publish snapshot -distribution=all streamplace-$(VERSION) s3:streamplace-releases: + +.PHONY: ci-deb-release +ci-deb-release: + $(MAKE) ci-download-file download_file=streamplace-default-http-$(VERSION)-linux-amd64.deb + $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-linux-amd64.deb + $(MAKE) ci-download-file download_file=streamplace-default-http-$(VERSION)-linux-arm64.deb + $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-linux-arm64.deb + echo $$CI_SIGNING_KEY_BASE64 | base64 -d | gpg --import + gpg --armor --export | gpg --no-default-keyring --keyring trustedkeys.gpg --import + echo '{"S3PublishEndpoints":{"streamplace-releases":{"region":"'$$S3_REGION'","bucket":"'$$S3_BUCKET_NAME'","endpoint":"'$$S3_ENDPOINT'","acl":"public-read","prefix":"debian"}}}' > ~/.aptly.conf + $(MAKE) deb-release + +# _____ _____ +# / ____|_ _| +# | | | | +# | | | | +# | |____ _| |_ +# \_____|_____| + +# mostly "do a thing and then gitlab upload the artifact" + .PHONY: ci-upload ci-upload: ci-upload-node ci-upload-android @@ -767,89 +969,3 @@ ci-download-file: --header "JOB-TOKEN: $$CI_JOB_TOKEN" \ -o bin/$(download_file) \ "$$CI_API_V4_URL/projects/$$CI_PROJECT_ID/packages/generic/$(BRANCH)/$(VERSION)/$(download_file)"; - -.PHONY: release -release: install - $(MAKE) lexicons - pnpm run release - -.PHONY: ci-release -ci-release: - go install gitlab.com/gitlab-org/release-cli/cmd/release-cli - go run ./pkg/config/git/git.go -release -o release.yml - release-cli create-from-file --file release.yml - -.PHONY: deb-release -deb-release: - aptly repo create -distribution=all -component=main streamplace-releases - aptly mirror create old-version $$S3_PUBLIC_URL/debian all - aptly mirror update old-version - aptly repo import old-version streamplace-releases streamplace streamplace-default-http - aptly repo add streamplace-releases \ - bin/streamplace-default-http-$(VERSION)-linux-arm64.deb \ - bin/streamplace-$(VERSION)-linux-arm64.deb \ - bin/streamplace-default-http-$(VERSION)-linux-amd64.deb \ - bin/streamplace-$(VERSION)-linux-amd64.deb - aptly snapshot create streamplace-$(VERSION) from repo streamplace-releases - aptly publish snapshot -distribution=all streamplace-$(VERSION) s3:streamplace-releases: - -.PHONY: ci-deb-release -ci-deb-release: - $(MAKE) ci-download-file download_file=streamplace-default-http-$(VERSION)-linux-amd64.deb - $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-linux-amd64.deb - $(MAKE) ci-download-file download_file=streamplace-default-http-$(VERSION)-linux-arm64.deb - $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-linux-arm64.deb - echo $$CI_SIGNING_KEY_BASE64 | base64 -d | gpg --import - gpg --armor --export | gpg --no-default-keyring --keyring trustedkeys.gpg --import - echo '{"S3PublishEndpoints":{"streamplace-releases":{"region":"'$$S3_REGION'","bucket":"'$$S3_BUCKET_NAME'","endpoint":"'$$S3_ENDPOINT'","acl":"public-read","prefix":"debian"}}}' > ~/.aptly.conf - $(MAKE) deb-release - -.PHONY: check -check: install - $(MAKE) golangci-lint - pnpm run check - if [ "`gofmt -l . | wc -l`" -gt 0 ]; then echo 'gofmt failed, run make fix'; exit 1; fi - -.PHONY: fix -fix: - pnpm run fix - gofmt -w . - -.PHONY: precommit -precommit: dockerfile-hash-precommit - -.PHONY: dockefile-hash-precommit -dockerfile-hash-precommit: - @bash -c 'printf "variables:\n DOCKERFILE_HASH: `git hash-object docker/build.Dockerfile`" > .ci/dockerfile-hash.yaml' \ - && git add .ci/dockerfile-hash.yaml - -.PHONY: rtcrec -rtcrec: - go build -o $(BUILDDIR)/rtcrec ./pkg/rtcrec/cmd/... - -.PHONY: homebrew -homebrew: - $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-linux-amd64.tar.gz - $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-linux-arm64.tar.gz - $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-darwin-amd64.tar.gz - $(MAKE) ci-download-file download_file=streamplace-$(VERSION)-darwin-arm64.tar.gz - git clone git@github.com:streamplace/homebrew-streamplace.git /tmp/homebrew-streamplace - go run ./pkg/config/git/git.go -homebrew -o /tmp/homebrew-streamplace/Formula/streamplace.rb - -.PHONY: ci-homebrew -ci-homebrew: - git config --global user.name "Streamplace Homebrew Robot" - git config --global user.email support@stream.place - mkdir -p ~/.ssh - echo "Host * \n\ - StrictHostKeyChecking no \n\ - UserKnownHostsFile=/dev/null" > ~/.ssh/config - echo "$$CI_HOMEBREW_KEY_BASE64" | base64 -d > ~/.ssh/id_ed25519 - chmod 600 ~/.ssh/id_ed25519 - - chmod 600 ~/.ssh/config - $(MAKE) homebrew - cd /tmp/homebrew-streamplace \ - && git add . \ - && git commit -m "Update streamplace $(VERSION)" \ - && git push diff --git a/cmd/libstreamplace/streamplace.go b/cmd/libstreamplace/streamplace.go index 9afa5f7e0..c1c07b4d8 100644 --- a/cmd/libstreamplace/streamplace.go +++ b/cmd/libstreamplace/streamplace.go @@ -10,11 +10,11 @@ import ( "stream.place/streamplace/pkg/log" "stream.place/streamplace/pkg/cmd" + _ "stream.place/streamplace/pkg/streamplacedeps" // _ "github.com/go-gst/go-glib/glib" // _ "github.com/go-gst/go-gst/gst" ) -//#cgo pkg-config: streamplacedeps import "C" var cleanExits = []error{ diff --git a/cmd/streamplace/empty.c b/cmd/streamplace/empty.c index 135736e46..5c7de3050 100644 --- a/cmd/streamplace/empty.c +++ b/cmd/streamplace/empty.c @@ -1,4 +1,7 @@ +// intentionally empty program that we use as atarget to convince meson to +// build all the streamplace dependencies + int main(int argc, char *argv[]) { return 0; -} \ No newline at end of file +} diff --git a/js/desktop/package.json b/js/desktop/package.json index 15b49e28d..4812586c5 100644 --- a/js/desktop/package.json +++ b/js/desktop/package.json @@ -11,7 +11,7 @@ "make": "electron-forge make", "publish": "electron-forge publish", "nolint": "eslint --ext .ts,.tsx .", - "prepare": "go run ../../pkg/config/git/git.go --js > src/version.ts" + "prepare": "CGO_ENABLED=0 go run ../../pkg/config/git/git.go --js > src/version.ts" }, "devDependencies": { "@electron-forge/cli": "^7.5.0", diff --git a/meson.build b/meson.build index 9103dbe5a..611e01b80 100644 --- a/meson.build +++ b/meson.build @@ -9,55 +9,20 @@ project( 'force_fallback_for': 'gio-2.0,gstreamer-controller-1.0,gstreamer-app-1.0,gstreamer-pbutils-1.0,glib-2.0,gobject-2.0,gio-2.0,gio-unix-2.0,fdk-aac,zlib,libffi,pcre2,intl,proxy-libintl,x264,freetype2,libpng,libjpeg,fontconfig,pango,opus,fribidi,harfbuzz,nettle,cairo,pixman,expat,openssl', 'buildtype': 'debugoptimized', 'prefix': meson.current_build_dir(), # otherwise mac meson will try and do /opt/homebrew sometimes + 'libdir': 'lib' }, ) -fs = import('fs') - -prog_go = find_program('go') - -flagbuilder = custom_target( - 'flagbuilder', - input: ['pkg/config/git/git.go'], - output: ['flagbuilder'], - command: [prog_go, 'build', '-o', '@OUTPUT0@', '@INPUT@'], - build_always_stale: true, - env: { - 'CGO_ENABLED': '0', - }, -) - -flags = custom_target( - 'flags', - input: [], - output: ['build-flags.go'], - command: [flagbuilder, '-o', '@OUTPUT0@'], - build_always_stale: true, -) - -version_cmd = run_command( - prog_go, - 'run', - 'pkg/config/git/git.go', - '-v', - check: true, - env: { - 'CGO_ENABLED': '0', - }, -) -version = version_cmd.stdout().strip() - -streamplace_go = custom_target( - 'streamplace.go', - input: 'cmd/libstreamplace/streamplace.go', - output: 'streamplace.go', - command: ['cp', '@INPUT@', '@OUTPUT@'], -) - -# todo: teach meson to automatically populate this CPATH thing for go -env = { - 'PKG_CONFIG_PATH': meson.current_build_dir() + '/lib/pkgconfig', -} +env = {} +if get_option('default_library') == 'static' + env = { + 'PKG_CONFIG_PATH': meson.current_build_dir() + '/meson-uninstalled', + } +else + env = { + 'PKG_CONFIG_PATH': meson.current_build_dir() + '/lib/pkgconfig', + } +endif GOOS = meson.get_external_property('GOOS', host_machine.system()) GOARCH = meson.get_external_property('GOARCH', host_machine.cpu()) @@ -238,6 +203,7 @@ streamplace_deps += [ dependency('gstreamer-controller-1.0'), dependency('gstreamer-app-1.0'), dependency('gstreamer-pbutils-1.0'), + dependency('libffi'), ] atproto = subproject( @@ -284,11 +250,146 @@ pkg.generate( description: 'all streamplace dependencies bundled for easy inclusion', ) -streamplacedeps = executable( +# dummy executable that we use as a target to convince meson to build all the streamplace dependencies +executable( 'streamplacedeps', ['cmd/streamplace/empty.c'], dependencies: [ streamplace_deps, ], link_with: [c2pa_go_dep, iroh_streamplace_dep], + install_tag: 'streamplacedeps', ) + +if get_option('default_library') == 'static' + prog_go = find_program('go') + + flagbuilder = custom_target( + 'flagbuilder', + input: ['pkg/config/git/git.go'], + output: ['flagbuilder'], + command: [prog_go, 'build', '-o', '@OUTPUT0@', '@INPUT@'], + build_always_stale: true, + env: { + 'CGO_ENABLED': '0', + }, + ) + version_cmd = run_command(prog_go, 'run', 'pkg/config/git/git.go', '-v', check: true, env: { + 'CGO_ENABLED': '0', + }) + version = version_cmd.stdout().strip() + + streamplace_go = custom_target( + 'streamplace.go', + input: 'cmd/libstreamplace/streamplace.go', + output: 'streamplace.go', + command: ['cp', '@INPUT@', '@OUTPUT@'], + ) + flags = custom_target( + 'flags', + input: [], + output: ['build-flags.go'], + command: [flagbuilder, '-o', '@OUTPUT0@'], + build_always_stale: true, + ) + + libstreamplace = custom_target( + 'libstreamplace', + input: [streamplace_go, flags], + output: ['streamplace.a', 'streamplace.h'], + command: [ + prog_go, + 'build', + '-o', '@OUTPUT0@', + '-buildmode', 'c-archive', + '-tags', 'netgo,static', + '@INPUT@', + ], + build_always_stale: true, + env: env, + ) + + if build_machine.system() == 'linux' and host_machine.system() == 'darwin' + # this only exists to convince meson to build all of the streamplace dependencies + # the real binary comes from the `go build` command below + cstreamplace = executable( + 'cstreamplace', + ['cmd/streamplace/streamplace.c', libstreamplace], + dependencies: [ + streamplace_deps, + ], + link_with: [c2pa_go_dep, iroh_streamplace_dep], + ) + + streamplace = custom_target( + 'streamplace', + input: [cstreamplace, flags], + output: ['streamplace'], + command: [ + prog_go, + 'build', + '-o', '@OUTPUT0@', + '-tags', 'netgo,static', + 'streamplace.go', + '@INPUT1@' + ], + build_always_stale: true, + env: env, + ) + else + streamplace = executable( + 'streamplace', + ['cmd/streamplace/streamplace.c', libstreamplace], + dependencies: [ + streamplace_deps, + ], + link_with: [c2pa_go_dep, iroh_streamplace_dep], + ) + endif + + + if not meson.is_cross_build() + test( + 'go-tests', + prog_go, + depends: [streamplace], + env: env, + verbose: true, + timeout: 0, + args: [ + 'test', + '-p', '1', + '-timeout', '600s', + '@0@/pkg/...'.format(meson.current_source_dir()), + '@0@/cmd/...'.format(meson.current_source_dir()), + ], + ) + endif + + if host_machine.system() == 'windows' + prog_zip = find_program('zip') + archive_name = 'streamplace-' + version + '-' + GOOS + '-' + GOARCH + '.zip' + custom_target( + 'archive', + input: [streamplace], + output: ['streamplace.zip'], + command: [prog_zip, '../bin/' + archive_name, '@INPUT@'], + install: true, + install_dir: './bin', + build_by_default: false, + ) + else + prog_tar = find_program('tar') + # archive_name = streamplace-$(VERSION)-$$GOOS-$$GOARCH.tar.gz + archive_name = 'streamplace-' + version + '-' + GOOS + '-' + GOARCH + '.tar.gz' + custom_target( + 'archive', + input: [streamplace], + output: ['streamplace.tar.gz'], + command: [prog_tar, '-czvf', '../bin/' + archive_name, '@INPUT@'], + install: true, + install_dir: './bin', + build_by_default: false, + ) + endif +endif diff --git a/pkg/cmd/streamplace.go b/pkg/cmd/streamplace.go index 19c1284e4..fb390600e 100644 --- a/pkg/cmd/streamplace.go +++ b/pkg/cmd/streamplace.go @@ -30,7 +30,8 @@ import ( "stream.place/streamplace/pkg/log" "stream.place/streamplace/pkg/media" "stream.place/streamplace/pkg/notifications" - "stream.place/streamplace/pkg/replication/iroh" + "stream.place/streamplace/pkg/replication" + "stream.place/streamplace/pkg/replication/boring" "stream.place/streamplace/pkg/rtmps" v0 "stream.place/streamplace/pkg/schema/v0" "stream.place/streamplace/pkg/spmetrics" @@ -43,7 +44,7 @@ import ( "stream.place/streamplace/pkg/config" "stream.place/streamplace/pkg/model" - irohStreamplace "stream.place/streamplace/pkg/iroh/generated/iroh_streamplace" + _ "stream.place/streamplace/pkg/iroh/generated/iroh_streamplace" ) // Additional jobs that can be injected by platforms @@ -305,21 +306,9 @@ func start(build *config.BuildFlags, platformJobs []jobFunc) error { log.Log(ctx, "successfully initialized hardware signer", "address", addr) signer = hwsigner } - irohEndpoint, err2 := irohStreamplace.NewEndpoint() - if err2.AsError() != nil { - return err2.AsError() - } - // TODO: something more useful - defaultTopic := "iroh-topic" - rep, err := iroh.NewIrohReplicator(ctx, irohEndpoint, defaultTopic) - if err != nil { - return err - } - addr := irohEndpoint.NodeAddr() - fmt.Printf("iroh running, ID: %s\nHome Relay: %s\n", addr.NodeId().String(), *addr.RelayUrl()) + var rep replication.Replicator = &boring.BoringReplicator{Peers: cli.Peers} mod, err := model.MakeDB(cli.DataFilePath([]string{"index"})) - if err != nil { return err } @@ -378,13 +367,6 @@ func start(build *config.BuildFlags, platformJobs []jobFunc) error { return err } - // TODO: based on a flag, subscribe - // rec, err2 := irohStreamplace.NewReceiver(irohEndpoint, mm) - // if err2.AsError() != nil { - // return err2.AsError() - // } - // rec.Subscribe(peer, defaultTopic) - ms, err := media.MakeMediaSigner(ctx, &cli, cli.StreamerName, signer) if err != nil { return err diff --git a/pkg/iroh/iroh_streamplace.go b/pkg/iroh/iroh_streamplace.go index 8d0f08698..f5c7cc1a3 100644 --- a/pkg/iroh/iroh_streamplace.go +++ b/pkg/iroh/iroh_streamplace.go @@ -2,8 +2,8 @@ package iroh_streamplace import ( _ "stream.place/streamplace/pkg/iroh/generated/iroh_streamplace" + _ "stream.place/streamplace/pkg/streamplacedeps" ) -// #cgo pkg-config: streamplacedeps // #cgo darwin LDFLAGS: -framework Security -framework SystemConfiguration import "C" diff --git a/pkg/media/media.go b/pkg/media/media.go index 57371ed0e..bc8795b3f 100644 --- a/pkg/media/media.go +++ b/pkg/media/media.go @@ -29,10 +29,9 @@ import ( "github.com/piprate/json-gold/ld" irohStreamplace "stream.place/streamplace/pkg/iroh/generated/iroh_streamplace" -) -// #cgo pkg-config: streamplacedeps -import "C" + _ "stream.place/streamplace/pkg/streamplacedeps" +) const CertFile = "cert.pem" const SegmentsDir = "segments" diff --git a/pkg/replication/iroh/iroh.go b/pkg/replication/iroh/iroh.go index d411ffdd1..9f5d4547f 100644 --- a/pkg/replication/iroh/iroh.go +++ b/pkg/replication/iroh/iroh.go @@ -10,7 +10,7 @@ import ( // IrohReplicator implements the replication mechanism using iroh type IrohReplicator struct { - topic string + topic string sender *irohStreamplace.Sender } @@ -20,9 +20,8 @@ func NewIrohReplicator(ctx context.Context, ep *irohStreamplace.Endpoint, topic return nil, err.AsError() } - return &IrohReplicator{ - topic: topic, + topic: topic, sender: sender, }, nil } diff --git a/pkg/streamplacedeps/streamplacedeps-dynamic.go b/pkg/streamplacedeps/streamplacedeps-dynamic.go new file mode 100644 index 000000000..6b8303c9e --- /dev/null +++ b/pkg/streamplacedeps/streamplacedeps-dynamic.go @@ -0,0 +1,8 @@ +//go:build !static + +// This runs during dynamic builds in dev + +package streamplacedeps + +// #cgo pkg-config: streamplacedeps +import "C" diff --git a/pkg/streamplacedeps/streamplacedeps-static.go b/pkg/streamplacedeps/streamplacedeps-static.go new file mode 100644 index 000000000..21063e40e --- /dev/null +++ b/pkg/streamplacedeps/streamplacedeps-static.go @@ -0,0 +1,8 @@ +//go:build static + +// This runs during static builds when we're making production executables + +package streamplacedeps + +// #cgo pkg-config: streamplacedeps-uninstalled +import "C" diff --git a/rust/iroh-streamplace/README.md b/rust/iroh-streamplace/README.md index 8371bd5ab..37c1a1a8d 100644 --- a/rust/iroh-streamplace/README.md +++ b/rust/iroh-streamplace/README.md @@ -1,6 +1,5 @@ # iroh-streamplace - ## Development ```sh diff --git a/rust/iroh-streamplace/meson.build b/rust/iroh-streamplace/meson.build index 978d6289e..b34d4bcd3 100644 --- a/rust/iroh-streamplace/meson.build +++ b/rust/iroh-streamplace/meson.build @@ -21,6 +21,8 @@ if get_option('default_library') == 'shared' 'cd "@2@/../.." && @0@ && cp "@2@/../../target/debug/libiroh_streamplace.@3@" "@1@/libiroh_streamplace.@3@"'.format(cargo_cmd, meson.current_build_dir(), meson.current_source_dir(), ext), ], build_by_default: true, + install: true, + install_dir: get_option('libdir'), ) else cargo_cmd = '@0@ build --release --target-dir "@1@"'.format(prog_cargo.full_path(), meson.current_build_dir()) @@ -42,5 +44,7 @@ else 'cd "@2@" && @0@ && cp "@3@/release/libiroh_streamplace.a" "@1@/libiroh_streamplace.a"'.format(cargo_cmd, meson.current_build_dir(), meson.current_source_dir(), archive_dir), ], build_by_default: true, + install: true, + install_dir: get_option('libdir'), ) endif diff --git a/subprojects/c2pa_go.wrap b/subprojects/c2pa_go.wrap index b6b1ffd6f..180a93807 100644 --- a/subprojects/c2pa_go.wrap +++ b/subprojects/c2pa_go.wrap @@ -1,4 +1,4 @@ [wrap-git] -url = https://git.stream.place/streamplace/c2pa-go.git -revision = v0.7.0 +url = https://github.com/streamplace/c2pa-go.git +revision = v0.7.2 depth = 1 diff --git a/util/streamplace-dev.sh b/util/streamplace-dev.sh index 4d04b27ee..377187306 100755 --- a/util/streamplace-dev.sh +++ b/util/streamplace-dev.sh @@ -7,7 +7,6 @@ set -euo pipefail SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) STREAMPLACE_DEV_VERSION=$(go run ./pkg/config/git/git.go -v) \ -LD_LIBRARY_PATH="$SCRIPT_DIR/lib/usr/local/lib/x86_64-linux-gnu:$SCRIPT_DIR/../target/debug" \ -DYLD_LIBRARY_PATH="$SCRIPT_DIR/lib/usr/local/lib:$SCRIPT_DIR/../target/debug" \ +LD_LIBRARY_PATH="$SCRIPT_DIR/lib" \ SP_DEV_FRONTEND_PROXY="http://127.0.0.1:38081" \ exec "$SCRIPT_DIR/libstreamplace" "$@"