Compare commits

..

32 Commits

Author SHA1 Message Date
Hyunjin Song
f54ac456dd Remove leftover of mingw-std-threads 2024-10-03 20:34:08 +09:00
Hyunjin Song
7782954e6e Fix namespace 2024-10-03 20:33:08 +09:00
Hyunjin Song
7ce62fe0cb Always build libcds as a static library 2024-10-03 19:48:14 +09:00
Hyunjin Song
47e6a3090a Merge branch 'master' into refac/memory 2024-10-03 17:05:29 +09:00
Hyunjin Song
ac5b3f07d7 Revert irrelevant changes 2024-09-21 21:58:05 +09:00
Lukas W
9df27e9e8e Merge branch 'master' into refac/memory 2020-12-11 09:47:41 +01:00
Lukas W
846ca178f5 CMake: Build lmms shared library instead of object library
Resolves some inexplicable linking errors on Windows. Saves us from
working around incomplete CMake support of object libraries.
2020-05-22 17:23:17 +02:00
Lukas W
ac0081de10 Fix crash on exit with MSVC 2020-05-14 10:14:16 +02:00
Lukas W
74ee6354e6 Merge remote-tracking branch 'origin/master' into refac/memory 2020-05-12 13:54:19 +02:00
Lukas W
a64f83e0ed Fix libcds MSVC compilation
* Update to include 4227281c367a0dd36765bba58bd9bb6f43ceb88b fixing
  https://github.com/khizmax/libcds/issues/124
* Make CDS_BUILD_STATIC_LIB compile definition public to avoid dllimport
  attribute in defs.h
* Make dependencies' defintions actually propagate to lmmsobjs
2020-05-12 13:39:28 +02:00
Lukas W
5ae42cafc4 Try to fix libcds counters issues
* For unknown reasons, _cdslib::_thread_counter is never initialized,
  trigger initialization manually by referencing during MemoryPool's
  construction.
* CircleCI linux.gcc test crashes on exit with an "invalid delete" at
  hpGC.reset() in libcds.cpp. I don't know what causes this, but it
  turns out we don't need garbage collection currently (we only use
  VyukovMPMCCycleQueue), so we can just remove the garbage collection
  for now.
2020-05-11 19:17:24 +02:00
Lukas W
78c92e8314 Tests: Allow specifying test suit name 2020-05-11 15:01:43 +02:00
Lukas W
29df871800 Add nifty counter instance to MmAllocaator
Prevents exit crashes in rare cases e.g. when Engine is not destroyed
2020-05-11 15:01:43 +02:00
Lukas W
1cd8b7a895 Fix libcds nifty counter typo
Thanks @PhysSong

Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
2020-05-11 14:55:29 +02:00
Lukas W
62606b64fe Try to fix CircleCI linux build 2020-05-06 12:38:12 +02:00
Lukas W
68d7157c8e Merge branch 'master' into refac/memory 2020-05-04 20:28:32 +02:00
Lukas W
e21c00e9b7 Apply suggestions by @PhysSong 2020-05-04 18:00:47 +02:00
Lukas W
bd1ee2983b Silence int conversion warning 2019-08-27 14:33:36 +02:00
Lukas W
d35df8ee7b Move BufferPool::clear to MixHelpers and rewrite
* Move out of BufferPool because it's not related to memory allocation
* Rewrite because memset() is not portable because it sets all bytes to
  zero which depends on the platform's float representation of 0.0 to be
  all zero bytes
2019-08-27 14:33:36 +02:00
Lukas W
5349be6a63 NiftyCounter: Fix decrement 2019-08-25 23:22:06 +02:00
Lukas W
71e9b45446 Memory: Fix wrong rebind 2019-08-25 23:22:06 +02:00
Lukas W
119efeec01 Fix tests crash due to incomplete cleanup 2019-08-25 23:22:06 +02:00
Lukas W
2f8e231b8c Fix macOS linking problem 2019-08-25 23:22:06 +02:00
Lukas W
8b122d5a4c Fix libcds on MinGW 2019-08-25 23:21:53 +02:00
Lukas W
ef7b8c68d5 Add naive benchmarks 2019-08-25 22:22:21 +02:00
Lukas W
2cb4455a5f Replace AllignedAllocator implementation with rpmalloc calls 2019-08-25 22:22:21 +02:00
Lukas W
178888af94 BufferManager: Use MemoryPool, rename to BufferPool 2019-08-25 22:22:21 +02:00
Lukas W
3e1a96693d Replace NotePlayHandleManager implementation with MemoryPool 2019-08-25 22:22:21 +02:00
Lukas W
1cd8e15942 Replace LocklessAllocator with new MemoryPool class
MemoryPool maintains a free list of pre-allocated entries stored in a
libcds MPMC Queue. In contrast to LocklessAllocator, it's a lot faster,
less (and less complex) code to maintain for us and it doesn't fail when
it's full.
2019-08-25 22:19:48 +02:00
Lukas W
1340c273c7 Memory.h fixes
* Use a Nifty Counter for rpmalloc initialization. This fixes init order
  with other static objects using MmAllocator or MemoryManagger
* Fix exception throwing in AlignedAllocator
* Add missing constructor to MmAllocator for compatibility with std
  containers
2019-08-25 22:18:47 +02:00
Lukas W
3c73270c23 Rename MemoryManager.h to Memory.h 2019-08-25 22:18:47 +02:00
Lukas W
2a08909380 Move aligned malloc to MemoryManager.h, port to stl allocator 2019-08-25 22:17:37 +02:00
945 changed files with 4754 additions and 7046 deletions

View File

@@ -1,7 +1,7 @@
---
# Language
Language: Cpp
Standard: c++20
Standard: Cpp11 # Cpp14 and Cpp17 are not supported by clang 11
# Indentation
TabWidth: 4

View File

@@ -20,6 +20,7 @@ Checks: >
readability-simplify-boolean-expr
WarningsAsErrors: ''
HeaderFilterRegex: '' # don't show errors from headers
AnalyzeTemporaryDtors: false
FormatStyle: none
User: user
CheckOptions:

View File

@@ -1,47 +0,0 @@
name: Extract Artifact
description: Waits for build, downloads and extracts the artifact
inputs:
check-name:
description: "Check name to wait for"
required: true
artifact-name:
description: "Name of the artifact to download"
required: true
github-token:
description: "GitHub token for authentication"
required: true
runs:
using: "composite"
steps:
- name: Wait for build
uses: lewagon/wait-on-check-action@v1.3.4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
check-name: ${{ inputs.check-name }}
repo-token: ${{ inputs.github-token }}
wait-interval: 30
- name: Download workflow artifact
uses: dawidd6/action-download-artifact@v6
with:
workflow: build.yml
name: ${{ inputs.artifact-name }}
- name: Extract artifact (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
chmod +x lmms-*.AppImage
./lmms-*.AppImage --appimage-extract
- name: Mount DMG (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
hdiutil attach lmms-*.dmg -mountpoint ~/tmpvolume
cp -R ~/tmpvolume/LMMS.app /tmp/
# Windows: Not working because (1) #7732 and (2) the unzip failed
#- name: Unpack installer (Windows)
# if: runner.os == 'Windows'
# run: Start-Process @(gci build/lmms-*.exe)[0] -ArgumentList /S -Wait

View File

@@ -5,15 +5,15 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
linux-x86_64:
name: linux-x86_64
runs-on: ubuntu-22.04
linux:
name: linux
runs-on: ubuntu-latest
container: ghcr.io/lmms/linux.gcc:20.04
env:
CMAKE_OPTS: >-
-DUSE_WERROR=ON
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DUSE_COMPILE_CACHE=ON
-DWANT_DEBUG_CPACK=ON
CCACHE_MAXSIZE: 0
CCACHE_NOCOMPRESS: 1
MAKEFLAGS: -j2
@@ -25,29 +25,6 @@ jobs:
with:
fetch-depth: 0
submodules: recursive
- name: Clone fltk
uses: actions/checkout@v4
with:
repository: fltk/fltk
path: fltk
ref: 27d991f046bdebb12bfd58f7c05a19f135979c29
fetch-depth: 1
- name: Configure winehq
run: |
sudo dpkg --add-architecture i386
sudo mkdir -pm755 /etc/apt/keyrings
wget -O - https://dl.winehq.org/wine-builds/winehq.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/winehq-archive.key -
sudo wget -NP /etc/apt/sources.list.d/ \
https://dl.winehq.org/wine-builds/ubuntu/dists/$(lsb_release -cs)/winehq-$(lsb_release -cs).sources
- name: Install packages
run: |
sudo apt-get update -y
sudo apt-get install -y --no-install-recommends \
$(xargs < .github/workflows/deps-ubuntu-24.04-gcc.txt)
sudo apt-get install -y --install-recommends g++-multilib gcc-multilib winehq-stable wine-stable-dev
sudo apt-get install -y --install-recommends \
$(xargs < .github/workflows/deps-ubuntu-24.04-fltk.txt)
- name: Cache ccache data
uses: actions/cache@v3
with:
@@ -56,20 +33,13 @@ jobs:
ccache-${{ github.job }}-${{ github.ref }}-
ccache-${{ github.job }}-
path: ~/.ccache
- name: Configure fltk
run: |
cmake -S fltk -B fltk/build -DFLTK_BUILD_SHARED_LIBS=ON -DFLTK_BACKEND_WAYLAND=ON \
-DFLTK_USE_LIBDECOR_GTK=OFF -DFLTK_BUILD_TEST=OFF -DFLTK_BUILD_GL=OFF
- name: Install fltk
run: |
cmake --build fltk/build
sudo cmake --install fltk/build --prefix /usr
- name: Configure
run: |
ccache --zero-stats
source /opt/qt5*/bin/qt5*-env.sh || true
cmake -S . \
-B build \
-DCMAKE_INSTALL_PREFIX=./install \
$CMAKE_OPTS
- name: Build
run: cmake --build build
@@ -79,7 +49,8 @@ jobs:
ctest --output-on-failure -j2
- name: Package
run: |
cmake --build build --target package
cmake --build build --target install
cmake --build build --target appimage
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
@@ -94,86 +65,6 @@ jobs:
ccache --show-stats
env:
CCACHE_MAXSIZE: 500M
linux-arm64:
name: linux-arm64
runs-on: ubuntu-24.04-arm
env:
CMAKE_OPTS: >-
-DUSE_WERROR=ON
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DUSE_COMPILE_CACHE=ON
-DWANT_DEBUG_CPACK=ON
CCACHE_MAXSIZE: 0
CCACHE_NOCOMPRESS: 1
MAKEFLAGS: -j2
DEBIAN_FRONTEND: noninteractive
steps:
- name: Configure git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Check out
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: recursive
- name: Clone fltk
uses: actions/checkout@v4
with:
repository: fltk/fltk
path: fltk
ref: 27d991f046bdebb12bfd58f7c05a19f135979c29
fetch-depth: 1
- name: Install system packages
run: |
sudo apt-get update -y
sudo apt-get install -y --no-install-recommends \
$(xargs < .github/workflows/deps-ubuntu-24.04-gcc.txt)
sudo apt-get install -y --install-recommends \
$(xargs < .github/workflows/deps-ubuntu-24.04-fltk.txt)
- name: Cache ccache data
uses: actions/cache@v3
with:
key: ccache-${{ github.job }}-${{ github.ref }}-${{ github.run_id }}
restore-keys: |
ccache-${{ github.job }}-${{ github.ref }}-
ccache-${{ github.job }}-
path: ~/.ccache
- name: Configure fltk
run: |
cmake -S fltk -B fltk/build -DFLTK_BUILD_SHARED_LIBS=ON -DFLTK_BACKEND_WAYLAND=ON \
-DFLTK_USE_LIBDECOR_GTK=OFF -DFLTK_BUILD_TEST=OFF -DFLTK_BUILD_GL=OFF
- name: Install fltk
run: |
cmake --build fltk/build
sudo cmake --install fltk/build --prefix /usr
- name: Configure
run: |
ccache --zero-stats
cmake -S . \
-B build \
$CMAKE_OPTS
- name: Build
run: cmake --build build
- name: Run tests
run: |
cd build/tests
ctest --output-on-failure -j2
- name: Package
run: |
cmake --build build --target package
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: linux-arm64
path: build/lmms-*.AppImage
- name: Trim ccache and print statistics
run: |
ccache --cleanup
echo "[ccache config]"
ccache --show-config
echo "[ccache stats]"
ccache --show-stats
env:
CCACHE_MAXSIZE: 500M
macos:
strategy:
fail-fast: false
@@ -181,11 +72,11 @@ jobs:
arch: [ x86_64, arm64 ]
include:
- arch: x86_64
os: macos-13
xcode: "15.2"
os: macos-12
xcode: "13.1"
- arch: arm64
os: macos-14
xcode: "15.4"
xcode: "14.3.1"
name: macos-${{ matrix.arch }}
runs-on: ${{ matrix.os }}
env:
@@ -238,6 +129,8 @@ jobs:
mkdir build
cmake -S . \
-B build \
-DCMAKE_INSTALL_PREFIX="../target" \
-DCMAKE_PREFIX_PATH="$(brew --prefix qt@5)" \
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.arch }} \
$CMAKE_OPTS \
-DUSE_WERROR=OFF
@@ -249,7 +142,8 @@ jobs:
ctest --output-on-failure -j3
- name: Package
run: |
cmake --build build --target package
cmake --build build --target install
cmake --build build --target dmg
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
@@ -274,8 +168,13 @@ jobs:
key: "homebrew-${{ matrix.arch }}\
-${{ hashFiles('Brewfile.lock.json') }}"
mingw:
name: mingw64
strategy:
fail-fast: false
matrix:
arch: ['32', '64']
name: mingw${{ matrix.arch }}
runs-on: ubuntu-latest
container: ghcr.io/lmms/linux.mingw:20.04
env:
CMAKE_OPTS: >-
-Werror=dev
@@ -286,12 +185,12 @@ jobs:
CCACHE_NOCOMPRESS: 1
MAKEFLAGS: -j2
steps:
- name: Configure apt
- name: Enable POSIX MinGW
run: |
sudo sh -c 'echo "deb http://ppa.launchpad.net/tobydox/mingw-w64/ubuntu focal main" > \
/etc/apt/sources.list.d/tobydox-mingw-w64.list'
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 72931B477E22FEFD47F8DECE02FE5F12ADDE29B2
sudo apt-get update -y
update-alternatives --set i686-w64-mingw32-gcc /usr/bin/i686-w64-mingw32-gcc-posix
update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix
update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix
update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
- name: Configure git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Check out
@@ -302,22 +201,19 @@ jobs:
- name: Cache ccache data
uses: actions/cache@v3
with:
key: "ccache-${{ github.job }}-64-${{ github.ref }}\
key: "ccache-${{ github.job }}-${{ matrix.arch }}-${{ github.ref }}\
-${{ github.run_id }}"
restore-keys: |
ccache-${{ github.job }}-64-${{ github.ref }}-
ccache-${{ github.job }}-64-
ccache-${{ github.job }}-${{ matrix.arch }}-${{ github.ref }}-
ccache-${{ github.job }}-${{ matrix.arch }}-
path: ~/.ccache
- name: Install dependencies
run: |
sudo apt-get install -y --no-install-recommends \
$(xargs < .github/workflows/deps-ubuntu-24.04-mingw.txt)
- name: Configure
run: |
ccache --zero-stats
cmake -S . \
-B build \
-DCMAKE_TOOLCHAIN_FILE="./cmake/toolchains/MinGW-W64-64.cmake" \
-DCMAKE_INSTALL_PREFIX=./install \
-DCMAKE_TOOLCHAIN_FILE="./cmake/toolchains/MinGW-W64-${{ matrix.arch }}.cmake" \
$CMAKE_OPTS
- name: Build
run: cmake --build build
@@ -326,7 +222,7 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: mingw64
name: mingw${{ matrix.arch }}
path: build/lmms-*.exe
- name: Trim ccache and print statistics
run: |
@@ -338,7 +234,11 @@ jobs:
env:
CCACHE_MAXSIZE: 500M
msvc:
name: msvc-x64
strategy:
fail-fast: false
matrix:
arch: ['x86', 'x64']
name: msvc-${{ matrix.arch }}
runs-on: windows-2019
env:
CCACHE_MAXSIZE: 0
@@ -353,19 +253,19 @@ jobs:
id: cache-deps
uses: actions/cache@v3
with:
key: vcpkg-msvc-x86_64-${{ hashFiles('vcpkg.json') }}
key: vcpkg-${{ matrix.arch }}-${{ hashFiles('vcpkg.json') }}
restore-keys: |
vcpkg-msvc-x86_64-
vcpkg-${{ matrix.arch }}-
path: build\vcpkg_installed
- name: Cache ccache data
uses: actions/cache@v3
with:
# yamllint disable rule:line-length
key: "ccache-${{ github.job }}-x64-${{ github.ref }}\
key: "ccache-${{ github.job }}-${{ matrix.arch }}-${{ github.ref }}\
-${{ github.run_id }}"
restore-keys: |
ccache-${{ github.job }}-x64-${{ github.ref }}-
ccache-${{ github.job }}-x64-
ccache-${{ github.job }}-${{ matrix.arch }}-${{ github.ref }}-
ccache-${{ github.job }}-${{ matrix.arch }}-
path: ~\AppData\Local\ccache
# yamllint enable rule:line-length
- name: Install tools
@@ -374,13 +274,21 @@ jobs:
uses: jurplel/install-qt-action@b3ea5275e37b734d027040e2c7fe7a10ea2ef946
with:
version: '5.15.2'
arch: "win64_msvc2019_64"
arch: |-
${{
fromJSON('
{
"x86": "win32_msvc2019",
"x64": "win64_msvc2019_64"
}
')[matrix.arch]
}}
archives: qtbase qtsvg qttools
cache: true
- name: Set up build environment
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89
with:
arch: x64
arch: ${{ matrix.arch }}
- name: Configure
run: |
ccache --zero-stats
@@ -393,8 +301,8 @@ jobs:
-DCMAKE_BUILD_TYPE=RelWithDebInfo `
-DUSE_COMPILE_CACHE=ON `
-DUSE_WERROR=ON `
-DVCPKG_TARGET_TRIPLET="x64-windows" `
-DVCPKG_HOST_TRIPLET="x64-windows" `
-DVCPKG_TARGET_TRIPLET="${{ matrix.arch }}-windows" `
-DVCPKG_HOST_TRIPLET="${{ matrix.arch }}-windows" `
-DVCPKG_MANIFEST_INSTALL="${{ env.should_install_manifest }}"
env:
should_install_manifest:
@@ -410,7 +318,7 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: msvc-x64
name: msvc-${{ matrix.arch }}
path: build\lmms-*.exe
- name: Trim ccache and print statistics
run: |

View File

@@ -1,3 +0,0 @@
libcairo2-dev
libpango1.0-dev
wayland-protocols

View File

@@ -1,52 +0,0 @@
binutils
ca-certificates
ccache
cmake
file
fluid
gcc
git
gpg
g++
libasound2-dev
libc6-dev
libfftw3-dev
libfluidsynth-dev
libgig-dev
libgtk2.0-0
libjack-jackd2-dev
liblilv-dev
liblist-moreutils-perl
libmp3lame-dev
libogg-dev
libqt5svg5-dev
libqt5x11extras5-dev
libsamplerate0-dev
libsdl2-dev
libsndfile1-dev
libsoundio-dev
libstk-dev
libsuil-dev
libvorbis-dev
libx11-xcb-dev
libxcb-keysyms1-dev
libxcb-util0-dev
libxft-dev
libxinerama-dev
libxml2-utils
libxml-perl
lsb-release
lv2-dev
make
perl
portaudio19-dev
qt5-qmake
qtbase5-dev
qtbase5-dev-tools
qtbase5-private-dev
qttools5-dev-tools
qtwayland5
software-properties-common
ssh-client
stk
wget

View File

@@ -1,32 +0,0 @@
binutils-mingw-w64
ccache
cmake
fftw-mingw-w64
file
flac-mingw-w64
fltk-mingw-w64
fluidsynth-mingw-w64
g++-mingw-w64-i686
g++-mingw-w64-x86-64
gcc-mingw-w64
gcc-mingw-w64-i686
gcc-mingw-w64-x86-64
git
glib2-mingw-w64
lame-mingw-w64
libgig-mingw-w64
liblist-moreutils-perl
libsamplerate-mingw-w64
libsndfile-mingw-w64
libsoundio-mingw-w64
libvorbis-mingw-w64
libxml-parser-perl
libz-mingw-w64-dev
mingw-w64-tools
nsis
portaudio-mingw-w64
qt5base-mingw-w64
qt5svg-mingw-w64
qttools5-dev-tools
sdl2-mingw-w64
stk-mingw-w64

View File

@@ -1,63 +0,0 @@
---
name: run-help
'on': [push, pull_request]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
help-linux:
strategy:
fail-fast: false
matrix:
config:
- arch: 'x86_64'
runner: 'ubuntu-latest'
suffix: ''
- arch: 'arm64'
runner: 'ubuntu-24.04-arm'
suffix: '-arm64'
name: help-linux-${{ matrix.config.arch }}
runs-on: ${{ matrix.config.runner }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Extract artifact
uses: ./.github/actions/extract-artifact
with:
check-name: linux-${{ matrix.config.arch }}
artifact-name: linux${{ matrix.config.suffix }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Display help
run: |
cd squashfs-root/
./AppRun --help | grep "Usage: lmms"
help-macos:
strategy:
fail-fast: false
matrix:
config:
- arch: 'x86_64'
runner: 'macos-latest'
- arch: 'arm64'
runner: 'macos-latest'
name: help-macos-${{ matrix.config.arch }}
runs-on: ${{ matrix.config.runner }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Extract artifact
uses: ./.github/actions/extract-artifact
with:
check-name: macos-${{ matrix.config.arch }}
artifact-name: macos-${{ matrix.config.arch }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Display help
run: |
/tmp/LMMS.app/Contents/MacOS/lmms --help | grep "Usage: lmms"
# Windows (does not work due to actions/extract-artifact issues)
# - name: Display help
# run: >
# $result = & "${env:ProgramFiles${{ matrix.config.programfiles-suffix }}}/LMMS/lmms.exe" "--help" |
# Select-String "Usage: lmms";
# if($result.Matches.Count -eq 0) { exit 1 }

View File

@@ -1,63 +0,0 @@
---
name: run-version
'on': [push, pull_request]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
version-linux:
strategy:
fail-fast: false
matrix:
config:
- arch: 'x86_64'
runner: 'ubuntu-latest'
suffix: ''
- arch: 'arm64'
runner: 'ubuntu-24.04-arm'
suffix: '-arm64'
name: version-linux-${{ matrix.config.arch }}
runs-on: ${{ matrix.config.runner }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Extract artifact
uses: ./.github/actions/extract-artifact
with:
check-name: linux-${{ matrix.config.arch }}
artifact-name: linux${{ matrix.config.suffix }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Display version
run: |
cd squashfs-root/
./AppRun --version | grep "Copyright (c) .* LMMS Developers"
version-macos:
strategy:
fail-fast: false
matrix:
config:
- arch: 'x86_64'
runner: 'macos-latest'
- arch: 'arm64'
runner: 'macos-latest'
name: version-macos-${{ matrix.config.arch }}
runs-on: ${{ matrix.config.runner }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Extract artifact
uses: ./.github/actions/extract-artifact
with:
check-name: macos-${{ matrix.config.arch }}
artifact-name: macos-${{ matrix.config.arch }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Display version
run: |
/tmp/LMMS.app/Contents/MacOS/lmms --version | grep "Usage: lmms"
# Windows (does not work due to actions/extract-artifact issues)
# - name: Display version
# run: >
# $result = & "${env:ProgramFiles${{ matrix.config.programfiles-suffix }}}/LMMS/lmms.exe" "--version" |
# Select-String -Pattern "Copyright \(c\) .* LMMS Developers";
# if($result.Matches.Count -eq 0) { exit 1 }

4
.gitmodules vendored
View File

@@ -16,7 +16,6 @@
[submodule "plugins/Xpressive/exprtk"]
path = plugins/Xpressive/exprtk
url = https://github.com/ArashPartow/exprtk
branch = release
[submodule "plugins/LadspaEffect/swh/ladspa"]
path = plugins/LadspaEffect/swh/ladspa
url = https://github.com/swh/ladspa
@@ -26,6 +25,9 @@
[submodule "src/3rdparty/weakjack/weakjack"]
path = src/3rdparty/weakjack/weakjack
url = https://github.com/x42/weakjack.git
[submodule "src/3rdparty/libcds"]
path = src/3rdparty/libcds
url = https://github.com/khizmax/libcds.git
[submodule "doc/wiki"]
path = doc/wiki
url = https://github.com/lmms/lmms.wiki.git

View File

@@ -13,7 +13,7 @@ brew "libsoundio"
brew "libvorbis"
brew "lilv"
brew "lv2"
brew "pkgconf"
brew "pkg-config"
brew "portaudio"
brew "qt@5"
brew "sdl2"

View File

@@ -1,5 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Set the given policy to NEW. If it does not exist, it will not be set. If it
# is already set to NEW (most likely due to predating the minimum required CMake
@@ -47,7 +46,7 @@ include(StaticDependencies)
STRING(TOUPPER "${CMAKE_PROJECT_NAME}" PROJECT_NAME_UCASE)
SET(PROJECT_YEAR 2025)
SET(PROJECT_YEAR 2024)
SET(PROJECT_AUTHOR "LMMS Developers")
SET(PROJECT_URL "https://lmms.io")
@@ -103,10 +102,7 @@ option(WANT_DEBUG_ASAN "Enable AddressSanitizer" OFF)
option(WANT_DEBUG_TSAN "Enable ThreadSanitizer" OFF)
option(WANT_DEBUG_MSAN "Enable MemorySanitizer" OFF)
option(WANT_DEBUG_UBSAN "Enable UndefinedBehaviorSanitizer" OFF)
option(WANT_DEBUG_GPROF "Enable gprof profiler" OFF)
OPTION(BUNDLE_QT_TRANSLATIONS "Install Qt translation files for LMMS" OFF)
option(WANT_DEBUG_CPACK "Show detailed logs for packaging commands" OFF)
option(WANT_CPACK_TARBALL "Request CPack to create a tarball instead of an installer" OFF)
IF(LMMS_BUILD_APPLE)
@@ -174,7 +170,7 @@ check_library_exists(rt shm_open "" LMMS_HAVE_LIBRT)
LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}")
FIND_PACKAGE(Qt5 5.9.0 COMPONENTS Core Gui Widgets Xml Svg REQUIRED)
FIND_PACKAGE(Qt5 5.9.0 COMPONENTS Core Gui Widgets Xml REQUIRED)
FIND_PACKAGE(Qt5 COMPONENTS LinguistTools QUIET)
include_directories(SYSTEM
@@ -189,7 +185,6 @@ SET(QT_LIBRARIES
Qt5::Gui
Qt5::Widgets
Qt5::Xml
Qt5::Svg
)
IF(LMMS_BUILD_LINUX AND WANT_VST)
@@ -241,28 +236,29 @@ if(LMMS_BUILD_APPLE)
endif()
find_package(Perl)
if(WANT_LV2)
if(PKG_CONFIG_FOUND)
pkg_check_modules(LV2 lv2)
endif()
find_package(Lilv)
if(Lilv_FOUND)
set(LILV_LIBRARIES Lilv::lilv)
endif()
# Ensure both dependencies are found
if(NOT LV2_FOUND)
set(STATUS_LV2 "not found, install lv2 or set PKG_CONFIG_PATH appropriately")
elseif(NOT Lilv_FOUND)
set(STATUS_LV2 "not found, install lilv or set PKG_CONFIG_PATH appropriately")
else()
set(LMMS_HAVE_LV2 TRUE)
set(STATUS_LV2 "OK")
endif()
else()
set(STATUS_LV2 "not built as requested")
endif()
IF(WANT_LV2)
IF(PKG_CONFIG_FOUND)
PKG_CHECK_MODULES(LV2 lv2)
PKG_CHECK_MODULES(LILV lilv-0)
ENDIF()
IF(NOT LV2_FOUND AND NOT LILV_FOUND)
UNSET(LV2_FOUND CACHE)
UNSET(LILV_FOUND CACHE)
FIND_PACKAGE(LV2 CONFIG)
FIND_PACKAGE(LILV CONFIG)
IF(LILV_FOUND)
SET(LILV_LIBRARIES "lilv::lilv")
ENDIF()
ENDIF()
IF(LV2_FOUND AND LILV_FOUND)
SET(LMMS_HAVE_LV2 TRUE)
SET(STATUS_LV2 "OK")
ELSE()
SET(STATUS_LV2 "not found, install it or set PKG_CONFIG_PATH appropriately")
ENDIF()
ELSE(WANT_LV2)
SET(STATUS_LV2 "not built as requested")
ENDIF(WANT_LV2)
IF(WANT_SUIL)
IF(PKG_CONFIG_FOUND)
@@ -270,7 +266,6 @@ IF(WANT_SUIL)
IF(SUIL_FOUND)
SET(LMMS_HAVE_SUIL TRUE)
SET(STATUS_SUIL "OK")
find_package(SuilModules)
ELSE()
SET(STATUS_SUIL "not found, install it or set PKG_CONFIG_PATH appropriately")
ENDIF()
@@ -609,17 +604,6 @@ ELSE()
SET (STATUS_DEBUG_FPE "Disabled")
ENDIF(WANT_DEBUG_FPE)
if(WANT_DEBUG_CPACK)
if((LMMS_BUILD_WIN32 AND CMAKE_VERSION VERSION_LESS "3.19") OR WANT_CPACK_TARBALL)
set(STATUS_DEBUG_CPACK "Wanted but disabled due to unsupported configuration")
else()
set(CPACK_DEBUG TRUE)
set(STATUS_DEBUG_CPACK "Enabled")
endif()
else()
set(STATUS_DEBUG_CPACK "Disabled")
endif()
# check for libsamplerate
FIND_PACKAGE(Samplerate 0.1.8 MODULE REQUIRED)
@@ -680,22 +664,6 @@ elseif(MSVC)
add_compile_options("/utf-8")
ENDIF()
# gcc builds support gprof for profiling
# clang too seems to support gprof, but i couldn't get it working.
# if needed, change the if condition to "GNU|CLANG"
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(STATUS_GPROF ", NOT SUPPORTED BY THIS COMPILER")
set(WANT_DEBUG_GPROF OFF)
endif()
if(WANT_DEBUG_GPROF)
add_compile_options(-pg)
add_link_options(-pg)
set(STATUS_GPROF "OK")
else()
set(STATUS_GPROF "Disabled ${STATUS_GPROF}")
endif()
# add enabled sanitizers
function(add_sanitizer sanitizer supported_compilers want_flag status_flag)
if(${want_flag})
@@ -730,6 +698,7 @@ include(CompileCache)
ADD_SUBDIRECTORY(cmake)
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(plugins)
ADD_SUBDIRECTORY(benchmarks)
ADD_SUBDIRECTORY(tests)
ADD_SUBDIRECTORY(data)
ADD_SUBDIRECTORY(doc)
@@ -759,7 +728,7 @@ IF(LMMS_BUILD_LINUX)
"${CMAKE_BINARY_DIR}/lmmsconfig.h"
"${CMAKE_BINARY_DIR}/lmmsversion.h"
"${CMAKE_SOURCE_DIR}/src/gui/embed.cpp"
DESTINATION "include/lmms/")
DESTINATION "${CMAKE_INSTALL_PREFIX}/include/lmms/")
ENDIF(LMMS_BUILD_LINUX)
#
@@ -863,8 +832,6 @@ MESSAGE(
"* Debug using ThreadSanitizer : ${STATUS_DEBUG_TSAN}\n"
"* Debug using MemorySanitizer : ${STATUS_DEBUG_MSAN}\n"
"* Debug using UBSanitizer : ${STATUS_DEBUG_UBSAN}\n"
"* Debug packaging commands : ${STATUS_DEBUG_CPACK}\n"
"* Profile using GNU profiler : ${STATUS_GPROF}\n"
)
MESSAGE(

18
LICENSE.MIT.txt Normal file
View File

@@ -0,0 +1,18 @@
The MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,39 +1,31 @@
<div align="center">
<h1>
<img src="https://raw.githubusercontent.com/LMMS/artwork/master/Icon%20%26%20Mimetypes/lmms-64x64.svg" alt="LMMS Logo"><br>LMMS
</h1>
<p>Cross-platform music production software</p>
<p>
<a href="https://lmms.io/">Website</a>
⦁︎
<a href="https://github.com/LMMS/lmms/releases">Releases</a>
⦁︎
<a href="https://github.com/LMMS/lmms/wiki">Developer wiki</a>
⦁︎
<a href="https://lmms.io/documentation">User manual</a>
⦁︎
<a href="https://lmms.io/showcase/">Showcase</a>
⦁︎
<a href="https://lmms.io/lsp/">Sharing platform</a>
</p>
<p>
<a href="https://github.com/LMMS/lmms/actions/workflows/build.yml"><img src="https://github.com/LMMS/lmms/actions/workflows/build.yml/badge.svg" alt="Build status"></a>
<a href="https://lmms.io/download"><img src="https://img.shields.io/github/release/LMMS/lmms.svg?maxAge=3600" alt="Latest stable release"></a>
<a href="https://github.com/LMMS/lmms/releases"><img src="https://img.shields.io/github/downloads/LMMS/lmms/total.svg?maxAge=3600" alt="Overall downloads on Github"></a>
<a href="https://discord.gg/3sc5su7"><img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" alt="Join the chat at Discord"></a>
<a href="https://www.transifex.com/lmms/lmms/"><img src="https://img.shields.io/badge/localise-on_transifex-green.svg"></a>
</p>
</div>
# ![LMMS Logo](https://raw.githubusercontent.com/LMMS/artwork/master/Icon%20%26%20Mimetypes/lmms-64x64.svg) LMMS
[![Build status](https://github.com/LMMS/lmms/actions/workflows/build.yml/badge.svg)](https://github.com/LMMS/lmms/actions/workflows/build.yml)
[![Latest stable release](https://img.shields.io/github/release/LMMS/lmms.svg?maxAge=3600)](https://lmms.io/download)
[![Overall downloads on Github](https://img.shields.io/github/downloads/LMMS/lmms/total.svg?maxAge=3600)](https://github.com/LMMS/lmms/releases)
[![Join the chat at Discord](https://img.shields.io/badge/chat-on%20discord-7289DA.svg)](https://discord.gg/3sc5su7)
[![Localise on transifex](https://img.shields.io/badge/localise-on_transifex-green.svg)](https://www.transifex.com/lmms/lmms/)
What is LMMS?
--------------
LMMS is an open-source cross-platform digital audio workstation designed for music production. It includes an advanced Piano Roll, Beat Sequencer, Song Editor, and Mixer for composing, arranging, and mixing music. It comes with 15+ synthesizer plugins by default, along with VST(i) and SoundFont2 support.
LMMS is a free cross-platform alternative to commercial programs like
FL Studio®, which allow you to produce music with your computer. This includes
the creation of melodies and beats, the synthesis and mixing of sounds, and
arranging of samples. You can have fun with your MIDI-keyboard and much more;
all in a user-friendly and modern interface.
[Homepage](https://lmms.io)<br>
[Downloads/Releases](https://github.com/LMMS/lmms/releases)<br>
[Developer Wiki](https://github.com/LMMS/lmms/wiki)<br>
[Artist & User Wiki/Documentation](https://lmms.io/documentation)<br>
[Sound Demos](https://lmms.io/showcase/)<br>
[LMMS Sharing Platform](https://lmms.io/lsp/) Share your songs!
Features
---------
* Song-Editor for arranging melodies, samples, patterns, and automation
* Song-Editor for composing songs
* Pattern-Editor for creating beats and patterns
* An easy-to-use Piano-Roll for editing patterns and melodies
* A Mixer with unlimited mixer channels and arbitrary number of effects
@@ -45,13 +37,22 @@ Features
Building
---------
See [Compiling LMMS](https://github.com/LMMS/lmms/wiki/Compiling)
See [Compiling LMMS](https://github.com/LMMS/lmms/wiki/Compiling) on our
wiki for information on how to build LMMS.
Join LMMS-development
----------------------
If you are interested in LMMS, its programming, artwork, testing, writing demo songs, (and improving this README...) or something like that, you're welcome to participate in the development of LMMS!
If you are interested in LMMS, its programming, artwork, testing, writing demo
songs, (and improving this README...) or something like that, you're welcome
to participate in the development of LMMS!
Information about what you can do and how can be found in the [wiki](https://github.com/LMMS/lmms/wiki).
Information about what you can do and how can be found in the
[wiki](https://github.com/LMMS/lmms/wiki).
Before coding a new big feature, please _always_ [file an issue](https://github.com/LMMS/lmms/issues/new) for your idea and suggestions about your feature and about the intended implementation on GitHub, or ask in one of the tech channels on Discord and wait for replies! Maybe there are different ideas, improvements, or hints, or maybe your feature is not welcome/needed at the moment.
Before coding a new big feature, please _always_
[file an issue](https://github.com/LMMS/lmms/issues/new) for your idea and
suggestions about your feature and about the intended implementation on GitHub,
or ask in one of the tech channels on Discord and wait for replies! Maybe there are different ideas, improvements, or hints, or
maybe your feature is not welcome/needed at the moment.

13
benchmarks/CMakeLists.txt Normal file
View File

@@ -0,0 +1,13 @@
SET(CMAKE_AUTOMOC ON)
ADD_EXECUTABLE(benchmarks
EXCLUDE_FROM_ALL
benchmark.cpp
)
# TODO replace usages of include_directories in src/CMakeLists.txt with target_include_directories
# and remove this line (also in tests/CMakeLists.txt)
target_include_directories(benchmarks PRIVATE $<TARGET_PROPERTY:lmmsobjs,INCLUDE_DIRECTORIES>)
target_static_libraries(benchmarks PRIVATE lmmsobjs)
target_compile_features(benchmarks PRIVATE cxx_std_17)

130
benchmarks/benchmark.cpp Normal file
View File

@@ -0,0 +1,130 @@
#include <thread>
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include "libcds.h"
#include <cds/container/vyukov_mpmc_cycle_queue.h>
#include "Engine.h"
#include "PerfLog.h"
#include "LocklessList.h"
#include "MemoryPool.h"
#include "NotePlayHandle.h"
using namespace lmms;
template<typename T>
using LocklessQueue = cds::container::VyukovMPMCCycleQueue<T>;
template<typename Alloc>
void benchmark_allocator(QString name, Alloc&& alloc, size_t n, size_t I)
{
using T = typename Alloc::value_type;
constexpr size_t S = sizeof(T);
std::vector<T*> ptrs{n};
PerfLogTimer timer(QString("Allocate: %1 x %2 x %3 bytes, %4")
.arg(I).arg(n).arg(S).arg(name));
for (size_t i=0; i < I; i++)
{
for (size_t j=0; j < n; j++) {
ptrs[j] = alloc.allocate(1);
}
for (size_t j=0; j < n; j++) {
alloc.deallocate(ptrs[j], 1);
}
}
}
template<typename Alloc>
void benchmark_allocator_threaded(QString name, Alloc&& alloc, size_t n, size_t t)
{
using T = typename Alloc::value_type;
constexpr size_t S = sizeof(T);
LocklessQueue<T*> ptrs{n};
PerfLogTimer timer(QString("Allocate multi-threaded: %1 x %2 bytes using %3 threads, %4")
.arg(n).arg(S).arg(t).arg(name));
std::vector<std::thread> threads; threads.reserve(t*2);
std::atomic_uint_fast64_t allocated{0};
std::atomic_uint_fast64_t deallocated{0};
for (size_t i=0; i < t; i++) {
threads.emplace_back([&]() {
while(allocated++ < n) {
auto ptr = alloc.allocate(1);
ptrs.push(ptr);
}
});
}
for (size_t i=0; i < t; i++) {
threads.emplace_back([&]() {
while(deallocated++ < n) {
T* ptr;
while (! ptrs.pop(ptr));
alloc.deallocate(ptr, 1);
}
});
}
for (std::thread& thread : threads) {
thread.join();
}
}
int main(int argc, char* argv[])
{
new QCoreApplication(argc, argv);
using Stack = LocklessList<size_t>;
{
size_t n = 100 * 1000 * 1000;
Stack stack{n};
PerfLogTimer timer("LocklessList: Insert 100m entries, single-threaded, pre-allocated");
for (size_t i=0; i < n; i++) {
stack.push(i);
}
}
{
size_t n = 50 * 1000 * 1000;
size_t t = 5;
Stack stack{n};
std::vector<std::thread> threads; threads.reserve(t);
PerfLogTimer timer("LocklessList: Push 50m entries, multi-threaded, pre-allocated");
for (int i=0; i < 5; i++) {
threads.emplace_back([&]() {
for (size_t j=0; j < n / t; j++) {
stack.push(j);
}
});
}
for (int i=0; i < 5; i++) {
threads.at(i).join();
}
}
{
size_t n = 10 * 1000 * 1000;
constexpr size_t S = 256;
using T = std::array<char, S>;
benchmark_allocator("std::allocator", std::allocator<T>{}, n, 1);
benchmark_allocator("MemoryPool", MemoryPool<T>{n}, n, 1);
}
{
size_t n = 10 * 1000 * 1000;
constexpr size_t S = 256;
using T = std::array<char, S>;
benchmark_allocator_threaded("std::allocator", std::allocator<T>{}, n, 4);
benchmark_allocator_threaded("MemoryPool", MemoryPool<T>{n}, n, 4);
}
}

View File

@@ -14,14 +14,10 @@ ENDIF()
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME_UCASE}")
SET(CPACK_SOURCE_GENERATOR "TBZ2")
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}")
SET(CPACK_PACKAGE_EXECUTABLES "${CMAKE_PROJECT_NAME}" "${PROJECT_NAME_UCASE} binary")
# Disable strip for Debug|RelWithDebInfo
if(CMAKE_BUILD_TYPE MATCHES "Deb")
unset(CPACK_STRIP_FILES)
else()
set(CPACK_STRIP_FILES TRUE)
endif()
IF(NOT DEFINED WIN32)
SET(CPACK_STRIP_FILES "bin/${CMAKE_PROJECT_NAME};${PLUGIN_DIR}/*.so")
SET(CPACK_PACKAGE_EXECUTABLES "${CMAKE_PROJECT_NAME}" "${PROJECT_NAME_UCASE} binary")
ENDIF()
IF(LMMS_BUILD_WIN32)
ADD_SUBDIRECTORY(nsis)

View File

@@ -1,3 +1,24 @@
SET(MACOSX_BUNDLE_ICON_FILE "icon.icns")
SET(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_NAME_UCASE}")
SET(MACOSX_BUNDLE_LONG_VERSION_STRING "${VERSION}")
SET(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME_UCASE}")
SET(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VERSION}")
SET(MACOSX_BUNDLE_BUNDLE_VERSION "${VERSION}")
SET(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT}")
SET(MACOSX_BUNDLE_MIMETYPE "application/x-lmms-project")
SET(MACOSX_BUNDLE_MIMETYPE_ICON "project.icns")
SET(MACOSX_BUNDLE_MIMETYPE_ID "io.lmms")
SET(MACOSX_BUNDLE_PROJECT_URL "${PROJECT_URL}")
SET(MACOSX_BUNDLE_DMG_TITLE "${MACOSX_BUNDLE_BUNDLE_NAME} ${MACOSX_BUNDLE_LONG_VERSION_STRING}")
# FIXME: appdmg won't allow volume names > 27 char
# See also https://github.com/LinusU/node-appdmg/issues/48
STRING(SUBSTRING "${MACOSX_BUNDLE_DMG_TITLE}" 0 27 MACOSX_BUNDLE_DMG_TITLE)
CONFIGURE_FILE("lmms.plist.in" "${CMAKE_BINARY_DIR}/Info.plist")
CONFIGURE_FILE("install_apple.sh.in" "${CMAKE_BINARY_DIR}/install_apple.sh" @ONLY)
CONFIGURE_FILE("package_apple.json.in" "${CMAKE_BINARY_DIR}/package_apple.json" @ONLY)
IF(CMAKE_OSX_ARCHITECTURES)
SET(DMG_ARCH "${CMAKE_OSX_ARCHITECTURES}")
ELSEIF(IS_ARM64)
@@ -8,31 +29,18 @@ ELSE()
SET(DMG_ARCH "x86_64")
ENDIF()
# Standard CPack options
set(CPACK_GENERATOR "External" PARENT_SCOPE)
set(CPACK_EXTERNAL_ENABLE_STAGING TRUE PARENT_SCOPE)
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-mac${APPLE_OS_VER}-${DMG_ARCH}")
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}" PARENT_SCOPE)
set(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_CURRENT_SOURCE_DIR}/MacDeployQt.cmake" PARENT_SCOPE)
# disable cpack's strip: causes missing symbols on macOS
set(CPACK_STRIP_FILES_ORIG "${CPACK_STRIP_FILES}" PARENT_SCOPE)
set(CPACK_STRIP_FILES FALSE PARENT_SCOPE)
# DMG creation target
SET(DMG_FILE "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-${VERSION}-mac${APPLE_OS_VER}-${DMG_ARCH}.dmg")
# Custom vars to expose to Cpack
# must be prefixed with "CPACK_" per https://stackoverflow.com/a/46526757/3196753)
set(CPACK_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE)
set(CPACK_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE)
set(CPACK_BINARY_DIR "${CMAKE_BINARY_DIR}" PARENT_SCOPE)
set(CPACK_SOURCE_DIR "${CMAKE_SOURCE_DIR}" PARENT_SCOPE)
set(CPACK_QMAKE_EXECUTABLE "${QT_QMAKE_EXECUTABLE}" PARENT_SCOPE)
set(CPACK_CARLA_LIBRARIES "${CARLA_LIBRARIES}" PARENT_SCOPE)
set(CPACK_PROJECT_NAME "${PROJECT_NAME}" PARENT_SCOPE)
set(CPACK_PROJECT_VERSION "${VERSION}" PARENT_SCOPE)
set(CPACK_PROJECT_NAME_UCASE "${PROJECT_NAME_UCASE}" PARENT_SCOPE)
set(CPACK_PROJECT_URL "${PROJECT_URL}" PARENT_SCOPE)
set(CPACK_SUIL_MODULES "${Suil_MODULES}" PARENT_SCOPE)
set(CPACK_SUIL_MODULES_PREFIX "${Suil_MODULES_PREFIX}" PARENT_SCOPE)
FILE(REMOVE "${DMG_FILE}")
ADD_CUSTOM_TARGET(removedmg
COMMAND touch "\"${DMG_FILE}\"" && rm "\"${DMG_FILE}\""
COMMENT "Removing old DMG")
ADD_CUSTOM_TARGET(dmg
COMMAND appdmg "\"${CMAKE_BINARY_DIR}/package_apple.json\"" "\"${DMG_FILE}\""
DEPENDS "${CMAKE_BINARY_DIR}/package_apple.json"
COMMENT "Generating DMG")
ADD_DEPENDENCIES(dmg removedmg)
# see also ../postinstall/CMakeLists.txt
if(CMAKE_VERSION VERSION_LESS "3.19")
message(WARNING "DMG creation requires at least CMake 3.19")
endif()

View File

@@ -1,175 +0,0 @@
# Create a macOS .dmg desktop installer using macdeployqt
#
# Copyright (c) 2025, Tres Finocchiaro, <tres.finocchiaro@gmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Variables must be prefixed with "CPACK_" to be visible here
set(lmms "${CPACK_PROJECT_NAME}")
set(APP "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/${CPACK_PROJECT_NAME_UCASE}.app")
# Toggle command echoing & verbosity
# 0 = no output, 1 = error/warning, 2 = normal, 3 = debug
if(DEFINED ENV{CPACK_DEBUG})
set(CPACK_DEBUG "$ENV{CPACK_DEBUG}")
endif()
if(NOT CPACK_DEBUG)
set(VERBOSITY 1)
set(COMMAND_ECHO NONE)
else()
set(VERBOSITY 2)
set(COMMAND_ECHO STDOUT)
endif()
# Detect release|debug build
if(NOT CPACK_STRIP_FILES_ORIG)
# -use-debug-libs implies -no-strip
if(CPACK_QMAKE_EXECUTABLE MATCHES "/homebrew/|/usr/local")
message(STATUS "Homebrew does not provide debug qt libraries, replacing \"-use-debug-libs\" with \"-no-strip\" instead")
set(USE_DEBUG_LIBS -no-strip)
else()
set(USE_DEBUG_LIBS -use-debug-libs)
endif()
endif()
# Cleanup CPack "External" json, txt files, old DMG files
file(GLOB cleanup "${CPACK_BINARY_DIR}/${lmms}-*.json"
"${CPACK_BINARY_DIR}/${lmms}-*.dmg"
"${CPACK_BINARY_DIR}/install_manifest.txt")
list(SORT cleanup)
file(REMOVE ${cleanup})
# Create bundle structure
file(MAKE_DIRECTORY "${APP}/Contents/MacOS")
file(MAKE_DIRECTORY "${APP}/Contents/Frameworks")
file(MAKE_DIRECTORY "${APP}/Contents/Resources")
# Fix layout
file(RENAME "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib" "${APP}/Contents/lib")
file(RENAME "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/share" "${APP}/Contents/share")
file(RENAME "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/bin" "${APP}/Contents/bin")
# Move binaries into Contents/MacOS
file(RENAME "${APP}/Contents/bin/${lmms}" "${APP}/Contents/MacOS/${lmms}")
file(RENAME "${APP}/Contents/lib/${lmms}/RemoteZynAddSubFx" "${APP}/Contents/MacOS/RemoteZynAddSubFx")
file(REMOVE_RECURSE "${APP}/Contents/bin")
file(REMOVE_RECURSE "${APP}/Contents/share/man1")
file(REMOVE_RECURSE "${APP}/Contents/include")
# Copy missing files
# Convert https://lmms.io to io.lmms
string(REPLACE "." ";" mime_parts "${CPACK_PROJECT_URL}")
string(REPLACE ":" ";" mime_parts "${mime_parts}")
string(REPLACE "/" "" mime_parts "${mime_parts}")
list(REMOVE_AT mime_parts 0)
list(REVERSE mime_parts)
list(JOIN mime_parts "." MACOS_MIMETYPE_ID)
configure_file("${CPACK_CURRENT_SOURCE_DIR}/lmms.plist.in" "${APP}/Contents/Info.plist" @ONLY)
file(COPY "${CPACK_CURRENT_SOURCE_DIR}/project.icns" DESTINATION "${APP}/Contents/Resources")
file(COPY "${CPACK_CURRENT_SOURCE_DIR}/icon.icns" DESTINATION "${APP}/Contents/Resources")
file(RENAME "${APP}/Contents/Resources/icon.icns" "${APP}/Contents/Resources/${lmms}.icns")
# Copy Suil modules
if(CPACK_SUIL_MODULES)
set(SUIL_MODULES_TARGET "${APP}/Contents/Frameworks/${CPACK_SUIL_MODULES_PREFIX}")
file(MAKE_DIRECTORY "${SUIL_MODULES_TARGET}")
file(COPY ${CPACK_SUIL_MODULES} DESTINATION "${SUIL_MODULES_TARGET}")
endif()
# Make all libraries writable for macdeployqt
file(CHMOD_RECURSE "${APP}/Contents" PERMISSIONS
OWNER_EXECUTE OWNER_WRITE OWNER_READ
GROUP_EXECUTE GROUP_WRITE GROUP_READ
WORLD_READ)
# Qt6: Fix @rpath bug https://github.com/orgs/Homebrew/discussions/2823
include(CreateSymlink)
get_filename_component(QTBIN "${CPACK_QMAKE_EXECUTABLE}" DIRECTORY)
get_filename_component(QTDIR "${QTBIN}" DIRECTORY)
create_symlink("${QTDIR}/lib" "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib")
# Replace @rpath with @loader_path for Carla
execute_process(COMMAND install_name_tool -change
"@rpath/libcarlabase.dylib"
"@loader_path/libcarlabase.dylib"
"${APP}/Contents/lib/${lmms}/libcarlapatchbay.so"
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
execute_process(COMMAND install_name_tool -change
"@rpath/libcarlabase.dylib"
"@loader_path/libcarlabase.dylib"
"${APP}/Contents/lib/${lmms}/libcarlarack.so"
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
# Build list of executables to inform macdeployqt about
# e.g. -executable=foo.dylib -executable=bar.dylib
file(GLOB LIBS "${APP}/Contents/lib/${lmms}/*.so")
# Inform macdeployqt about LADSPA plugins; may depend on bundled fftw3f, etc.
file(GLOB LADSPA "${APP}/Contents/lib/${lmms}/ladspa/*.so")
# Inform macdeployqt about remote plugins
file(GLOB REMOTE_PLUGINS "${APP}/Contents/MacOS/*Remote*")
# Collect, sort and dedupe all libraries
list(APPEND LIBS ${LADSPA})
list(APPEND LIBS ${REMOTE_PLUGINS})
list(APPEND LIBS ${CPACK_SUIL_MODULES})
list(REMOVE_DUPLICATES LIBS)
list(SORT LIBS)
# Construct macdeployqt parameters
foreach(_lib IN LISTS LIBS)
if(EXISTS "${_lib}")
list(APPEND EXECUTABLES "-executable=${_lib}")
endif()
endforeach()
# Call macdeployqt
get_filename_component(QTBIN "${CPACK_QMAKE_EXECUTABLE}" DIRECTORY)
message(STATUS "Calling ${QTBIN}/macdeployqt ${APP} [... executables]")
execute_process(COMMAND "${QTBIN}/macdeployqt" "${APP}" ${EXECUTABLES}
-verbose=${VERBOSITY}
${USE_DEBUG_LIBS}
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
# Cleanup symlink
file(REMOVE "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib")
# Remove dummy carla libs, relink to a sane location (e.g. /Applications/Carla.app/...)
# (must be done after calling macdeployqt)
file(GLOB CARLALIBS "${APP}/Contents/lib/${lmms}/libcarla*")
foreach(_carlalib IN LISTS CARLALIBS)
foreach(_lib "${CPACK_CARLA_LIBRARIES}")
set(_oldpath "../../Frameworks/lib${_lib}.dylib")
set(_newpath "Carla.app/Contents/MacOS/lib${_lib}.dylib")
execute_process(COMMAND install_name_tool -change
"@loader_path/${_oldpath}"
"@executable_path/../../../${_newpath}"
"${_carlalib}"
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
file(REMOVE "${APP}/Contents/Frameworks/lib${_lib}.dylib")
endforeach()
endforeach()
# Call ad-hoc codesign manually (CMake offers this as well)
execute_process(COMMAND codesign --force --deep --sign - "${APP}"
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
# Create DMG
# appdmg won't allow volume names > 27 char https://github.com/LinusU/node-alias/issues/7
find_program(APPDMG_BIN appdmg REQUIRED)
string(SUBSTRING "${CPACK_PROJECT_NAME_UCASE} ${CPACK_PROJECT_VERSION}" 0 27 APPDMG_VOLUME_NAME)
# We'll configure this file twice (again in MacDeployQt.cmake once we know CPACK_TEMPORARY_INSTALL_DIRECTORY)
configure_file("${CPACK_CURRENT_SOURCE_DIR}/appdmg.json.in" "${CPACK_CURRENT_BINARY_DIR}/appdmg.json" @ONLY)
execute_process(COMMAND "${APPDMG_BIN}"
"${CPACK_CURRENT_BINARY_DIR}/appdmg.json"
"${CPACK_BINARY_DIR}/${CPACK_PACKAGE_FILE_NAME}.dmg"
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)

View File

@@ -1,9 +0,0 @@
{
"title": "@APPDMG_VOLUME_NAME@",
"background": "@CPACK_SOURCE_DIR@/cmake/apple/background.png",
"icon-size": 128,
"contents": [
{ "x": 139, "y": 200, "type": "file", "path": "@CPACK_TEMPORARY_INSTALL_DIRECTORY@/@CPACK_PROJECT_NAME_UCASE@.app" },
{ "x": 568, "y": 200, "type": "link", "path": "/Applications" }
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

View File

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@@ -0,0 +1,104 @@
#!/bin/bash
# Creates Apple ".app" bundle for @PROJECT_NAME_UCASE@
# Note:
# Examine linkings using `otool -L somelib.so`
# Debug the loading of dynamic libraries using `export DYLD_PRINT_LIBRARIES=1`
set -e
# Place to create ".app" bundle
APP="@CMAKE_BINARY_DIR@/@PROJECT_NAME_UCASE@.app"
MSG_COLOR='\x1B[1;36m'
COLOR_RESET='\x1B[0m'
echo -e "$MSG_COLOR\n\nCreating App Bundle \"$APP\"...$COLOR_RESET"
qtpath="$(dirname "@QT_QMAKE_EXECUTABLE@")"
export PATH="$PATH:$qtpath"
# Remove any old .app bundles
rm -Rf "$APP"
# Copy/overwrite Info.plist
command cp "@CMAKE_BINARY_DIR@/Info.plist" "@CMAKE_INSTALL_PREFIX@/"
# Create .app bundle containing contents from CMAKE_INSTALL_PREFIX
mkdir -p "$APP/Contents/MacOS"
mkdir -p "$APP/Contents/Frameworks"
mkdir -p "$APP/Contents/Resources"
cd "@CMAKE_INSTALL_PREFIX@"
cp -R ./* "$APP/Contents"
cp "@CMAKE_SOURCE_DIR@/cmake/apple/"*.icns "$APP/Contents/Resources/"
# Make all libraries writable for macdeployqt
cd "$APP"
find . -type f -print0 | xargs -0 chmod u+w
lmmsbin="MacOS/@CMAKE_PROJECT_NAME@"
zynbin="MacOS/RemoteZynAddSubFx"
# Move lmms binary
mv "$APP/Contents/bin/@CMAKE_PROJECT_NAME@" "$APP/Contents/$lmmsbin"
# Fix zyn linking
mv "$APP/Contents/lib/lmms/RemoteZynAddSubFx" "$APP/Contents/$zynbin"
# Replace @rpath with @loader_path for Carla
# See also plugins/CarlaBase/CMakeLists.txt
# This MUST be done BEFORE calling macdeployqt
install_name_tool -change @rpath/libcarlabase.dylib \
@loader_path/libcarlabase.dylib \
"$APP/Contents/lib/lmms/libcarlapatchbay.so"
install_name_tool -change @rpath/libcarlabase.dylib \
@loader_path/libcarlabase.dylib \
"$APP/Contents/lib/lmms/libcarlarack.so"
# Link lmms binary
_executables="${_executables} -executable=$APP/Contents/$zynbin"
# Build a list of shared objects in target/lib/lmms
for file in "$APP/Contents/lib/lmms/"*.so; do
_thisfile="$APP/Contents/lib/lmms/${file##*/}"
_executables="${_executables} -executable=$_thisfile"
done
# Build a list of shared objects in target/lib/lmms/ladspa
for file in "$APP/Contents/lib/lmms/ladspa/"*.so; do
_thisfile="$APP/Contents/lib/lmms/ladspa/${file##*/}"
_executables="${_executables} -executable=$_thisfile"
done
# Finalize .app
# shellcheck disable=SC2086
macdeployqt "$APP" $_executables
# Carla is a standalone plugin. Remove library, look for it side-by-side LMMS.app
# This MUST be done AFTER calling macdeployqt
#
# For example:
# /Applications/LMMS.app
# /Applications/Carla.app
carlalibs=$(echo "@CARLA_LIBRARIES@"|tr ";" "\n")
# Loop over all libcarlas, fix linking
for file in "$APP/Contents/lib/lmms/"libcarla*; do
_thisfile="$APP/Contents/lib/lmms/${file##*/}"
for lib in $carlalibs; do
_oldpath="../../Frameworks/lib${lib}.dylib"
_newpath="Carla.app/Contents/MacOS/lib${lib}.dylib"
# shellcheck disable=SC2086
install_name_tool -change @loader_path/$_oldpath \
@executable_path/../../../$_newpath \
"$_thisfile"
rm -f "$APP/Contents/Frameworks/lib${lib}.dylib"
done
done
# Cleanup
rm -rf "$APP/Contents/bin"
# Codesign
codesign --force --deep --sign - "$APP"
echo -e "\nFinished.\n\n"

View File

@@ -7,13 +7,13 @@
<string>English</string>
<key>CFBundleIconFile</key>
<string>@CPACK_PROJECT_NAME@</string>
<string>@MACOSX_BUNDLE_ICON_FILE@</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleGetInfoString</key>
<string>@CPACK_PROJECT_NAME_UCASE@ @CPACK_PROJECT_VERSION@</string>
<string>@MACOSX_BUNDLE_GUI_IDENTIFIER@ @MACOSX_BUNDLE_LONG_VERSION_STRING@</string>
<!--
#############################################################
@@ -29,38 +29,38 @@
#############################################################
-->
<key>CFBundleSignature</key>
<string>@CPACK_PROJECT_NAME_UCASE@</string>
<string>@MACOSX_BUNDLE_GUI_IDENTIFIER@</string>
<key>CFBundleExecutable</key>
<string>@CPACK_PROJECT_NAME@</string>
<string>@MACOSX_BUNDLE_GUI_IDENTIFIER@</string>
<key>CFBundleVersion</key>
<string>@CPACK_PROJECT_VERSION@</string>
<string>@MACOSX_BUNDLE_LONG_VERSION_STRING@</string>
<key>CFBundleShortVersionString</key>
<string>@VERSIONCPACK_PROJECT_VERSION@</string>
<string>@MACOSX_BUNDLE_LONG_VERSION_STRING@</string>
<key>CFBundleName</key>
<string>@CPACK_PROJECT_NAME_UCASE@</string>
<string>@MACOSX_BUNDLE_BUNDLE_NAME@</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleIdentifier</key>
<string>@MACOS_MIMETYPE_ID@</string>
<string>@MACOSX_BUNDLE_MIMETYPE_ID@</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>mmpz</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>project</string>
<string>@MACOSX_BUNDLE_MIMETYPE_ICON@</string>
<key>CFBundleTypeName</key>
<string>@CPACK_PROJECT_NAME_UCASE@ Project</string>
<string>@MACOSX_BUNDLE_GUI_IDENTIFIER@ Project</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>mmpz</string>
@@ -69,19 +69,19 @@
<string>Editor</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/x-@CPACK_PROJECT_NAME@-project</string>
<string>@MACOSX_BUNDLE_MIMETYPE@</string>
</array>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>mmp</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>project</string>
<string>@MACOSX_BUNDLE_MIMETYPE_ICON@</string>
<key>CFBundleTypeName</key>
<string>@CPACK_PROJECT_NAME_UCASE@ Project (uncompressed)</string>
<string>@MACOSX_BUNDLE_GUI_IDENTIFIER@ Project (uncompressed)</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>mmp</string>
@@ -90,23 +90,23 @@
<string>Editor</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/x-@CPACK_PROJECT_NAME@-project</string>
<string>@MACOSX_BUNDLE_MIMETYPE@</string>
</array>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>@MACOS_MIMETYPE_ID@.mmpz</string>
<string>@MACOSX_BUNDLE_MIMETYPE_ID@.mmpz</string>
<key>UTTypeReferenceURL</key>
<string>@CPACK_PROJECT_URL@</string>
<string>@MACOSX_BUNDLE_PROJECT_URL@</string>
<key>UTTypeDescription</key>
<string>@CPACK_PROJECT_VERSIONPROJECT_NAME_UCASE@ Project</string>
<string>@MACOSX_BUNDLE_GUI_IDENTIFIER@ Project</string>
<key>UTTypeIconFile</key>
<string>project</string>
<string>@MACOSX_BUNDLE_MIMETYPE_ICON@</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
@@ -122,13 +122,13 @@
<dict>
<key>UTTypeIdentifier</key>
<string>@MACOS_MIMETYPE_ID@.mmp</string>
<string>@MACOSX_BUNDLE_MIMETYPE_ID@.mmp</string>
<key>UTTypeReferenceURL</key>
<string>@CPACK_PROJECT_URL@</string>
<string>@MACOSX_BUNDLE_PROJECT_URL@</string>
<key>UTTypeDescription</key>
<string>@CPACK_PROJECT_NAME_UCASE@ Project (uncompressed)</string>
<string>@MACOSX_BUNDLE_GUI_IDENTIFIER@ Project (uncompressed)</string>
<key>UTTypeIconFile</key>
<string>project</string>
<string>@MACOSX_BUNDLE_MIMETYPE_ICON@</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>

View File

@@ -0,0 +1,9 @@
{
"title": "@MACOSX_BUNDLE_DMG_TITLE@",
"background": "@CMAKE_SOURCE_DIR@/cmake/apple/dmg_branding.png",
"icon-size": 128,
"contents": [
{ "x": 139, "y": 200, "type": "file", "path": "@CMAKE_BINARY_DIR@/@MACOSX_BUNDLE_BUNDLE_NAME@.app" },
{ "x": 568, "y": 200, "type": "link", "path": "/Applications" }
]
}

View File

@@ -1,9 +1,6 @@
SET(PLUGIN_FILES "")
IF(LMMS_BUILD_WIN32)
INSTALL(FILES $<TARGET_FILE:Qt5::QWindowsIntegrationPlugin> DESTINATION platforms)
INSTALL(FILES $<TARGET_FILE:Qt5::QSvgIconPlugin> DESTINATION iconengines)
INSTALL(FILES $<TARGET_FILE:Qt5::QSvgPlugin> DESTINATION imageformats)
INSTALL(FILES $<TARGET_FILE:Qt5::Svg> DESTINATION .)
INSTALL(FILES $<TARGET_FILE:Qt5::QWindowsIntegrationPlugin> DESTINATION platforms)
ENDIF()
IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES)
@@ -43,10 +40,17 @@ ENDIF()
if(LMMS_HAVE_STK AND (LMMS_BUILD_WIN32 OR LMMS_BUILD_APPLE))
if(STK_RAWWAVE_ROOT)
file(GLOB RAWWAVES "${STK_RAWWAVE_ROOT}/*.raw")
list(SORT RAWWAVES)
install(FILES ${RAWWAVES} DESTINATION "${DATA_DIR}/stk/rawwaves")
else()
message(WARNING "Can't find STK rawwave root!")
endif()
endif()
IF(LMMS_BUILD_APPLE)
INSTALL(CODE "EXECUTE_PROCESS(COMMAND chmod u+x ${CMAKE_BINARY_DIR}/install_apple.sh)")
INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_BINARY_DIR}/install_apple.sh RESULT_VARIABLE EXIT_CODE)
IF(NOT EXIT_CODE EQUAL 0)
MESSAGE(FATAL_ERROR \"Execution of install_apple.sh failed\")
ENDIF()
")
ENDIF()

View File

@@ -1,51 +1,19 @@
install(DIRECTORY icons/ DESTINATION "${DATA_DIR}/icons/hicolor")
install(FILES lmms.desktop DESTINATION "${DATA_DIR}/applications")
install(FILES lmms.xml DESTINATION "${DATA_DIR}/mime/packages")
INSTALL(DIRECTORY icons/ DESTINATION "${DATA_DIR}/icons/hicolor")
INSTALL(FILES lmms.desktop DESTINATION "${DATA_DIR}/applications")
INSTALL(FILES lmms.xml DESTINATION "${DATA_DIR}/mime/packages")
# Preserve old CPack behavior
if(WANT_CPACK_TARBALL)
message(STATUS "Skipping AppImage creation")
return()
endif()
# AppImage creation target
SET(APPIMAGE_FILE "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-${VERSION}-linux-${CMAKE_SYSTEM_PROCESSOR}.AppImage")
# Standard CPack options
set(CPACK_GENERATOR "External" PARENT_SCOPE)
set(CPACK_EXTERNAL_ENABLE_STAGING true PARENT_SCOPE)
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-linux-${CMAKE_SYSTEM_PROCESSOR}")
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}" PARENT_SCOPE)
set(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_CURRENT_SOURCE_DIR}/LinuxDeploy.cmake" PARENT_SCOPE)
CONFIGURE_FILE("package_linux.sh.in" "${CMAKE_BINARY_DIR}/package_linux.sh" @ONLY)
# Custom vars to expose to Cpack
# must be prefixed with "CPACK_" per https://stackoverflow.com/a/46526757/3196753)
set(CPACK_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE)
set(CPACK_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE)
set(CPACK_BINARY_DIR "${CMAKE_BINARY_DIR}" PARENT_SCOPE)
set(CPACK_SOURCE_DIR "${CMAKE_SOURCE_DIR}" PARENT_SCOPE)
set(CPACK_QMAKE_EXECUTABLE "${QT_QMAKE_EXECUTABLE}" PARENT_SCOPE)
set(CPACK_CARLA_LIBRARIES "${CARLA_LIBRARIES}" PARENT_SCOPE)
set(CPACK_WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIRS}" PARENT_SCOPE)
set(CPACK_WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIRS}" PARENT_SCOPE)
set(CPACK_PROJECT_NAME "${PROJECT_NAME}" PARENT_SCOPE)
set(CPACK_PROJECT_NAME_UCASE "${PROJECT_NAME_UCASE}" PARENT_SCOPE)
set(CPACK_PROJECT_VERSION "${VERSION}" PARENT_SCOPE)
set(CPACK_CMAKE_COMMAND "${CMAKE_COMMAND}" PARENT_SCOPE)
set(CPACK_SUIL_MODULES "${Suil_MODULES}" PARENT_SCOPE)
set(CPACK_SUIL_MODULES_PREFIX "${Suil_MODULES_PREFIX}" PARENT_SCOPE)
set(CPACK_STK_RAWWAVE_ROOT "${STK_RAWWAVE_ROOT}" PARENT_SCOPE)
# TODO: Canidate for DetectMachine.cmake
if(IS_X86_64)
set(CPACK_TARGET_ARCH x86_64 PARENT_SCOPE)
elseif(IS_X86)
set(CPACK_TARGET_ARCH i386 PARENT_SCOPE)
elseif(IS_ARM64)
set(CPACK_TARGET_ARCH aarch64 PARENT_SCOPE)
elseif(IS_ARM32)
set(CPACK_TARGET_ARCH armhf PARENT_SCOPE)
else()
set(CPACK_TARGET_ARCH unknown PARENT_SCOPE)
endif()
if(CMAKE_VERSION VERSION_LESS "3.19")
message(WARNING "AppImage creation requires at least CMake 3.19")
endif()
FILE(REMOVE "${APPIMAGE_FILE}")
ADD_CUSTOM_TARGET(removeappimage
COMMAND rm -f "${APPIMAGE_FILE}"
COMMENT "Removing old AppImage")
ADD_CUSTOM_TARGET(appimage
COMMAND chmod +x "${CMAKE_BINARY_DIR}/package_linux.sh"
COMMAND "${CMAKE_BINARY_DIR}/package_linux.sh"
COMMENT "Generating AppImage"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
ADD_DEPENDENCIES(appimage removeappimage)

View File

@@ -1,327 +0,0 @@
# Create a Linux desktop installer using linuxdeploy
# * Creates a relocatable LMMS.AppDir installation in build/_CPack_Packages using linuxdeploy
# * If CPACK_TOOL=appimagetool or is not set, bundles AppDir into redistributable ".AppImage" file
# * If CPACK_TOOL=makeself is provided, bundles into a redistributable ".run" file
#
# Copyright (c) 2025, Tres Finocchiaro, <tres.finocchiaro@gmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Variables must be prefixed with "CPACK_" to be visible here
set(lmms "${CPACK_PROJECT_NAME}")
set(LMMS "${CPACK_PROJECT_NAME_UCASE}")
set(ARCH "${CPACK_TARGET_ARCH}")
set(APP "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/${LMMS}.AppDir")
# Target AppImage file
set(APPIMAGE_FILE "${CPACK_BINARY_DIR}/${CPACK_PACKAGE_FILE_NAME}.AppImage")
set(APPIMAGE_BEFORE_RENAME "${CPACK_BINARY_DIR}/${LMMS}-${ARCH}.AppImage")
set(DESKTOP_FILE "${APP}/usr/share/applications/${lmms}.desktop")
# Determine which packaging tool to use
if(NOT CPACK_TOOL)
# Pick up environmental variable
if(DEFINED ENV{CPACK_TOOL})
set(CPACK_TOOL "$ENV{CPACK_TOOL}")
else()
set(CPACK_TOOL "appimagetool")
endif()
endif()
# Toggle command echoing & verbosity
# 0 = no output, 1 = error/warning, 2 = normal, 3 = debug
if(DEFINED ENV{CPACK_DEBUG})
set(CPACK_DEBUG "$ENV{CPACK_DEBUG}")
endif()
if(NOT CPACK_DEBUG)
set(VERBOSITY 1)
set(APPIMAGETOOL_VERBOSITY "")
set(COMMAND_ECHO NONE)
set(OUTPUT_QUIET OUTPUT_QUIET)
else()
set(VERBOSITY 2)
set(APPIMAGETOOL_VERBOSITY "--verbose")
set(COMMAND_ECHO STDOUT)
unset(OUTPUT_QUIET)
endif()
include(DownloadBinary)
include(CreateSymlink)
# Cleanup CPack "External" json, txt files, old AppImage files
file(GLOB cleanup "${CPACK_BINARY_DIR}/${lmms}-*.json"
"${CPACK_BINARY_DIR}/${lmms}-*.AppImage"
"${CPACK_BINARY_DIR}/install_manifest.txt")
list(SORT cleanup)
file(REMOVE ${cleanup})
# Download and extract linuxdeploy
download_binary(LINUXDEPLOY_BIN
"https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${ARCH}.AppImage"
linuxdeploy-${ARCH}.AppImage
FALSE)
# Guess the path to appimagetool
set(APPIMAGETOOL_BIN "${CPACK_CURRENT_BINARY_DIR}/.linuxdeploy-${ARCH}.AppImage/squashfs-root/plugins/linuxdeploy-plugin-appimage/appimagetool-prefix/AppRun")
# Download linuxdeploy-plugin-qt
download_binary(LINUXDEPLOY_PLUGIN_BIN
"https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-${ARCH}.AppImage"
linuxdeploy-plugin-qt-${ARCH}.AppImage
FALSE)
message(STATUS "Creating AppDir ${APP}...")
file(REMOVE_RECURSE "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/include")
file(MAKE_DIRECTORY "${APP}/usr")
# Setup AppDir structure (/usr/bin, /usr/lib, /usr/share... etc)
file(GLOB files "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/*")
list(SORT files)
foreach(_file ${files})
get_filename_component(_filename "${_file}" NAME)
if(NOT _filename MATCHES ".AppDir")
file(RENAME "${_file}" "${APP}/usr/${_filename}")
endif()
endforeach()
# Copy Suil modules
if(CPACK_SUIL_MODULES)
set(SUIL_MODULES_TARGET "${APP}/usr/lib/${CPACK_SUIL_MODULES_PREFIX}")
file(MAKE_DIRECTORY "${SUIL_MODULES_TARGET}")
file(COPY ${CPACK_SUIL_MODULES} DESTINATION "${SUIL_MODULES_TARGET}")
endif()
# Copy stk/rawwaves
if(CPACK_STK_RAWWAVE_ROOT)
set(STK_RAWWAVE_TARGET "${APP}/usr/share/stk/rawwaves/")
file(MAKE_DIRECTORY "${STK_RAWWAVE_TARGET}")
file(GLOB RAWWAVES "${CPACK_STK_RAWWAVE_ROOT}/*.raw")
file(COPY ${RAWWAVES} DESTINATION "${STK_RAWWAVE_TARGET}")
endif()
# Ensure project's "qmake" executable is first on the PATH
get_filename_component(QTBIN "${CPACK_QMAKE_EXECUTABLE}" DIRECTORY)
set(ENV{PATH} "${QTBIN}:$ENV{PATH}")
# Promote finding our own libraries first
set(ENV{LD_LIBRARY_PATH} "${APP}/usr/lib/${lmms}/:${APP}/usr/lib/${lmms}/optional:$ENV{LD_LIBRARY_PATH}")
# Skip slow searching of copyright files https://github.com/linuxdeploy/linuxdeploy/issues/278
set(ENV{DISABLE_COPYRIGHT_FILES_DEPLOYMENT} 1)
# Patch desktop file
file(APPEND "${DESKTOP_FILE}" "X-AppImage-Version=${CPACK_PROJECT_VERSION}\n")
# Custom scripts to run immediately before lmms is executed
file(COPY "${CPACK_SOURCE_DIR}/cmake/linux/apprun-hooks" DESTINATION "${APP}")
file(REMOVE "${APP}/apprun-hooks/README.md")
# Prefer a hard-copy of .DirIcon over appimagetool's symlinking
# 256x256 default for Cinnamon Desktop https://forums.linuxmint.com/viewtopic.php?p=2585952
file(COPY "${APP}/usr/share/icons/hicolor/256x256/apps/${lmms}.png" DESTINATION "${APP}")
file(RENAME "${APP}/${lmms}.png" "${APP}/.DirIcon")
file(COPY "${APP}/usr/share/icons/hicolor/256x256/apps/${lmms}.png" DESTINATION "${APP}")
# Build list of libraries to inform linuxdeploy about
# e.g. --library=foo.so --library=bar.so
file(GLOB LIBS "${APP}/usr/lib/${lmms}/*.so")
# Inform linuxdeploy about LADSPA plugins; may depend on bundled fftw3f, etc.
file(GLOB LADSPA "${APP}/usr/lib/${lmms}/ladspa/*.so")
# Inform linuxdeploy about remote plugins
file(GLOB REMOTE_PLUGINS "${APP}/usr/lib/${lmms}/*Remote*")
# Inform linuxdeploy-plugin-qt about wayland plugin
set(ENV{EXTRA_PLATFORM_PLUGINS} "libqwayland-generic.so")
set(ENV{EXTRA_QT_MODULES} "waylandcompositor")
# Collect, sort and dedupe all libraries
list(APPEND LIBS ${LADSPA})
list(APPEND LIBS ${REMOTE_PLUGINS})
list(APPEND LIBS ${CPACK_SUIL_MODULES})
list(REMOVE_DUPLICATES LIBS)
list(SORT LIBS)
# Handle non-relinkable files (e.g. RemoveVstPlugin[32|64], but not NativeLinuxRemoteVstPlugin)
list(FILTER LIBS EXCLUDE REGEX "\\/RemoteVst")
# Construct linuxdeploy parameters
foreach(_lib IN LISTS LIBS)
if(EXISTS "${_lib}")
list(APPEND LIBRARIES "--library=${_lib}")
endif()
endforeach()
list(APPEND SKIP_LIBRARIES "--exclude-library=*libgallium*")
# Call linuxdeploy
message(STATUS "Calling ${LINUXDEPLOY_BIN} --appdir \"${APP}\" ... [... libraries].")
execute_process(COMMAND "${LINUXDEPLOY_BIN}"
--appdir "${APP}"
--desktop-file "${DESKTOP_FILE}"
--plugin qt
${LIBRARIES}
${SKIP_LIBRARIES}
--verbosity ${VERBOSITY}
WORKING_DIRECTORY "${CPACK_CURRENT_BINARY_DIR}"
${OUTPUT_QUIET}
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
# Remove svg ambitiously placed by linuxdeploy
file(REMOVE "${APP}/${lmms}.svg")
# Remove libraries that are normally system-provided
file(GLOB EXCLUDE_LIBS
"${APP}/usr/lib/libwine*"
"${APP}/usr/lib/libcarla_native*"
"${APP}/usr/lib/${lmms}/optional/libcarla*"
"${APP}/usr/lib/libjack*")
list(SORT EXCLUDE_LIBS)
foreach(_lib IN LISTS EXCLUDE_LIBS)
if(EXISTS "${_lib}")
file(REMOVE "${_lib}")
endif()
endforeach()
# FIXME: Remove when linuxdeploy supports subfolders https://github.com/linuxdeploy/linuxdeploy/issues/305
foreach(_lib IN LISTS LIBS)
if(EXISTS "${_lib}")
file(REMOVE "${_lib}")
endif()
endforeach()
# Move RemotePlugins into to LMMS_PLUGIN_DIR
file(GLOB WINE_VST_LIBS
"${APP}/usr/lib/${lmms}/RemoteVstPlugin*"
"${APP}/usr/lib/${lmms}/32")
foreach(_file IN LISTS WINE_VST_LIBS)
if(EXISTS "${_file}")
get_filename_component(_name "${_file}" NAME)
file(RENAME "${_file}" "${APP}/usr/lib/${_name}")
endif()
endforeach()
file(GLOB WINE_32_LIBS
"${APP}/usr/lib/${lmms}/RemoteVstPlugin*")
foreach(_lib IN LISTS WINE_64_LIBS)
if(EXISTS "${_lib}")
get_filename_component(_file "${_lib}" NAME)
file(RENAME "${_lib}" "${APP}/usr/lib/${_file}")
endif()
endforeach()
file(REMOVE_RECURSE "${SUIL_MODULES_TARGET}" "${APP}/usr/lib/${lmms}/ladspa/")
# Copy "exclude-list" lib(s) into specified location
macro(copy_excluded ldd_target name_match destination relocated_lib)
execute_process(COMMAND ldd
"${ldd_target}"
OUTPUT_VARIABLE ldd_output
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
# escape periods to avoid double-escaping
string(REPLACE "." "\\." name_match "${name_match}")
# cli output --> list
string(REPLACE "\n" ";" ldd_list "${ldd_output}")
foreach(line ${ldd_list})
if(line MATCHES "${name_match}")
# Assumes format "libname.so.0 => /lib/location/libname.so.0 (0x00007f48d0b0e000)"
string(REPLACE " " ";" parts "${line}")
list(LENGTH parts len)
math(EXPR index "${len}-2")
list(GET parts ${index} lib)
# Resolve any possible symlinks
file(REAL_PATH "${lib}" libreal)
get_filename_component(symname "${lib}" NAME)
get_filename_component(realname "${libreal}" NAME)
file(MAKE_DIRECTORY "${destination}")
# Copy, but with original symlink name
file(COPY "${libreal}" DESTINATION "${destination}")
file(RENAME "${destination}/${realname}" "${destination}/${symname}")
set("${relocated_lib}" "${destination}/${symname}")
break()
endif()
endforeach()
endmacro()
# copy libjack
copy_excluded("${APP}/usr/bin/${lmms}" "libjack.so" "${APP}/usr/lib/jack" relocated_jack)
if(relocated_jack)
# libdb's not excluded however we'll re-use the macro as a convenient path calculation
# See https://github.com/LMMS/lmms/issues/7689s
copy_excluded("${relocated_jack}" "libdb-" "${APP}/usr/lib/jack" relocated_libdb)
get_filename_component(libdb_name "${relocated_libdb}" NAME)
if(relocated_libdb AND EXISTS "${APP}/usr/lib/${libdb_name}")
# assume a copy already resides in usr/lib and symlink
file(REMOVE "${relocated_libdb}")
create_symlink("${APP}/usr/lib/${libdb_name}" "${relocated_libdb}")
endif()
endif()
# cleanup empty directories
file(REMOVE_RECURSE "${APP}/usr/lib/${lmms}/optional/")
if(CPACK_TOOL STREQUAL "appimagetool")
# Create ".AppImage" file using appimagetool (default)
# appimage plugin needs ARCH set when running in extracted form from squashfs-root / CI
set(ENV{ARCH} "${ARCH}")
message(STATUS "Finishing the AppImage...")
execute_process(COMMAND "${APPIMAGETOOL_BIN}" "${APP}" "${APPIMAGE_FILE}"
${APPIMAGETOOL_VERBOSITY}
${OUTPUT_QUIET}
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
message(STATUS "AppImage created: ${APPIMAGE_FILE}")
elseif(CPACK_TOOL STREQUAL "makeself")
# Create self-extracting ".run" script using makeself
find_program(MAKESELF_BIN makeself REQUIRED)
message(STATUS "Finishing the .run file using ${MAKESELF_BIN}...")
string(REPLACE ".AppImage" ".run" RUN_FILE "${APPIMAGE_FILE}")
configure_file(
"${CPACK_SOURCE_DIR}/cmake/linux/makeself_setup.sh.in" "${APP}/setup.sh" @ONLY
FILE_PERMISSIONS
OWNER_EXECUTE OWNER_WRITE OWNER_READ
GROUP_EXECUTE GROUP_WRITE GROUP_READ
WORLD_READ)
if(OUTPUT_QUIET)
set(MAKESELF_QUIET "--quiet")
set(ERROR_QUIET ERROR_QUIET)
endif()
# makeself.sh [args] archive_dir file_name label startup_script [script_args]
file(REMOVE "${RUN_FILE}")
execute_process(COMMAND "${MAKESELF_BIN}"
--keep-umask
--nox11
${MAKESELF_QUIET}
"${APP}"
"${RUN_FILE}"
"${LMMS} Installer"
"./setup.sh"
${OUTPUT_QUIET}
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
# ensure the installer can be executed as a script file
execute_process(COMMAND "${RUN_FILE}" --help
${OUTPUT_QUIET}
${ERROR_QUIET}
COMMAND_ECHO ${COMMAND_ECHO}
COMMAND_ERROR_IS_FATAL ANY)
message(STATUS "Installer created: ${RUN_FILE}")
else()
message(FATAL_ERROR "Packaging tool CPACK_TOOL=\"${CPACK_TOOL}\" is not yet supported")
endif()

View File

@@ -1,11 +0,0 @@
# AppRun Hooks
Scripts placed in this directory will automatically be bundled into AppImages
(e.g. `LMMS.AppDir/apprun-hooks`) and executed immediately before lmms.
Quoting:
> "Sometimes it's important to perform actions before running the actual app. Some plugins might have to set e.g.,
> environment variables to work properly."
See also: https://github.com/linuxdeploy/linuxdeploy/wiki/Plugin-system#apprun-hooks

View File

@@ -1,46 +0,0 @@
#!/usr/bin/env bash
# Workaround nuances with carla being an optional-yet-hard-linked plugin
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
ME="$( basename "${BASH_SOURCE[0]}")"
CARLA_LIB_NAME="libcarla_native-plugin.so"
KNOWN_LOCATIONS=("lib" "lib64")
unset CARLA_LIB_FILE
# Check for carla at "known" locations
if command -v carla > /dev/null 2>&1; then
CARLA_PATH="$(command -v carla)"
CARLA_PREFIX="${CARLA_PATH%/bin*}"
# Look for libcarla_native-plugin.so in adjacent lib directory
for lib in "${KNOWN_LOCATIONS[@]}"; do
if [ -e "$CARLA_PREFIX/$lib/carla/$CARLA_LIB_NAME" ]; then
# Add directory to LD_LIBRARY_PATH so libcarlabase.so can find it
CARLA_LIB_FILE="$CARLA_PREFIX/$lib/carla/$CARLA_LIB_NAME"
export LD_LIBRARY_PATH="$CARLA_PREFIX/$lib/carla/:$LD_LIBRARY_PATH"
echo "[$ME] Carla appears to be installed on this system at $CARLA_PREFIX/$lib/carla so we'll use it." >&2
break
fi
done
else
echo "[$ME] Carla does not appear to be installed, we'll remove it from the plugin listing." >&2
export "LMMS_EXCLUDE_PLUGINS=libcarla,${LMMS_EXCLUDE_PLUGINS}"
export "LMMS_EXCLUDE_LADSPA=libcarla,${LMMS_EXCLUDE_LADSPA}"
fi
# Additional workarounds for library conflicts
# libgobject has been versioned "2.0" for over 20 years, but the ABI is constantly changing
KNOWN_CONFLICTS=("libgobject-2.0.so.0")
if [ -n "$CARLA_LIB_FILE" ]; then
for conflict in "${KNOWN_CONFLICTS[@]}"; do
# Only prepend LD_PRELOAD if we bundle the same version
if [ -e "$DIR/usr/lib/$conflict" ]; then
conflict_sys="$(ldd "$CARLA_LIB_FILE" | grep "$conflict" | awk '{print $3}')"
if [ -e "$conflict_sys" ]; then
# Add library to LD_PRELOAD so lmms can find it over its bundled version
echo "[$ME] Preferring the system's \"$conflict\" over the version bundled." >&2
export LD_PRELOAD="$conflict_sys:$LD_PRELOAD"
fi
fi
done
fi

View File

@@ -1,15 +0,0 @@
#!/usr/bin/env bash
# Workaround crash when jack is missing by providing a dummy version
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
ME="$( basename "${BASH_SOURCE[0]}")"
# Set language to English
export LC_ALL=C
if ldd "$DIR/usr/bin/lmms" |grep "libjack.so" |grep "not found" > /dev/null 2>&1; then
echo "[$ME] Jack does not appear to be installed. That's OK, we'll use a dummy version instead." >&2
export LD_LIBRARY_PATH="$DIR/usr/lib/jack:$LD_LIBRARY_PATH"
else
echo "[$ME] Jack appears to be installed on this system, so we'll use it." >&2
fi
# Restore language
unset LC_ALL

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env bash
# Workaround Unity desktop menubar integration
# - Unity's menubar relocation breaks Qt's MDI window handling in Linux
# - Unity was default in Ubuntu 11.04 - 18.04
if [ "$XDG_CURRENT_DESKTOP" = "Unity" ]; then
export QT_X11_NO_NATIVE_MENUBAR=1
fi

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env bash
# Workaround libraries being incorrectly placed in usr/lib (e.g. instead of usr/lib/lmms, etc)
# FIXME: Remove when linuxdeploy supports subfolders https://github.com/linuxdeploy/linuxdeploy/issues/305
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
export LMMS_PLUGIN_DIR="$DIR/usr/lib/"
export LADSPA_PATH="$DIR/usr/lib/"
export SUIL_MODULE_DIR="$DIR/usr/lib/"

View File

@@ -1,7 +0,0 @@
#!/usr/bin/env bash
ME="$( basename "${BASH_SOURCE[0]}")"
# Workaround crash in VirtualBox when hardware rendering is enabled
if lsmod |grep vboxguest > /dev/null 2>&1; then
echo "[$ME] VirtualBox detected. Forcing libgl software rendering." >&2
export LIBGL_ALWAYS_SOFTWARE=1;
fi

View File

@@ -1,12 +0,0 @@
#!/usr/bin/env bash
# Configure QPlatform Abstraction (qpa) to prefer X-Protocol C-Bindings (xcb) over Wayland
ME="$( basename "${BASH_SOURCE[0]}")"
if [ -n "$QT_QPA_PLATFORM" ]; then
echo "[$ME] QT_QPA_PLATFORM=\"$QT_QPA_PLATFORM\" was provided, using." >&2
else
export QT_QPA_PLATFORM="xcb"
echo "[$ME] Defaulting to QT_QPA_PLATFORM=\"$QT_QPA_PLATFORM\" for compatibility purposes." >&2
echo "[$ME] To force wayland, set QT_QPA_PLATFORM=\"wayland\" or call using \"-platform wayland\"." >&2
fi

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
export PATH="$PATH:/sbin"
if command -v carla > /dev/null 2>&1; then
CARLAPATH="$(command -v carla)"
CARLAPREFIX="${CARLAPATH%/bin*}"
echo "Carla appears to be installed on this system at $CARLAPREFIX/lib[64]/carla so we'll use it." >&2
export LD_LIBRARY_PATH=$CARLAPREFIX/lib/carla:$CARLAPREFIX/lib64/carla:$LD_LIBRARY_PATH
else
echo "Carla does not appear to be installed. That's OK, please ignore any related library errors." >&2
fi
export LD_LIBRARY_PATH=$DIR/usr/lib/:$DIR/usr/lib/lmms:$LD_LIBRARY_PATH
# Prevent segfault on VirualBox
if lsmod |grep vboxguest > /dev/null 2>&1; then
echo "VirtualBox detected. Forcing libgl software rendering." >&2
export LIBGL_ALWAYS_SOFTWARE=1;
fi
if ldconfig -p | grep libjack.so.0 > /dev/null 2>&1; then
echo "Jack appears to be installed on this system, so we'll use it." >&2
else
echo "Jack does not appear to be installed. That's OK, we'll use a dummy version instead." >&2
export LD_LIBRARY_PATH=$DIR/usr/lib/lmms/optional:$LD_LIBRARY_PATH
fi
QT_X11_NO_NATIVE_MENUBAR=1 "$DIR"/usr/bin/lmms.real "$@"

View File

@@ -1,35 +0,0 @@
#!/bin/bash
# Halt on first error
set -e
DESTDIR="/opt/@CPACK_PROJECT_NAME@"
BASHCOMPLETIONS="/usr/share/bash-completion/completions"
if [ "$(id -u)" != "0" ]; then
# Prepend "$HOME" so we can install to a writable location
DESTDIR="${HOME}${DESTDIR}"
BASHCOMPLETIONS="${HOME}/.local/share/bash-completion/completions"
echo "Installing as a regular user to ${DESTDIR}/..."
else
echo "Installing as elevated user to ${DESTDIR}/..."
fi
# Deploy @CPACK_PROJECT_NAME_UCASE@
mkdir -p "${DESTDIR}"
unalias cp &> /dev/null || true
cp -rf ./* "${DESTDIR}"
rm -f "${DESTDIR}/setup.sh"
mv "${DESTDIR}/AppRun" "${DESTDIR}/@CPACK_PROJECT_NAME@"
# Install bash completions
mkdir -p "${BASHCOMPLETIONS}"
ln -sf "${DESTDIR}/usr/share/@CPACK_PROJECT_NAME@/bash-completion/completions/@CPACK_PROJECT_NAME@" "${BASHCOMPLETIONS}/@CPACK_PROJECT_NAME@"
# Test @CPACK_PROJECT_NAME_UCASE@
echo "Installation complete... Testing \"@CPACK_PROJECT_NAME@\"..."
"${DESTDIR}/@CPACK_PROJECT_NAME@" --allowroot --version &> /dev/null
# TODO: Register file associations, desktop icon, etc
echo "@CPACK_PROJECT_NAME_UCASE@ was installed successfully to ${DESTDIR}. To run:"
echo " ${DESTDIR}/@CPACK_PROJECT_NAME@"

View File

@@ -0,0 +1,213 @@
#!/usr/bin/env bash
# Creates Linux ".AppImage" for @PROJECT_NAME_UCASE@
#
# Depends: linuxdeployqt
#
# Notes: Will attempt to fetch linuxdeployqt automatically (x86_64 only)
# See Also: https://github.com/probonopd/linuxdeployqt/blob/master/BUILDING.md
VERBOSITY=2 # 3=debug
LOGFILE="@CMAKE_BINARY_DIR@/appimage.log"
APPDIR="@CMAKE_BINARY_DIR@/@PROJECT_NAME_UCASE@.AppDir/"
DESKTOPFILE="${APPDIR}usr/share/applications/lmms.desktop"
STRIP=""
# Don't strip for Debug|RelWithDebInfo builds
# shellcheck disable=SC2193
if [[ "@CMAKE_BUILD_TYPE@" == *"Deb"* ]]; then
STRIP="-no-strip"
fi
# Console colors
RED="\\x1B[1;31m"
GREEN="\\x1B[1;32m"
YELLOW="\\x1B[1;33m"
PLAIN="\\x1B[0m"
function error {
echo -e " ${PLAIN}[${RED}error${PLAIN}] ${1}"
return 1
}
function success {
echo -e " ${PLAIN}[${GREEN}success${PLAIN}] ${1}"
}
function skipped {
echo -e " ${PLAIN}[${YELLOW}skipped${PLAIN}] ${1}"
}
# Exit with error message if any command fails
trap "error 'Failed to generate AppImage'; exit 1" ERR
# Run a command silently, but print output if it fails
function run_and_log {
echo -e "\n\n>>>>> $1" >> "$LOGFILE"
output="$("$@" 2>&1)"
status=$?
echo "$output" >> "$LOGFILE"
[[ $status != 0 ]] && echo "$output"
return $status
}
# Blindly assume system arch is appimage arch
ARCH=$(uname -m)
export ARCH
# Check for problematic install locations
INSTALL=$(echo "@CMAKE_INSTALL_PREFIX@" | sed 's/\/*$//g')
if [ "$INSTALL" == "/usr/local" ] || [ "$INSTALL" == "/usr" ] ; then
error "Incompatible CMAKE_INSTALL_PREFIX for creating AppImage: @CMAKE_INSTALL_PREFIX@"
fi
# Ensure linuxdeployqt uses the same qmake version as cmake
PATH="$(dirname "@QT_QMAKE_EXECUTABLE@"):$PATH"
export PATH
# Use linuxdeployqt from env or in PATH
[[ $LINUXDEPLOYQT ]] || LINUXDEPLOYQT="$(which linuxdeployqt 2>/dev/null)" || true
[[ $APPIMAGETOOL ]] || APPIMAGETOOL="$(which appimagetool 2>/dev/null)" || true
# Fetch portable linuxdeployqt if not in PATH
if [[ -z $LINUXDEPLOYQT || -z $APPIMAGETOOL ]]; then
filename="linuxdeployqt-continuous-$ARCH.AppImage"
url="https://github.com/probonopd/linuxdeployqt/releases/download/continuous/$filename"
echo " [.......] Downloading: ${url}"
wget -N -q "$url" && err=0 || err=$?
case "$err" in
0) success "Downloaded $PWD/$filename" ;;
# 8 == server issued 4xx error
8) error "Download failed (perhaps no package available for $ARCH)" ;;
*) error "Download failed" ;;
esac
# Extract AppImage and replace LINUXDEPLOYQT variable with extracted binary
# to support systems without fuse
# Also, we need to set LD_LIBRARY_PATH, but linuxdepoyqt's AppRun unsets it
# See https://github.com/probonopd/linuxdeployqt/pull/370/
chmod +x "$filename"
./"$filename" --appimage-extract >/dev/null
success "Extracted $filename"
# Use the extracted linuxdeployqt and appimagetool
PATH="$(pwd -P)/squashfs-root/usr/bin:$PATH"
[[ $LINUXDEPLOYQT ]] || LINUXDEPLOYQT="$(which linuxdeployqt)"
[[ $APPIMAGETOOL ]] || APPIMAGETOOL="$(which appimagetool)"
fi
# Make skeleton AppDir
echo -e "\nCreating ${APPDIR}..."
rm -rf "${APPDIR}"
mkdir -p "${APPDIR}usr"
success "Created ${APPDIR}"
# Clone install to AppDir
echo -e "\nCopying @CMAKE_INSTALL_PREFIX@ to ${APPDIR}..."
cp -R "@CMAKE_INSTALL_PREFIX@/." "${APPDIR}usr"
rm -rf "${APPDIR}usr/include"
success "${APPDIR}"
# Copy rawwaves directory for stk/mallets
mkdir -p "${APPDIR}usr/share/stk/"
cp -R /usr/share/stk/rawwaves/ "${APPDIR}usr/share/stk/"
# Create a wrapper script which calls the lmms executable
mv "${APPDIR}usr/bin/lmms" "${APPDIR}usr/bin/lmms.real"
cp "@CMAKE_CURRENT_SOURCE_DIR@/launch_lmms.sh" "${APPDIR}usr/bin/lmms"
chmod +x "${APPDIR}usr/bin/lmms"
# Per https://github.com/probonopd/linuxdeployqt/issues/129
unset LD_LIBRARY_PATH
# Ensure linuxdeployqt can find shared objects
export LD_LIBRARY_PATH="${APPDIR}"usr/lib/lmms/:"${APPDIR}"usr/lib/lmms/optional:"$LD_LIBRARY_PATH"
# Move executables so linuxdeployqt can find them
ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx"
VSTLIB32="${APPDIR}usr/lib/lmms/32/RemoteVstPlugin32.exe.so"
VSTLIB64="${APPDIR}usr/lib/lmms/RemoteVstPlugin64.exe.so"
ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx"
VSTBIN32="${APPDIR}usr/bin/RemoteVstPlugin32.exe.so"
VSTBIN64="${APPDIR}usr/bin/RemoteVstPlugin64.exe.so"
mv "$ZYNLIB" "$ZYNBIN"
mv "$VSTLIB32" "$VSTBIN32" || true
mv "$VSTLIB64" "$VSTBIN64" || true
# Handle wine linking
if [ -d "@WINE_32_LIBRARY_DIR@" ] && \
ldd "$VSTBIN32" | grep "libwine\.so" | grep "not found"; then
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"@WINE_32_LIBRARY_DIRS@"
fi
if [ -d "@WINE_64_LIBRARY_DIR@" ] && \
ldd "$VSTBIN64" | grep "libwine\.so" | grep "not found"; then
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"@WINE_64_LIBRARY_DIRS@"
fi
# Patch the desktop file
sed -i 's/.*Exec=.*/Exec=lmms.real/' "$DESKTOPFILE"
echo "X-AppImage-Version=@VERSION@" >> "$DESKTOPFILE"
# Fix linking for soft-linked plugins
for file in "${APPDIR}usr/lib/lmms/"*.so; do
thisfile="${APPDIR}usr/lib/lmms/${file##*/}"
executables="${executables} -executable=$thisfile"
done
executables="${executables} -executable=${ZYNBIN}"
executables="${executables} -executable=${VSTBIN32}"
executables="${executables} -executable=${VSTBIN64}"
executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imp_1199.so"
executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imbeq_1197.so"
executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale_1193.so"
executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale_1194.so"
echo -e "\nWriting verbose output to \"${LOGFILE}\""
echo -n > "$LOGFILE"
# Bundle both qt and non-qt dependencies into appimage format
echo -e "\nBundling and relinking system dependencies..."
# shellcheck disable=SC2086
run_and_log "$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP
success "Bundled and relinked dependencies"
# Link to original location so lmms can find them
ln -sr "$ZYNBIN" "$ZYNLIB"
ln -sr "$VSTBIN32" "$VSTLIB32" || true
ln -sr "$VSTBIN64" "$VSTLIB64" || true
# Remove wine library conflict
rm -f "${APPDIR}/usr/lib/libwine.so.1"
# Use system-provided carla
rm -f "${APPDIR}usr/lib/"libcarla*.so
rm -f "${APPDIR}usr/lib/lmms/optional/"libcarla*.so
# Remove bundled jack in LD_LIBRARY_PATH if exists
if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then
rm "${APPDIR}/usr/lib/libjack.so.0"
fi
# Bundle jack out of LD_LIBRARY_PATH
JACK_LIB=$(ldd "${APPDIR}/usr/bin/lmms.real" | sed -n 's/\tlibjack\.so\.0 => \(.\+\) (0x[0-9a-f]\+)/\1/p')
if [ -e "$JACK_LIB" ]; then
mkdir -p "${APPDIR}usr/lib/lmms/optional/"
cp "$JACK_LIB" "${APPDIR}usr/lib/lmms/optional/"
fi
# Point the AppRun to the shim launcher
rm -f "${APPDIR}/AppRun"
ln -sr "${APPDIR}/usr/bin/lmms" "${APPDIR}/AppRun"
# Add icon
ln -srf "${APPDIR}/lmms.png" "${APPDIR}/.DirIcon"
# Create AppImage
echo -e "\nFinishing the AppImage..."
run_and_log "$APPIMAGETOOL" "${APPDIR}" "@APPIMAGE_FILE@"
success "Created @APPIMAGE_FILE@"
echo -e "\nFinished"

View File

@@ -1,78 +1,93 @@
# Copyright (c) 2024, Tres Finocchiaro, <tres.finocchiaro@gmail.com>
# A wrapper around pkg-config-provided and cmake-provided bash completion that
# will have dynamic behavior at INSTALL() time to allow both root-level
# INSTALL() as well as user-level INSTALL().
#
# See also https://github.com/scop/bash-completion
#
# Copyright (c) 2018, Tres Finocchiaro, <tres.finocchiaro@gmail.com>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
# Description:
# Fail-safe bash-completion installation support
# - Installs to ${CMAKE_INSTALL_PREFIX}/share/bash-completion/completions
# - Attempts to calculate and install to system-wide location
# - See also https://github.com/scop/bash-completion
#
# Usage:
# INCLUDE(BashCompletion)
# BASHCOMP_INSTALL(foo)
# ... where "foo" is a shell script adjacent to the CMakeLists.txt
#
# How it determines BASHCOMP_PKG_PATH, in order:
# 1. Uses BASHCOMP_PKG_PATH if already set (e.g. -DBASHCOMP_PKG_PATH=...)
# a. If not, uses pkg-config's PKG_CHECK_MODULES to determine path
# b. Fallback to cmake's FIND_PACKAGE(bash-completion) path
# c. Fallback to hard-coded /usr/share/bash-completion/completions
# 2. Final fallback to ${CMAKE_INSTALL_PREFIX}/share/bash-completion/completions if
# detected path is unwritable.
# Honor manual override if provided
if(NOT BASHCOMP_PKG_PATH)
# First, use pkg-config, which is the most reliable
find_package(PkgConfig QUIET)
if(PKGCONFIG_FOUND)
PKG_CHECK_MODULES(BASH_COMPLETION bash-completion)
PKG_GET_VARIABLE(BASHCOMP_PKG_PATH bash-completion completionsdir)
else()
# Second, use cmake (preferred but less common)
find_package(bash-completion QUIET)
if(BASH_COMPLETION_FOUND)
set(BASHCOMP_PKG_PATH "${BASH_COMPLETION_COMPLETIONSDIR}")
endif()
endif()
# - Windows does not support bash completion
# - macOS support should eventually be added for Homebrew (TODO)
IF(WIN32)
MESSAGE(STATUS "Bash completion is not supported on this platform.")
ELSEIF(APPLE)
MESSAGE(STATUS "Bash completion is not yet implemented for this platform.")
ELSE()
INCLUDE(FindUnixCommands)
# Honor manual override if provided
IF(NOT BASHCOMP_PKG_PATH)
# First, use pkg-config, which is the most reliable
FIND_PACKAGE(PkgConfig QUIET)
IF(PKGCONFIG_FOUND)
PKG_CHECK_MODULES(BASH_COMPLETION bash-completion)
PKG_GET_VARIABLE(BASHCOMP_PKG_PATH bash-completion completionsdir)
ELSE()
# Second, use cmake (preferred but less common)
FIND_PACKAGE(bash-completion QUIET)
IF(BASH_COMPLETION_FOUND)
SET(BASHCOMP_PKG_PATH "${BASH_COMPLETION_COMPLETIONSDIR}")
ENDIF()
ENDIF()
# Third, use a hard-coded fallback value
if("${BASHCOMP_PKG_PATH}" STREQUAL "")
set(BASHCOMP_PKG_PATH "/usr/share/bash-completion/completions")
endif()
endif()
# Third, use a hard-coded fallback value
IF("${BASHCOMP_PKG_PATH}" STREQUAL "")
SET(BASHCOMP_PKG_PATH "/usr/share/bash-completion/completions")
ENDIF()
ENDIF()
# Always provide a fallback for non-root INSTALL()
# * "lmms" subfolder ensures we don't pollute /usr/local/share/ on default "make install"
set(BASHCOMP_USER_PATH "share/${PROJECT_NAME}/bash-completion/completions")
# Always provide a fallback for non-root INSTALL()
SET(BASHCOMP_USER_PATH "${CMAKE_INSTALL_PREFIX}/share/bash-completion/completions")
macro(BASHCOMP_INSTALL SCRIPT_NAME)
# Note: When running from CPack, message(...) will be supressed unless WARNING
if(WIN32)
message(STATUS "Bash completion is not supported on this platform.")
else()
# Install a copy of bash completion to the default install prefix
# See also: https://github.com/LMMS/lmms/pull/7252/files#r1815749125
install(FILES "${SCRIPT_NAME}" DESTINATION "${BASHCOMP_USER_PATH}")
# Next, blindly attempt a system-wide install, ignoring failure
# See also: https://stackoverflow.com/q/58448332
# * CPack doesn't use CMAKE_INSTALL_PREFIX, so the original will be missing when packaging
# and this step will be skipped
# * For non-root installs (e.g. ../target), this will silently fail
set(BASHCOMP_ORIG "${CMAKE_INSTALL_PREFIX}/${BASHCOMP_USER_PATH}/${CMAKE_PROJECT_NAME}")
set(BASHCOMP_LINK "${BASHCOMP_PKG_PATH}/${CMAKE_PROJECT_NAME}")
if(BASHCOMP_PKG_PATH)
# TODO: CMake 3.21 Use "file(COPY_FILE ...)"
install(CODE "
if(EXISTS \"${BASHCOMP_ORIG}\")
file(REMOVE \"${BASHCOMP_LINK}\")
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
\"${BASHCOMP_ORIG}\"
\"${BASHCOMP_LINK}\"
ERROR_QUIET
RESULT_VARIABLE result)
if(result EQUAL 0)
message(STATUS \"Bash completion-support has been installed to ${BASHCOMP_LINK}\")
endif()
endif()
")
endif()
endif()
endmacro()
# Cmake doesn't allow easy use of conditional logic at INSTALL() time
# this is a problem because ${BASHCOMP_PKG_PATH} may not be writable and we
# need sane fallback behavior for bundled INSTALL() (e.g. .AppImage, etc).
#
# The reason this can't be detected by cmake is that it's fairly common to
# run "cmake" as a one user (i.e. non-root) and "make install" as another user
# (i.e. root).
#
# - Creates a script called "install_${SCRIPT_NAME}_completion.sh" into the
# working binary directory and invokes this script at install.
# - Script handles INSTALL()-time conditional logic for sane ballback behavior
# when ${BASHCOMP_PKG_PATH} is unwritable (i.e. non-root); Something cmake
# can't handle on its own at INSTALL() time)
MACRO(BASHCOMP_INSTALL SCRIPT_NAME)
# A shell script for wrapping conditionl logic
SET(BASHCOMP_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/install_${SCRIPT_NAME}_completion.sh")
FILE(WRITE ${BASHCOMP_SCRIPT} "\
#!${BASH}\n\
set -e\n\
if [ -w \"${BASHCOMP_PKG_PATH}\" ]; then\n\
BASHCOMP_PKG_PATH=\"${BASHCOMP_PKG_PATH}\"\n\
else \n\
BASHCOMP_PKG_PATH=\"\$DESTDIR${BASHCOMP_USER_PATH}\"\n\
fi\n\
echo -e \"\\nInstalling bash completion...\\n\"\n\
mkdir -p \"\$BASHCOMP_PKG_PATH\"\n\
cp \"${CMAKE_CURRENT_SOURCE_DIR}/${SCRIPT_NAME}\" \"\$BASHCOMP_PKG_PATH\"\n\
chmod a+r \"\$BASHCOMP_PKG_PATH/${SCRIPT_NAME}\"\n\
echo -e \"Bash completion for ${SCRIPT_NAME} has been installed to \$BASHCOMP_PKG_PATH/${SCRIPT_NAME}\"\n\
")
INSTALL(CODE "EXECUTE_PROCESS(COMMAND chmod u+x \"install_${SCRIPT_NAME}_completion.sh\" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )")
INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"./install_${SCRIPT_NAME}_completion.sh\" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )")
MESSAGE(STATUS "Bash completion script for ${SCRIPT_NAME} will be installed to ${BASHCOMP_PKG_PATH} or fallback to ${BASHCOMP_USER_PATH} if unwritable.")
ENDMACRO()
ENDIF()

View File

@@ -44,8 +44,8 @@ SET(ENV{LC_ALL} "C")
SET(ENV{LANG} "en_US")
# Submodule list pairs, unparsed (WARNING: Assumes alpha-numeric paths)
STRING(REGEX MATCHALL "path = [-0-9A-Za-z/]+" SUBMODULE_LIST_RAW ${SUBMODULE_DATA})
STRING(REGEX MATCHALL "url = [.:%-0-9A-Za-z/]+" SUBMODULE_URL_RAW ${SUBMODULE_DATA})
STRING(REGEX MATCHALL "path = [-0-9A-Za-z/_]+" SUBMODULE_LIST_RAW ${SUBMODULE_DATA})
STRING(REGEX MATCHALL "url = [.:%-0-9A-Za-z/_]+" SUBMODULE_URL_RAW ${SUBMODULE_DATA})
# Submodule list pairs, parsed
SET(SUBMODULE_LIST "")

View File

@@ -9,19 +9,7 @@ FUNCTION(CheckWineGcc BITNESS WINEGCC_EXECUTABLE RESULT)
return 0;
}
")
# Handle non-Intel platforms
IF(LMMS_HOST_X86_64 OR LMMS_HOST_X86)
SET(MPLATFORM "-m${BITNESS}")
ELSEIF(BITNESS EQUAL 64)
SET(MPLATFORM "")
ELSE()
# Skip 32-bit for non-Intel
SET(${RESULT} False PARENT_SCOPE)
RETURN()
ENDIF()
EXECUTE_PROCESS(COMMAND ${WINEGCC_EXECUTABLE} "${MPLATFORM}"
EXECUTE_PROCESS(COMMAND ${WINEGCC_EXECUTABLE} "-m${BITNESS}"
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx"
"-o" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test"
OUTPUT_QUIET ERROR_QUIET

View File

@@ -1,34 +0,0 @@
# Offer relative symlink support via "cmake -E create_symlink"
# For verbose, set COMMAND_ECHO to STDOUT in calling script
macro(create_symlink filepath sympath)
if(CMAKE_COMMAND)
set(_cmake_command "${CMAKE_COMMAND}")
elseif(CPACK_CMAKE_COMMAND)
set(_cmake_command "${CPACK_CMAKE_COMMAND}")
else()
message(FATAL_ERROR "Sorry, can't resolve variable CMAKE_COMMAND")
endif()
if(NOT IS_ABSOLUTE "${sympath}")
message(FATAL_ERROR "Sorry, this command only works with absolute paths")
endif()
if(NOT DEFINED COMMAND_ECHO)
set(_command_echo NONE)
else()
set(_command_echo "${COMMAND_ECHO}")
endif()
# Calculate the relative path
file(RELATIVE_PATH reldir "${sympath}/../" "${filepath}")
get_filename_component(symname "${sympath}" NAME)
# Calculate the working directory
get_filename_component(sympath_parent "${sympath}" DIRECTORY)
# Create the symbolic link
execute_process(COMMAND "${_cmake_command}" -E create_symlink "${reldir}" "${symname}"
WORKING_DIRECTORY "${sympath_parent}"
COMMAND_ECHO ${_command_echo}
COMMAND_ERROR_IS_FATAL ANY)
endmacro()

View File

@@ -77,15 +77,13 @@ IF(WIN32)
unset(MSVC_VER)
else()
# Cross-compiled
if($ENV{MSYSTEM_CARCH} MATCHES "aarch64")
set(IS_ARM64 TRUE)
set(LMMS_BUILD_WIN64 TRUE)
elseif(WIN64)
set(IS_X86_64 TRUE)
set(LMMS_BUILD_WIN64 TRUE)
else()
set(IS_X86 TRUE)
endif()
# TODO: Handle Windows ARM64 targets
IF(WIN64)
SET(IS_X86_64 TRUE)
SET(LMMS_BUILD_WIN64 TRUE)
ELSE(WIN64)
SET(IS_X86 TRUE)
ENDIF(WIN64)
endif()
ELSE()
# Detect target architecture based on compiler target triple e.g. "x86_64-pc-linux"
@@ -165,26 +163,15 @@ IF(LMMS_BUILD_APPLE)
# Detect Homebrew versus Macports environment
EXECUTE_PROCESS(COMMAND brew --prefix RESULT_VARIABLE DETECT_HOMEBREW OUTPUT_VARIABLE HOMEBREW_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
EXECUTE_PROCESS(COMMAND which port RESULT_VARIABLE DETECT_MACPORTS OUTPUT_VARIABLE MACPORTS_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
IF(DETECT_HOMEBREW EQUAL 0)
SET(HOMEBREW 1)
SET(APPLE_PREFIX "${HOMEBREW_PREFIX}")
# Configure Qt
SET(Qt5_DIR "${HOMEBREW_PREFIX}/opt/qt@5/lib/cmake/Qt5")
SET(Qt5Test_DIR "${HOMEBREW_PREFIX}/opt/qt@5/lib/cmake/Qt5Test")
SET(Qt6_DIR "${HOMEBREW_PREFIX}/opt/qt@6/lib/cmake/Qt6")
SET(Qt6Test_DIR "${HOMEBREW_PREFIX}/opt/qt@6/lib/cmake/Qt6Test")
ELSEIF(DETECT_MACPORTS EQUAL 0)
SET(MACPORTS 1)
# move up two directories
GET_FILENAME_COMPONENT(MACPORTS_PREFIX "${MACPORTS_PREFIX}" DIRECTORY)
GET_FILENAME_COMPONENT(MACPORTS_PREFIX "${MACPORTS_PREFIX}" DIRECTORY)
SET(APPLE_PREFIX "${MACPORTS_PREFIX}")
# Configure Qt
SET(Qt5_DIR "${MACPORTS_PREFIX}/lib/cmake/Qt5")
SET(Qt5Test_DIR "${MACPORTS_PREFIX}/lib/cmake/Qt5Test")
SET(Qt6_DIR "${MACPORTS_PREFIX}/lib/cmake/Qt6")
SET(Qt6Test_DIR "${MACPORTS_PREFIX}/lib/cmake/Qt6Test")
LINK_DIRECTORIES(${LINK_DIRECTORIES} ${APPLE_PREFIX}/lib)
IF(${DETECT_HOMEBREW} EQUAL 0)
SET(HOMEBREW 1)
SET(APPLE_PREFIX "${HOMEBREW_PREFIX}")
ELSEIF(${DETECT_MACPORTS} EQUAL 0)
SET(MACPORTS 1)
GET_FILENAME_COMPONENT(MACPORTS_PREFIX ${MACPORTS_PREFIX} DIRECTORY)
GET_FILENAME_COMPONENT(MACPORTS_PREFIX ${MACPORTS_PREFIX} DIRECTORY)
SET(APPLE_PREFIX "${MACPORTS_PREFIX}")
LINK_DIRECTORIES(${LINK_DIRECTORIES} ${APPLE_PREFIX}/lib)
ENDIF()
# Detect OS Version

View File

@@ -1,143 +0,0 @@
# Downloads an executable from the provided URL for use in a build system
# and optionally prepends it to the PATH
#
# Assumes:
# - CMAKE_CURRENT_BINARY_DIR/[${_name}]
# - CPACK_CURRENT_BINARY_DIR/[${_name}]
# - Fallback to $ENV{TMPDIR}/[RANDOM]/[${_name}]
# - For verbose, set COMMAND_ECHO to STDOUT in calling script
#
macro(download_binary RESULT_VARIABLE _url _name _prepend_to_path)
if(NOT COMMAND_ECHO OR "${COMMAND_ECHO}" STREQUAL "NONE")
set(_command_echo NONE)
set(_output_quiet OUTPUT_QUIET)
set(_error_quiet ERROR_QUIET)
else()
set(_command_echo "${COMMAND_ECHO}")
set(_output_quiet "")
set(_error_quiet "")
endif()
# Check if fuse is needed
if("${RESULT_VARIABLE}" MATCHES "\\.AppImage$" OR "${_name}" MATCHES "\\.AppImage$")
message(STATUS "AppImage detected, we'll extract the AppImage before using")
set(_${RESULT_VARIABLE}_IS_APPIMAGE TRUE)
endif()
# Determine a suitable working directory
if(CMAKE_CURRENT_BINARY_DIR)
# Assume we're called from configure step
set(_working_dir "${CMAKE_CURRENT_BINARY_DIR}")
elseif(CPACK_CURRENT_BINARY_DIR)
# Assume cpack (non-standard variable name, but used throughout)
set(_working_dir "${CPACK_CURRENT_BINARY_DIR}")
else()
# Fallback to somewhere temporary, writable
if($ENV{_tmpdir})
# POSIX
set(_tmpdir "$ENV{_tmpdir}")
elseif($ENV{TEMP})
# Windows
set(_tmpdir "$ENV{TEMP}")
else()
# Linux, shame on you!
find_program(MKTEMP mktemp)
if(MKTEMP)
execute_process(COMMAND mktemp
OUTPUT_VARIABLE _working_dir
OUTPUT_STRIP_TRAILING_WHITESPACE
${_output_quiet}
COMMAND_ECHO ${_command_echo})
# mktemp formats it how we want it
else()
# Ummm... Linux you can do better!
set(_tmpdir "/tmp")
endif()
endif()
if(NOT DEFINED _working_dir)
string(RANDOM subdir)
set(_working_dir "${_tmpdir}/tmp.${subdir}")
endif()
if(NOT EXISTS "${_working_dir}")
file(MAKE_DIRECTORY "${_working_dir}")
endif()
endif()
if(_prepend_to_path)
# Ensure the PATH is configured
string(FIND "$ENV{PATH}" "${_working_dir}" _pathloc)
if(NOT $_pathloc EQUAL 0)
set(ENV{PATH} "${_working_dir}:$ENV{PATH}")
endif()
endif()
# First ensure the binary doesn't already exist
find_program(_${RESULT_VARIABLE} "${_name}" HINTS "${_working_dir}")
set(_binary_path "${_working_dir}/${_name}")
if(NOT _${RESULT_VARIABLE})
message(STATUS "Downloading ${_name} from ${_url}...")
file(DOWNLOAD
"${_url}"
"${_binary_path}"
STATUS DOWNLOAD_STATUS)
# Check if download was successful.
list(GET DOWNLOAD_STATUS 0 STATUS_CODE)
list(GET DOWNLOAD_STATUS 1 ERROR_MESSAGE)
if(NOT ${STATUS_CODE} EQUAL 0)
file(REMOVE "${_binary_path}")
message(FATAL_ERROR "Error downloading ${_url} ${ERROR_MESSAGE}")
endif()
# Ensure the file is executable
file(CHMOD "${_binary_path}" PERMISSIONS
OWNER_EXECUTE OWNER_WRITE OWNER_READ
GROUP_EXECUTE GROUP_WRITE GROUP_READ)
# Ensure it's found
find_program(_${RESULT_VARIABLE} "${_name}" HINTS "${_working_dir}" REQUIRED)
endif()
# We need to create a subdirectory for this binary and symlink it's AppRun to where it's expected
if(_${RESULT_VARIABLE}_IS_APPIMAGE AND NOT IS_SYMLINK "${_${RESULT_VARIABLE}}")
if(NOT COMMAND create_symlink)
include(CreateSymlink)
endif()
message(STATUS "Extracting ${_${RESULT_VARIABLE}} to ${_working_dir}/.${_name}/")
# extract appimage
execute_process(COMMAND "${_${RESULT_VARIABLE}}" --appimage-extract
WORKING_DIRECTORY "${_working_dir}"
COMMAND_ECHO ${_command_echo}
${_output_quiet}
${_error_quiet}
COMMAND_ERROR_IS_FATAL ANY)
# move extracted files to dedicated location (e.g. ".linuxdeploy-x86_64.AppImage/squashfs-root/")
file(MAKE_DIRECTORY "${_working_dir}/.${_name}/")
file(RENAME "${_working_dir}/squashfs-root/" "${_working_dir}/.${_name}/squashfs-root/")
# remove the unusable binary
file(REMOVE "${_${RESULT_VARIABLE}}")
# symlink the expected binary name to the AppRun file
message(STATUS "Creating a symbolic link ${_${RESULT_VARIABLE}} which points to ${_working_dir}/.${_name}/squashfs-root/AppRun")
create_symlink("${_working_dir}/.${_name}/squashfs-root/AppRun" "${_${RESULT_VARIABLE}}")
endif()
# Test the binary
# - TODO: Add support for bad binaries that set "$?" to an error code for no good reason
# - TODO: Add support for Windows binaries expecting "/?" instead of "--help"
message(STATUS "Testing that ${_name} works on this system...")
set(_test_param "--help")
execute_process(COMMAND "${_${RESULT_VARIABLE}}" ${_test_param}
COMMAND_ECHO ${_command_echo}
${_output_quiet}
${_error_quiet}
COMMAND_ERROR_IS_FATAL ANY)
message(STATUS "The binary \"${_${RESULT_VARIABLE}}\" is now available")
set(${RESULT_VARIABLE} "${_${RESULT_VARIABLE}}")
endmacro()

View File

@@ -65,10 +65,6 @@ elseif(MSVC)
"/WX" # Treat warnings as errors
)
endif()
# Silence deprecation warnings for the std::atomic_...<std::shared_ptr> family of functions.
# TODO: Remove once C++20's std::atomic<std::shared_ptr> is fully supported.
add_compile_definitions("_SILENCE_CXX20_OLD_SHARED_PTR_ATOMIC_SUPPORT_DEPRECATION_WARNING")
endif()
# Add the flags to the whole directory tree. We use the third-party flags for

View File

@@ -22,7 +22,7 @@ find_path(FluidSynth_INCLUDE_DIR
)
find_library(FluidSynth_LIBRARY
NAMES "fluidsynth" "fluidsynth-3" "fluidsynth-2" "fluidsynth-1"
NAMES "fluidsynth"
HINTS ${FLUIDSYNTH_PKG_LIBRARY_DIRS}
)

View File

@@ -1,19 +0,0 @@
# Copyright (c) 2025 Dalton Messmer <messmer.dalton/at/gmail.com>
#
# Redistribution and use is allowed according to the terms of the New BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
include(ImportedTargetHelpers)
find_package_config_mode_with_fallback(Lilv Lilv::lilv
LIBRARY_NAMES "lilv" "lilv-0"
INCLUDE_NAMES "lilv/lilv.h"
PKG_CONFIG "lilv-0"
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Lilv
REQUIRED_VARS Lilv_LIBRARY Lilv_INCLUDE_DIRS
VERSION_VAR Lilv_VERSION
)

View File

@@ -14,7 +14,7 @@ if(STK_INCLUDE_DIRS)
list(GET STK_INCLUDE_DIRS 0 STK_INCLUDE_DIR)
find_path(STK_RAWWAVE_ROOT
NAMES silence.raw sinewave.raw
HINTS "${STK_INCLUDE_DIR}/.." "${STK_INCLUDE_DIR}/../.."
HINTS "${STK_INCLUDE_DIR}/.."
PATH_SUFFIXES share/stk/rawwaves share/libstk/rawwaves
)
endif()
@@ -22,6 +22,6 @@ endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(STK
REQUIRED_VARS STK_LIBRARY STK_INCLUDE_DIR STK_RAWWAVE_ROOT
REQUIRED_VARS STK_LIBRARY STK_INCLUDE_DIR
# STK doesn't appear to expose its version, so we can't pass it here
)

View File

@@ -1,40 +0,0 @@
# Copyright (c) 2024 Tres Finocchiaro
#
# Redistribution and use is allowed according to the terms of the New BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# This module defines
# Suil_MODULES: List of full paths to Suil modules (e.g. "/usr/lib/suil-0/libsuil_x11.so;...")
# Suil_MODULES_PREFIX: Only the directory name of the Suil_MODULES path (e.g. "suil-0")
pkg_check_modules(Suil QUIET suil-0)
if(Suil_FOUND)
if(APPLE)
set(_lib_ext "dylib")
elseif(WIN32)
set(_lib_ext "dll")
else()
set(_lib_ext "so")
endif()
# Isolate -- if needed -- the first suil library path (e.g. "/usr/lib/libsuil-0.so")
list(GET Suil_LINK_LIBRARIES 0 _lib)
if(EXISTS "${_lib}")
# Isolate -- if needed -- the first suil library name (e.g. "suil-0")
list(GET Suil_LIBRARIES 0 _modules_prefix)
get_filename_component(_lib_dir "${_lib}" DIRECTORY)
# Construct modules path (e.g. "/usr/lib/suil-0")
set(_modules_dir "${_lib_dir}/${_modules_prefix}")
if(IS_DIRECTORY "${_modules_dir}")
set(Suil_MODULES_PREFIX "${_modules_prefix}")
file(GLOB Suil_MODULES "${_modules_dir}/*.${_lib_ext}")
list(SORT Suil_MODULES)
endif()
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SuilModules
REQUIRED_VARS Suil_MODULES Suil_MODULES_PREFIX
)

View File

@@ -35,8 +35,6 @@ list(APPEND WINE_LOCATIONS
/opt/wine-staging
/opt/wine-devel
/opt/wine-stable
# Gentoo Systems
/etc/eselect/wine
/usr/lib/wine)
# Prepare bin search
@@ -73,13 +71,8 @@ FIND_PROGRAM(WINE_BUILD NAMES winebuild PATHS ${WINE_CXX_LOCATIONS} NO_DEFAULT_P
# Detect wine paths and handle linking problems
IF(WINE_CXX)
# call wineg++ to obtain implied includes and libs
if(LMMS_HOST_X86_64 OR LMMS_HOST_X86)
execute_process(COMMAND ${WINE_CXX} -m32 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_32 ERROR_QUIET)
execute_process(COMMAND ${WINE_CXX} -m64 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_64 ERROR_QUIET)
else()
execute_process(COMMAND ${WINE_CXX} -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_64 ERROR_QUIET)
endif()
execute_process(COMMAND ${WINE_CXX} -m32 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_32 ERROR_QUIET)
execute_process(COMMAND ${WINE_CXX} -m64 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_64 ERROR_QUIET)
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem/usr/include$" BUGGED_WINEGCC)
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem" WINEGCC_INCLUDE_DIR)
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "libwinecrt0\\.a.*" WINECRT_32)

View File

@@ -8,18 +8,6 @@ IF(GIT_FOUND AND NOT FORCE_VERSION)
# number from the environment and add it to the build metadata
if("$ENV{GITHUB_REF}" MATCHES "refs/pull/([0-9]+)/merge")
list(APPEND BUILD_METADATA "pr${CMAKE_MATCH_1}")
# Parse hash from merge description
# e.g. "Merge abc1234 into def4567"
execute_process(
COMMAND "${GIT_EXECUTABLE}" log -n 1 --format=%s
OUTPUT_VARIABLE COMMIT_HASH
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
TIMEOUT 10
OUTPUT_STRIP_TRAILING_WHITESPACE)
# If successful, use the first 7 characters to mimic github's hash style
if(COMMIT_HASH)
string(SUBSTRING "${COMMIT_HASH}" 6 7 COMMIT_HASH)
endif()
endif()
# Look for git tag information (e.g. Tagged: "v1.0.0", Untagged: "v1.0.0-123-a1b2c3d")
@@ -56,12 +44,7 @@ IF(GIT_FOUND AND NOT FORCE_VERSION)
ELSEIF(TAG_LIST_LENGTH EQUAL 3)
# Get the number of commits and latest commit hash
LIST(GET TAG_LIST 1 EXTRA_COMMITS)
# Prefer PR hash from above if present
if(NOT COMMIT_HASH)
list(GET TAG_LIST 2 COMMIT_HASH)
# Mimic github's hash style
string(SUBSTRING "${COMMIT_HASH}" 1 7 COMMIT_HASH)
endif()
LIST(GET TAG_LIST 2 COMMIT_HASH)
list(APPEND PRERELEASE_DATA "${EXTRA_COMMITS}")
list(APPEND BUILD_METADATA "${COMMIT_HASH}")
# Bump the patch version, since a pre-release (as specified by the extra
@@ -74,12 +57,7 @@ IF(GIT_FOUND AND NOT FORCE_VERSION)
# Get the pre-release stage, number of commits, and latest commit hash
LIST(GET TAG_LIST 1 VERSION_STAGE)
LIST(GET TAG_LIST 2 EXTRA_COMMITS)
# Prefer PR hash from above if present
if(NOT COMMIT_HASH)
list(GET TAG_LIST 3 COMMIT_HASH)
# Mimic github's hash style
string(SUBSTRING "${COMMIT_HASH}" 1 7 COMMIT_HASH)
endif()
LIST(GET TAG_LIST 3 COMMIT_HASH)
list(APPEND PRERELEASE_DATA "${VERSION_STAGE}")
list(APPEND PRERELEASE_DATA "${EXTRA_COMMITS}")
list(APPEND BUILD_METADATA "${COMMIT_HASH}")

View File

@@ -35,11 +35,7 @@ SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "
" PARENT_SCOPE)
IF(WIN64)
if(IS_ARM64)
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-${WIN_PLATFORM}-arm64")
else()
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-${WIN_PLATFORM}-win64")
endif()
SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-${WIN_PLATFORM}-win64")
SET(CPACK_INSTALL_FIX "$PROGRAMFILES64\\\\${CPACK_PACKAGE_INSTALL_DIRECTORY}\\\\")
SET(CPACK_NSIS_DEFINES "
${CPACK_NSIS_DEFINES}
@@ -53,15 +49,6 @@ SET(CPACK_NSIS_DEFINES "${CPACK_NSIS_DEFINES}" PARENT_SCOPE)
SET(CPACK_PACKAGE_ICON "${CPACK_PACKAGE_ICON}" PARENT_SCOPE)
SET(CPACK_NSIS_MUI_ICON "${CPACK_NSIS_MUI_ICON}" PARENT_SCOPE)
# Disable cpack's strip for historic reasons
set(CPACK_STRIP_FILES_ORIG "${CPACK_STRIP_FILES}" PARENT_SCOPE)
set(CPACK_STRIP_FILES FALSE PARENT_SCOPE)
if(CPACK_DEBUG)
# CMake 3.19+
set(CPACK_NSIS_EXECUTABLE_PRE_ARGUMENTS "-V4")
endif()
# Windows resource compilers
CONFIGURE_FILE("lmms.rc.in" "${CMAKE_BINARY_DIR}/lmms.rc")
CONFIGURE_FILE("zynaddsubfx.rc.in" "${CMAKE_BINARY_DIR}/plugins/ZynAddSubFx/zynaddsubfx.rc")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -96,6 +96,24 @@
</bbtrack>
</track>
</trackcontainer>
<track type="6" muted="0" name="Automation track" solo="0">
<automationtrack/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
</track>
<mixer visible="1" width="561" height="332" x="10" y="314" maximized="0" minimized="0">
<mixerchannel num="0" muted="0" volume="1" name="Master" soloed="0">
<fxchain numofeffects="0" enabled="0"/>

View File

@@ -214,6 +214,24 @@
</bbtrack>
</track>
</trackcontainer>
<track type="6" muted="0" name="Automation track" solo="0">
<automationtrack/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
</track>
<mixer visible="1" width="561" height="332" x="10" y="314" maximized="0" minimized="0">
<mixerchannel num="0" muted="0" volume="1" name="Master" soloed="0">
<fxchain numofeffects="0" enabled="0"/>

View File

@@ -113,6 +113,24 @@
</bbtrack>
</track>
</trackcontainer>
<track type="6" muted="0" name="Automation track" solo="0">
<automationtrack/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
</track>
<mixer visible="1" width="561" height="332" x="10" y="314" maximized="0" minimized="0">
<mixerchannel num="0" muted="0" volume="1" name="Master" soloed="0">
<fxchain numofeffects="0" enabled="0"/>

View File

@@ -4,6 +4,19 @@
<head timesig_denominator="4" bpm="140" masterpitch="0" mastervol="100" timesig_numerator="4"/>
<song>
<trackcontainer visible="1" width="600" height="300" type="song" x="6" y="5" maximized="0" minimized="0"/>
<track type="6" muted="0" name="Automation track" solo="0">
<automationtrack/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
</track>
<mixer visible="1" width="561" height="332" x="5" y="310" maximized="0" minimized="0">
<mixerchannel num="0" muted="0" volume="1" name="Master" soloed="0">
<fxchain numofeffects="0" enabled="0"/>

View File

@@ -282,6 +282,24 @@
</bbtrack>
</track>
</trackcontainer>
<track type="6" muted="0" name="Automation track" solo="0">
<automationtrack/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
</track>
<mixer visible="1" width="561" height="332" x="10" y="314" maximized="0" minimized="0">
<mixerchannel num="0" muted="0" volume="1" name="Master" soloed="0">
<fxchain numofeffects="0" enabled="0"/>

View File

@@ -52,6 +52,24 @@
<automationtrack/>
</track>
</trackcontainer>
<track muted="0" type="6" name="Automation track" solo="0">
<automationtrack/>
<automationpattern tens="1" mute="0" prog="0" name="Numerator" pos="0" len="192">
<object id="4975896"/>
</automationpattern>
<automationpattern tens="1" mute="0" prog="0" name="Denominator" pos="0" len="192">
<object id="6613237"/>
</automationpattern>
<automationpattern tens="1" mute="0" prog="0" name="Tempo" pos="0" len="192">
<object id="6054005"/>
</automationpattern>
<automationpattern tens="1" mute="0" prog="0" name="Master volume" pos="0" len="192">
<object id="1345820"/>
</automationpattern>
<automationpattern tens="1" mute="0" prog="0" name="Master pitch" pos="0" len="192">
<object id="5865711"/>
</automationpattern>
</track>
<mixer width="543" x="5" y="310" maximized="0" height="335" visible="1" minimized="0">
<mixerchannel num="0" muted="0" volume="1" name="Master" soloed="0">
<fxchain numofeffects="0" enabled="0"/>

View File

@@ -50,6 +50,23 @@
<bbtco usestyle="1" muted="0" name="Beat/Baseline 0" pos="0" len="1536" color="4282417407"/>
</track>
</trackcontainer>
<track type="6" muted="0" name="Automation track" solo="0">
<automationtrack/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192">
<time pos="0" value="140"/>
</automationpattern>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192">
<time pos="0" value="100"/>
</automationpattern>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192">
<time pos="0" value="0"/>
</automationpattern>
<automationpattern prog="0" mute="0" name="Numerator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Denominator" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Tempo" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master volume" pos="0" tens="1" len="192"/>
<automationpattern prog="0" mute="0" name="Master pitch" pos="0" tens="1" len="192"/>
</track>
<mixer visible="1" width="647" height="332" x="9" y="441" maximized="0" minimized="0">
<mixerchannel num="0" muted="0" volume="1" name="Master" soloed="0">
<fxchain numofeffects="0" enabled="0"/>

View File

@@ -1,3 +1,4 @@
INCLUDE(InstallHelpers)
INSTALL_DATA_SUBDIRS("themes" "*.png;*.svg;*.css")
INSTALL_DATA_SUBDIRS("themes" "*.png;*.css")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 859 B

After

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 B

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 B

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 B

After

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 B

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 449 B

After

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 B

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 B

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 B

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 B

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 B

After

Width:  |  Height:  |  Size: 296 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 802 B

After

Width:  |  Height:  |  Size: 900 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 698 B

After

Width:  |  Height:  |  Size: 1000 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 B

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Some files were not shown because too many files have changed in this diff Show More