fb9cba0d01
I was hoping SDL2 would get this functionality eventually, but nope, proper clipboard support is staged for SDL3, which we're not going to see much of for at least a few more months. This will have to do for 98.0. The feature can be disabled at runtime from powder.pref. Implementation status: - windows (via winapi): has the most friendly api so of course the implementation is flawless and uses every available optimization >_> - macos (via cocoa): I'm bad at cocoa so this is only as good as absolutely necessary; TODO: on-demand rendering - x11 (via xclip): I am NOT implementing icccm2; TODO: remove reliance on external tools - wayland (via wl-clipboard): oh god wayland oh why, you're almost as bad as x11; TODO: remove reliance on external tools - android: TODO; is there even a point? - emscripten: TODO; the tricky bit is that in a browser we can only get clipboard data when the user is giving it to us, so this will require some JS hackery that I'm not mentally prepared for right now; also I think the supported content types are very limited and you can't just define your own x11 and wayland support are handled by a common backend which delegates clipboard management to xclip-like external programs, such as xclip itself or wl-clipboard, and can load custom command line templates from powder.pref for use with other such programs.
466 lines
12 KiB
Meson
466 lines
12 KiB
Meson
project(
|
|
'the-powder-toy',
|
|
[ 'c', 'cpp' ],
|
|
version: 'the.cake.is.a.lie',
|
|
default_options: [
|
|
'c_std=c99',
|
|
'cpp_std=c++17',
|
|
'cpp_rtti=false',
|
|
'build.c_std=c99', # used by to_array
|
|
'build.cpp_std=c++17', # used by to_array
|
|
'build.cpp_rtti=false', # used by to_array
|
|
],
|
|
meson_version: '>=0.64.0',
|
|
)
|
|
|
|
if get_option('prepare')
|
|
# we're being run by prepare.py in a ghactions workflow only to determine the values of options; exit early
|
|
subdir_done()
|
|
endif
|
|
|
|
fs = import('fs')
|
|
to_array = generator(
|
|
executable('toarray', sources: 'resources/ToArray.cpp', native: true),
|
|
output: [ '@PLAINNAME@.cpp', '@PLAINNAME@.h' ],
|
|
arguments: [ '@OUTPUT0@', '@OUTPUT1@', '@INPUT@', '@EXTRA_ARGS@' ]
|
|
)
|
|
|
|
render_icons_with_inkscape = get_option('render_icons_with_inkscape')
|
|
inkscape = find_program('inkscape', required: render_icons_with_inkscape)
|
|
|
|
c_compiler = meson.get_compiler('c')
|
|
|
|
is_x86 = host_machine.cpu_family() in [ 'x86', 'x86_64' ]
|
|
is_64bit = host_machine.cpu_family() in [ 'aarch64', 'x86_64' ]
|
|
is_msvc = c_compiler.get_id() in [ 'msvc' ]
|
|
|
|
host_arch = host_machine.cpu_family()
|
|
host_platform = host_machine.system()
|
|
# educated guesses follow, PRs welcome
|
|
if c_compiler.get_id() in [ 'msvc' ]
|
|
if host_platform != 'windows'
|
|
error('this seems fishy')
|
|
endif
|
|
host_libc = 'msvc'
|
|
elif c_compiler.get_id() in [ 'gcc' ] and host_platform == 'windows'
|
|
host_libc = 'mingw'
|
|
if get_option('b_lto')
|
|
warning('mingw does not like static + lto')
|
|
endif
|
|
elif host_platform in [ 'darwin' ]
|
|
host_libc = 'macos'
|
|
elif host_platform in [ 'emscripten' ]
|
|
host_platform = 'emscripten'
|
|
host_libc = 'emscripten'
|
|
elif host_platform in [ 'android' ]
|
|
host_platform = 'android'
|
|
host_libc = 'bionic'
|
|
else
|
|
if host_platform != 'linux'
|
|
# TODO: maybe use 'default' in place of 'linux', or use something other than host_platform where details such as desktop integration are concerned
|
|
warning('host platform is not linux but we will pretend that it is')
|
|
host_platform = 'linux'
|
|
endif
|
|
host_libc = 'gnu'
|
|
endif
|
|
|
|
static_variant = get_option('static')
|
|
if static_variant != 'prebuilt' and host_platform == 'android'
|
|
warning('only prebuilt libs are supported for android')
|
|
static_variant = 'prebuilt'
|
|
endif
|
|
if static_variant == 'system' and host_platform == 'windows'
|
|
warning('no way to find system libs on windows')
|
|
static_variant = 'prebuilt'
|
|
endif
|
|
|
|
is_static = static_variant != 'none'
|
|
is_debug = get_option('optimization') in [ '0', 'g' ]
|
|
app_exe = get_option('app_exe')
|
|
|
|
tpt_libs_static = 'none'
|
|
if static_variant == 'prebuilt'
|
|
tpt_libs_static = 'static'
|
|
endif
|
|
if static_variant == 'none' and host_platform == 'windows'
|
|
tpt_libs_static = 'dynamic'
|
|
endif
|
|
tpt_libs_debug = is_debug ? 'debug' : 'release'
|
|
tpt_libs_variant = '@0@-@1@-@2@-@3@'.format(host_arch, host_platform, host_libc, tpt_libs_static)
|
|
tpt_libs_vtag = get_option('tpt_libs_vtag')
|
|
if tpt_libs_vtag == ''
|
|
tpt_libs_vtag = 'v20231003175140'
|
|
endif
|
|
if tpt_libs_static != 'none'
|
|
if tpt_libs_variant not in [
|
|
'x86_64-linux-gnu-static',
|
|
'x86_64-windows-mingw-static',
|
|
'x86_64-windows-mingw-dynamic',
|
|
'x86_64-windows-msvc-static',
|
|
'x86_64-windows-msvc-dynamic',
|
|
'x86-windows-msvc-static',
|
|
'x86-windows-msvc-dynamic',
|
|
'x86_64-darwin-macos-static',
|
|
'aarch64-darwin-macos-static',
|
|
'x86-android-bionic-static',
|
|
'x86_64-android-bionic-static',
|
|
'arm-android-bionic-static',
|
|
'aarch64-android-bionic-static',
|
|
'wasm32-emscripten-emscripten-static',
|
|
]
|
|
error('no prebuilt @0@ libraries are currently provided'.format(tpt_libs_variant))
|
|
endif
|
|
tpt_libs = subproject('tpt-libs-prebuilt-@0@-@1@-@2@'.format(tpt_libs_variant, tpt_libs_debug, tpt_libs_vtag))
|
|
else
|
|
if get_option('workaround_elusive_bzip2')
|
|
bzip2_lib_name = get_option('workaround_elusive_bzip2_lib_name')
|
|
bzip2_include_name = get_option('workaround_elusive_bzip2_include_name')
|
|
bzip2_lib_dir = get_option('workaround_elusive_bzip2_lib_dir')
|
|
bzip2_include_dir = include_directories(get_option('workaround_elusive_bzip2_include_dir'))
|
|
bzip2_static = get_option('workaround_elusive_bzip2_static')
|
|
meson.override_dependency('bzip2', declare_dependency(
|
|
dependencies: c_compiler.find_library(
|
|
bzip2_lib_name,
|
|
has_headers: bzip2_include_name,
|
|
dirs: bzip2_lib_dir,
|
|
header_include_directories: bzip2_include_dir,
|
|
static: bzip2_static,
|
|
),
|
|
include_directories: bzip2_include_dir,
|
|
))
|
|
endif
|
|
endif
|
|
|
|
x86_sse_level_str = get_option('x86_sse')
|
|
if x86_sse_level_str == 'auto'
|
|
x86_sse_level = 20
|
|
if not is_x86 or not is_64bit or host_platform == 'darwin' or (is_64bit and is_msvc)
|
|
x86_sse_level = 0
|
|
endif
|
|
elif x86_sse_level_str == 'sse3'
|
|
x86_sse_level = 30
|
|
elif x86_sse_level_str == 'sse2'
|
|
x86_sse_level = 20
|
|
elif x86_sse_level_str == 'sse'
|
|
x86_sse_level = 10
|
|
elif x86_sse_level_str == 'none'
|
|
x86_sse_level = 0
|
|
endif
|
|
|
|
lua_variant = get_option('lua')
|
|
if lua_variant == 'auto'
|
|
if host_platform == 'emscripten'
|
|
lua_variant = 'lua5.2'
|
|
else
|
|
lua_variant = 'luajit'
|
|
endif
|
|
endif
|
|
if lua_variant == 'luajit' and host_platform == 'emscripten'
|
|
error('luajit does not work with emscripten')
|
|
endif
|
|
if lua_variant == 'none'
|
|
lua_dep = []
|
|
elif lua_variant == 'lua5.1' or lua_variant == 'lua5.2'
|
|
lua_dep = dependency(lua_variant + '-c++', static: is_static, required: false)
|
|
if not lua_dep.found()
|
|
if not get_option('workaround_noncpp_lua')
|
|
error('your system @0@ is not compatible with C++, configure with -Dworkaround_noncpp_lua=true to disable this error'.format(lua_variant))
|
|
endif
|
|
lua_dep = dependency(lua_variant, static: is_static)
|
|
endif
|
|
elif lua_variant == 'luajit'
|
|
lua_dep = dependency('luajit', static: is_static)
|
|
endif
|
|
|
|
enable_http = get_option('http')
|
|
if host_platform == 'android'
|
|
android_ndk_toolchain_prefix = meson.get_external_property('android_ndk_toolchain_prefix')
|
|
android_platform = meson.get_external_property('android_platform')
|
|
tpt_libs_android_toolchain_prefix = tpt_libs.get_variable('android_toolchain_prefix')
|
|
tpt_libs_android_system_version = tpt_libs.get_variable('android_system_version')
|
|
tpt_libs_android_platform = tpt_libs.get_variable('android_platform')
|
|
if '@0@@1@-'.format(tpt_libs_android_toolchain_prefix, tpt_libs_android_system_version) != android_ndk_toolchain_prefix
|
|
error('tpt-libs android toolchain mismatch')
|
|
endif
|
|
if tpt_libs_android_platform != android_platform
|
|
error('tpt-libs android platform mismatch')
|
|
endif
|
|
endif
|
|
curl_dep = []
|
|
if enable_http and host_platform != 'emscripten'
|
|
curl_dep = dependency('libcurl', static: is_static)
|
|
endif
|
|
|
|
project_link_args = []
|
|
project_c_args = []
|
|
project_cpp_args = []
|
|
|
|
fftw_dep = dependency('fftw3f', static: is_static)
|
|
threads_dep = dependency('threads')
|
|
if host_platform == 'emscripten'
|
|
zlib_dep = []
|
|
png_dep = []
|
|
sdl2_dep = []
|
|
bzip2_dep = []
|
|
project_link_args += [
|
|
'--no-heap-copy',
|
|
'-s', 'WASM=1',
|
|
'-s', 'ALLOW_MEMORY_GROWTH=1',
|
|
'-s', 'FORCE_FILESYSTEM=1',
|
|
'-s', 'EXIT_RUNTIME=0',
|
|
'-s', 'EXPORTED_RUNTIME_METHODS=ccall,cwrap',
|
|
'-s', 'FS_DEBUG',
|
|
'-s', 'MODULARIZE',
|
|
'-s', 'EXPORT_NAME=create_' + app_exe,
|
|
'-Wl,-u,_emscripten_run_callback_on_thread',
|
|
'-lidbfs.js',
|
|
]
|
|
emcc_args = [
|
|
'-s', 'USE_SDL=2',
|
|
'-s', 'USE_BZIP2=1',
|
|
'-s', 'USE_LIBPNG',
|
|
'-s', 'USE_ZLIB=1',
|
|
'-s', 'DISABLE_EXCEPTION_CATCHING=0',
|
|
]
|
|
if is_debug
|
|
project_link_args += [ '--source-map-base=./' ]
|
|
emcc_args += [ '-gsource-map' ]
|
|
endif
|
|
project_link_args += emcc_args
|
|
project_c_args += emcc_args
|
|
project_cpp_args += emcc_args
|
|
else
|
|
zlib_dep = dependency('zlib', static: is_static)
|
|
png_dep = dependency('libpng16', static: is_static)
|
|
sdl2_dep = dependency('sdl2', static: is_static)
|
|
bzip2_dep = dependency('bzip2', static: is_static)
|
|
endif
|
|
json_dep = dependency('jsoncpp', static: is_static)
|
|
|
|
if is_msvc
|
|
if x86_sse_level >= 30
|
|
warning('SSE3 configured to be enabled but unavailable in msvc')
|
|
x86_sse_level = 20
|
|
endif
|
|
if is_64bit and x86_sse_level > 0
|
|
warning('SSE explicitly configured but unavailable in msvc targeting 64-bit machines')
|
|
x86_sse_level = 0
|
|
endif
|
|
args_msvc = [
|
|
'/GS',
|
|
'/D_SCL_SECURE_NO_WARNINGS',
|
|
'/DUNICODE',
|
|
'/D_UNICODE',
|
|
]
|
|
if x86_sse_level >= 20
|
|
args_msvc += [ '/arch:SSE2' ]
|
|
elif x86_sse_level >= 10
|
|
args_msvc += [ '/arch:SSE' ]
|
|
endif
|
|
if not is_debug
|
|
args_msvc += [
|
|
'/Oy-',
|
|
'/fp:fast',
|
|
'/GL',
|
|
]
|
|
project_link_args += [
|
|
'/OPT:REF',
|
|
'/OPT:ICF',
|
|
'/LTCG',
|
|
]
|
|
endif
|
|
project_c_args += args_msvc
|
|
project_cpp_args += args_msvc
|
|
else
|
|
args_ccomp = []
|
|
if host_platform == 'darwin' and x86_sse_level > 0
|
|
message('SSE level explicitly configured but unavailable on macosx')
|
|
x86_sse_level = 0
|
|
endif
|
|
if x86_sse_level >= 30
|
|
args_ccomp += [ '-msse3' ]
|
|
elif x86_sse_level >= 20
|
|
args_ccomp += [ '-msse2' ]
|
|
elif x86_sse_level >= 10
|
|
args_ccomp += [ '-msse' ]
|
|
endif
|
|
if host_platform == 'windows'
|
|
args_ccomp += [
|
|
'-DUNICODE',
|
|
'-D_UNICODE',
|
|
]
|
|
endif
|
|
if not is_debug
|
|
args_ccomp += [
|
|
'-ftree-vectorize',
|
|
'-funsafe-math-optimizations',
|
|
'-ffast-math',
|
|
'-fomit-frame-pointer',
|
|
]
|
|
endif
|
|
if host_platform == 'android'
|
|
if not is_64bit
|
|
args_ccomp += [ '-U_FILE_OFFSET_BITS' ]
|
|
endif
|
|
# android doesn't ship libc++_shared.so, so we might as well link it statically;
|
|
# the alternative would be to grab libc++_shared.so from the NDK and ship it with
|
|
# the app alongside libpowder.so, and possibly add it to SDL's list of libraries to load
|
|
project_link_args += [ '-static-libstdc++' ]
|
|
endif
|
|
project_c_args += args_ccomp + [
|
|
'-Wno-implicit-fallthrough',
|
|
'-Wno-missing-field-initializers',
|
|
'-Wno-unused-result',
|
|
'-Wno-unused-parameter',
|
|
]
|
|
project_cpp_args += args_ccomp + [
|
|
'-Wno-invalid-offsetof',
|
|
'-Wno-unused-result',
|
|
'-Wno-missing-field-initializers',
|
|
'-Wno-unused-parameter',
|
|
]
|
|
endif
|
|
|
|
if host_platform == 'windows'
|
|
args_ccomp_win = [ '-D_WIN32_WINNT=0x0501', '-DNOMINMAX' ]
|
|
windows_mod = import('windows')
|
|
if is_static
|
|
args_ccomp_win += [ '-DCURL_STATICLIB' ]
|
|
if host_arch == 'x86_64'
|
|
args_ccomp_win += [ '-DZLIB_WINAPI' ]
|
|
endif
|
|
else
|
|
foreach input_output_condition : tpt_libs.get_variable('config_dlls')
|
|
dll_input = input_output_condition[0]
|
|
dll_output = input_output_condition[1]
|
|
dll_condition = input_output_condition[2]
|
|
do_copy = false
|
|
if dll_condition == 'all'
|
|
do_copy = true
|
|
elif dll_condition == 'lua=' + lua_variant
|
|
do_copy = true
|
|
endif
|
|
if do_copy
|
|
fs.copyfile(dll_input, dll_output)
|
|
endif
|
|
endforeach
|
|
endif
|
|
project_c_args += args_ccomp_win
|
|
project_cpp_args += args_ccomp_win
|
|
endif
|
|
|
|
project_inc = include_directories([ 'src', 'resources' ])
|
|
|
|
if host_platform == 'windows'
|
|
ident_platform = is_64bit ? 'WIN64' : 'WIN32'
|
|
elif host_platform == 'linux'
|
|
ident_platform = is_64bit ? 'LIN64' : 'LIN32'
|
|
elif host_platform == 'darwin'
|
|
ident_platform = host_arch == 'aarch64' ? 'MACOSARM' : 'MACOSX'
|
|
else
|
|
ident_platform = 'UNKNOWN'
|
|
endif
|
|
|
|
data_files = []
|
|
powder_deps = []
|
|
|
|
subdir('src')
|
|
subdir('resources')
|
|
|
|
powder_files += data_files
|
|
render_files += data_files
|
|
font_files += data_files
|
|
|
|
if host_platform == 'emscripten'
|
|
project_link_args += [
|
|
'-o', app_exe + '.js', # so we get a .wasm, and a .js
|
|
]
|
|
endif
|
|
|
|
if get_option('build_powder')
|
|
powder_deps += [
|
|
threads_dep,
|
|
zlib_dep,
|
|
png_dep,
|
|
sdl2_dep,
|
|
lua_dep,
|
|
curl_dep,
|
|
fftw_dep,
|
|
bzip2_dep,
|
|
json_dep,
|
|
]
|
|
if host_platform == 'android'
|
|
powder_sha = shared_library(
|
|
app_exe,
|
|
sources: powder_files,
|
|
include_directories: project_inc,
|
|
c_args: project_c_args,
|
|
cpp_args: project_cpp_args,
|
|
link_args: project_link_args,
|
|
dependencies: powder_deps,
|
|
)
|
|
subdir('android')
|
|
else
|
|
executable(
|
|
app_exe,
|
|
sources: powder_files,
|
|
include_directories: project_inc,
|
|
c_args: project_c_args,
|
|
cpp_args: project_cpp_args,
|
|
win_subsystem: is_debug ? 'console' : 'windows',
|
|
link_args: project_link_args,
|
|
dependencies: powder_deps,
|
|
install: true,
|
|
)
|
|
endif
|
|
endif
|
|
|
|
if get_option('build_render')
|
|
if host_platform == 'emscripten'
|
|
error('render does not target emscripten')
|
|
endif
|
|
render_deps = [
|
|
threads_dep,
|
|
zlib_dep,
|
|
bzip2_dep,
|
|
json_dep,
|
|
png_dep,
|
|
]
|
|
render_link_args = project_link_args
|
|
if host_platform == 'linux' and is_static
|
|
render_link_args += [ '-static' ]
|
|
endif
|
|
executable(
|
|
'render',
|
|
sources: render_files,
|
|
include_directories: project_inc,
|
|
c_args: project_c_args,
|
|
cpp_args: project_cpp_args,
|
|
link_args: render_link_args,
|
|
dependencies: render_deps,
|
|
)
|
|
endif
|
|
|
|
if get_option('build_font')
|
|
if host_platform == 'emscripten'
|
|
error('font does not target emscripten')
|
|
endif
|
|
font_deps = [
|
|
threads_dep,
|
|
zlib_dep,
|
|
png_dep,
|
|
sdl2_dep,
|
|
bzip2_dep,
|
|
json_dep,
|
|
]
|
|
executable(
|
|
'font',
|
|
sources: font_files,
|
|
include_directories: project_inc,
|
|
c_args: project_c_args,
|
|
cpp_args: project_cpp_args,
|
|
link_args: project_link_args,
|
|
dependencies: font_deps,
|
|
)
|
|
endif
|