project( 'drawterm', 'c', version: '1.0', meson_version: '>=1.1.0', default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'b_ndebug=if-release' ], ) platform = 'posix' au = get_option('audio') ui = get_option('gui') kern_deps = [dependency('threads')] sys = host_machine.system() if sys == 'haiku' add_languages('cpp', native: false, required: true) cpp = meson.get_compiler('cpp') kern_deps += [cpp.find_library('network', required: true), cpp.find_library('be', required: true)] elif sys == 'darwin' au = 'none' add_languages('objc', native: false, required: true) add_project_arguments( '-fobjc-arc', language: 'objc', ) endif cc = meson.get_compiler('c') add_project_arguments( '-Wno-missing-braces', '-Wno-parentheses', '-Wno-sign-compare', '-Wno-unused-parameter', '-Wno-shift-negative-value', '-Wno-implicit-fallthrough', '-Wno-missing-field-initializers', language: ['c', 'cpp'], ) if cc.get_id() == 'clang' add_project_arguments( '-Wno-incompatible-pointer-types-discards-qualifiers', '-Wno-gnu-designator', '-Wno-string-plus-int', language: ['c', 'cpp'], ) else add_project_arguments( '-Wno-discarded-qualifiers', '-Wno-clobbered', language: ['c', 'cpp'], ) endif inc = include_directories( 'include', 'kern', ) if sys.contains('bsd') if sys == 'openbsd' au = 'sndio' else au = 'oss' endif ui = ['x11'] endif if sys == 'windows' audio = static_library( 'audio_win32', sources: [ 'kern/devaudio-win32.c', ], include_directories: inc, ) platform = 'win32' elif sys == 'haiku' media = cpp.find_library('media', required: true) add_project_arguments( '-D_POSIX_C_SOURCE', language: ['c', 'cpp'], ) audio = static_library( 'audio_haiku', sources: [ 'kern/devaudio-haiku.cpp', ], dependencies: [ media, ], include_directories: inc, link_language: 'cpp', ) elif au == 'pipewire' audio = static_library( 'audio_pipewire', sources: [ 'kern/devaudio-pipewire.c', ], dependencies: [ dependency('libpipewire-0.3', required: true), ], include_directories: inc, ) elif au == 'alsa' audio = static_library( 'audio_alsa', sources: [ 'kern/devaudio-alsa.c', ], dependencies: [ dependency('alsa', required: true), ], include_directories: inc, ) elif au == 'sndio' audio = static_library( 'audio_sndio', sources: [ 'kern/devaudio-sndio.c', ], dependencies: [ dependency('sndio', required: true), ], include_directories: inc, ) elif au == 'oss' audio = static_library( 'audio_oss', sources: [ 'kern/devaudio-unix.c', ], dependencies: [ ], include_directories: inc, ) elif au == 'none' audio = static_library( 'audio_none', sources: [ 'kern/devaudio-none.c', ], dependencies: [ ], include_directories: inc, ) endif kern = static_library( 'kern', sources: [ 'kern/alloc.c', 'kern/allocb.c', 'kern/chan.c', 'kern/data.c', 'kern/dev.c', 'kern/devaudio.c', 'kern/devcmd.c', 'kern/devcons.c', 'kern/devdraw.c', 'kern/devenv.c', 'kern/devip.c', 'kern/devkbd.c', 'kern/devmnt.c', 'kern/devmouse.c', 'kern/devpipe.c', 'kern/devroot.c', 'kern/devssl.c', 'kern/devtab.c', 'kern/devtls.c', 'kern/error.c', 'kern/parse.c', 'kern/pgrp.c', 'kern/procinit.c', 'kern/qio.c', 'kern/qlock.c', 'kern/rwlock.c', 'kern/sleep.c', 'kern/stub.c', 'kern/sysfile.c', 'kern/term.c', 'kern/waserror.c', 'kern/devfs-'+platform+'.c', 'kern/devip-'+platform+'.c', 'kern/devlfd-'+platform+'.c', 'kern/'+platform+'.c', ], dependencies: [ kern_deps, ], include_directories: inc, ) guis = {} extra_sources = [] if sys == 'windows' windows = import('windows') guis += {'': static_library( 'gui_win32', sources: [ 'gui-win32/screen.c', ], include_directories: inc, )} extra_sources = [windows.compile_resources('glenda-t.rc', depend_files: ['glenda-t.ico'])] elif sys == 'haiku' guis += {'': static_library( 'gui_haiku', sources: [ 'gui-haiku/screen.cpp', ], include_directories: inc, link_language: 'cpp', )} elif sys == 'darwin' install_data('gui-cocoa/drawterm.app/glenda-t.icns', install_dir: 'Contents/Resources') install_data('gui-cocoa/drawterm.app/Info.plist', install_dir: 'Contents') guis += {'': static_library( 'gui_cocoa', sources: [ 'gui-cocoa/screen.m', ], dependencies: [ dependency('Cocoa', method: 'extraframework'), dependency('Metal', method: 'extraframework'), dependency('QuartzCore', method: 'extraframework'), ], include_directories: inc, link_language: 'objc', )} else if 'wayland' in ui wlc = dependency('wayland-client', required: true) xkb = dependency('xkbcommon', required: true) wlp = dependency('wayland-protocols', required: true) wlrp = dependency('wlr-protocols', required: true) wlscanner = find_program('wayland-scanner', required: true) wlprotodir = wlp.get_variable('', pkgconfig: 'pkgdatadir') wlrdir = wlrp.get_variable('', pkgconfig: 'pkgdatadir') scan_c = [wlscanner, 'private-code', '@INPUT@', '@OUTPUT@'] scan_h = [wlscanner, 'client-header', '@INPUT@', '@OUTPUT@'] proto = [] i = wlprotodir/'stable/xdg-shell/xdg-shell.xml' o = 'xdg-shell-protocol' proto += [ custom_target(output: o+'.c', input: i, command: scan_c), custom_target(output: o+'.h', input: i, command: scan_h), ] i = wlprotodir/'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml' o = 'xdg-decoration-protocol' proto += [ custom_target(output: o+'.c', input: i, command: scan_c), custom_target(output: o+'.h', input: i, command: scan_h), ] i = wlprotodir/'unstable/primary-selection/primary-selection-unstable-v1.xml' o = 'xdg-primary-selection-protocol' proto += [ custom_target(output: o+'.c', input: i, command: scan_c), custom_target(output: o+'.h', input: i, command: scan_h), ] i = wlrdir/'unstable/wlr-virtual-pointer-unstable-v1.xml' o = 'wlr-virtual-pointer' proto += [ custom_target(output: o+'.c', input: i, command: scan_c), custom_target(output: o+'.h', input: i, command: scan_h), ] guis += {'wayland': static_library( 'gui_wayland', sources: [ 'gui-wl/wl-cb.c', 'gui-wl/wl-screen.c', 'gui-wl/wl-util.c', proto, ], dependencies: [ wlc, xkb, ], include_directories: inc, )} endif if 'x11' in ui guis += {'x11': static_library( 'gui_x11', sources: [ 'gui-x11/keysym2ucs-x11.c', 'gui-x11/x11.c', ], dependencies: [ dependency('x11', required: true), ], include_directories: inc, )} endif if 'fbdev' in ui assert(sys == 'linux', 'fbdev ui is only supported on Linux') guis += {'fbdev': static_library( 'gui_fbdev', sources: [ 'gui-fbdev/fbdev.c', ], include_directories: inc, )} endif endif if guis == {} assert(false, 'no GUI variants (use -Dgui=...)') endif auth = static_library( 'auth', sources: [ 'libauth/attr.c', 'libauth/auth_attr.c', 'libauth/auth_proxy.c', 'libauth/auth_rpc.c', ], include_directories: inc, ) authsrv = static_library( 'authsrv', sources: [ 'libauthsrv/_asgetpakkey.c', 'libauthsrv/_asgetresp.c', 'libauthsrv/_asgetticket.c', 'libauthsrv/_asrdresp.c', 'libauthsrv/_asrequest.c', 'libauthsrv/authpak.c', 'libauthsrv/convA2M.c', 'libauthsrv/convM2A.c', 'libauthsrv/convM2PR.c', 'libauthsrv/convM2T.c', 'libauthsrv/convM2TR.c', 'libauthsrv/convPR2M.c', 'libauthsrv/convT2M.c', 'libauthsrv/convTR2M.c', 'libauthsrv/form1.c', 'libauthsrv/nvcsum.c', 'libauthsrv/passtokey.c', 'libauthsrv/readcons.c', 'libauthsrv/readnvram.c', ], include_directories: inc, ) c = static_library( 'libc', sources: [ 'libc/atexit.c', 'libc/charstod.c', 'libc/cleanname.c', 'libc/convD2M.c', 'libc/convM2D.c', 'libc/convM2S.c', 'libc/convS2M.c', 'libc/crypt.c', 'libc/ctime.c', 'libc/dial.c', 'libc/dirfstat.c', 'libc/dirfwstat.c', 'libc/dirmodefmt.c', 'libc/dirstat.c', 'libc/dirwstat.c', 'libc/dofmt.c', 'libc/dorfmt.c', 'libc/encodefmt.c', 'libc/fcallfmt.c', 'libc/fltfmt.c', 'libc/fmt.c', 'libc/fmtfd.c', 'libc/fmtfdflush.c', 'libc/fmtlock.c', 'libc/fmtprint.c', 'libc/fmtquote.c', 'libc/fmtrune.c', 'libc/fmtstr.c', 'libc/fmtvprint.c', 'libc/fprint.c', 'libc/frand.c', 'libc/getenv.c', 'libc/getfields.c', 'libc/lnrand.c', 'libc/lock.c', 'libc/lrand.c', 'libc/mallocz.c', 'libc/nan64.c', 'libc/netmkaddr.c', 'libc/nrand.c', 'libc/nsec.c', 'libc/pow10.c', 'libc/pushssl.c', 'libc/pushtls.c', 'libc/rand.c', 'libc/read9pmsg.c', 'libc/readn.c', 'libc/rune.c', 'libc/runefmtstr.c', 'libc/runeseprint.c', 'libc/runesmprint.c', 'libc/runesnprint.c', 'libc/runesprint.c', 'libc/runestrcat.c', 'libc/runestrchr.c', 'libc/runestrcmp.c', 'libc/runestrcpy.c', 'libc/runestrdup.c', 'libc/runestrecpy.c', 'libc/runestrlen.c', 'libc/runestrncat.c', 'libc/runestrncmp.c', 'libc/runestrncpy.c', 'libc/runestrrchr.c', 'libc/runestrstr.c', 'libc/runetype.c', 'libc/runevseprint.c', 'libc/runevsmprint.c', 'libc/runevsnprint.c', 'libc/seprint.c', 'libc/smprint.c', 'libc/snprint.c', 'libc/sprint.c', 'libc/strecpy.c', 'libc/strtod.c', 'libc/strtoll.c', 'libc/sysfatal.c', 'libc/time.c', 'libc/tokenize.c', 'libc/truerand.c', 'libc/u16.c', 'libc/u32.c', 'libc/u64.c', 'libc/utfecpy.c', 'libc/utflen.c', 'libc/utfnlen.c', 'libc/utfrrune.c', 'libc/utfrune.c', 'libc/utfutf.c', 'libc/vfprint.c', 'libc/vseprint.c', 'libc/vsmprint.c', 'libc/vsnprint.c', ], include_directories: inc, ) draw = static_library( 'draw', sources: [ 'libdraw/alloc.c', 'libdraw/arith.c', 'libdraw/badrect.c', 'libdraw/bytesperline.c', 'libdraw/chan.c', 'libdraw/defont.c', 'libdraw/drawrepl.c', 'libdraw/fmt.c', 'libdraw/icossin.c', 'libdraw/icossin2.c', 'libdraw/rectclip.c', 'libdraw/rgb.c', ], include_directories: inc, ) exportfs = static_library( 'exportfs', sources: [ 'exportfs/exportfs.c', 'exportfs/exportsrv.c', ], include_directories: inc, ) ip = static_library( 'ip', sources: [ 'libip/bo.c', 'libip/classmask.c', 'libip/eipfmt.c', 'libip/ipaux.c', 'libip/parseip.c', ], include_directories: inc, ) memdraw = static_library( 'memdraw', sources: [ 'libmemdraw/alloc.c', 'libmemdraw/arc.c', 'libmemdraw/cload.c', 'libmemdraw/cmap.c', 'libmemdraw/cread.c', 'libmemdraw/defont.c', 'libmemdraw/draw.c', 'libmemdraw/ellipse.c', 'libmemdraw/fillpoly.c', 'libmemdraw/hwdraw.c', 'libmemdraw/line.c', 'libmemdraw/load.c', 'libmemdraw/openmemsubfont.c', 'libmemdraw/poly.c', 'libmemdraw/read.c', 'libmemdraw/string.c', 'libmemdraw/subfont.c', 'libmemdraw/unload.c', 'libmemdraw/write.c', ], include_directories: inc, ) memlayer = static_library( 'memlayer', sources: [ 'libmemlayer/draw.c', 'libmemlayer/lalloc.c', 'libmemlayer/layerop.c', 'libmemlayer/ldelete.c', 'libmemlayer/lhide.c', 'libmemlayer/line.c', 'libmemlayer/load.c', 'libmemlayer/lorigin.c', 'libmemlayer/lsetrefresh.c', 'libmemlayer/ltofront.c', 'libmemlayer/ltorear.c', 'libmemlayer/unload.c', ], include_directories: inc, ) mp = static_library( 'libmp', sources: [ 'libmp/betomp.c', 'libmp/cnfield.c', 'libmp/crt.c', 'libmp/gmfield.c', 'libmp/letomp.c', 'libmp/mpadd.c', 'libmp/mpaux.c', 'libmp/mpcmp.c', 'libmp/mpdigdiv.c', 'libmp/mpdiv.c', 'libmp/mpexp.c', 'libmp/mpextendedgcd.c', 'libmp/mpfactorial.c', 'libmp/mpfield.c', 'libmp/mpfmt.c', 'libmp/mpinvert.c', 'libmp/mpleft.c', 'libmp/mplogic.c', 'libmp/mpmod.c', 'libmp/mpmodop.c', 'libmp/mpmul.c', 'libmp/mpnrand.c', 'libmp/mprand.c', 'libmp/mpright.c', 'libmp/mpsel.c', 'libmp/mpsub.c', 'libmp/mptobe.c', 'libmp/mptober.c', 'libmp/mptoi.c', 'libmp/mptole.c', 'libmp/mptolel.c', 'libmp/mptoui.c', 'libmp/mptouv.c', 'libmp/mptov.c', 'libmp/mpvecadd.c', 'libmp/mpveccmp.c', 'libmp/mpvecdigmuladd.c', 'libmp/mpvecsub.c', 'libmp/mpvectscmp.c', 'libmp/strtomp.c', ], include_directories: inc, ) sec = static_library( 'libsec', sources: [ 'libsec/aes.c', 'libsec/aesCBC.c', 'libsec/aesCFB.c', 'libsec/aesOFB.c', 'libsec/aes_gcm.c', 'libsec/aes_xts.c', 'libsec/aesni.c', 'libsec/blowfish.c', 'libsec/ccpoly.c', 'libsec/chacha.c', 'libsec/chachablock.c', 'libsec/curve25519.c', 'libsec/curve25519_dh.c', 'libsec/decodepem.c', 'libsec/des.c', 'libsec/des3CBC.c', 'libsec/desmodes.c', 'libsec/dh.c', 'libsec/ecc.c', 'libsec/fastrand.c', 'libsec/genrandom.c', 'libsec/hkdf.c', 'libsec/hmac.c', 'libsec/jacobian.c', 'libsec/md5.c', 'libsec/md5block.c', 'libsec/nfastrand.c', 'libsec/pbkdf2.c', 'libsec/poly1305.c', 'libsec/prng.c', 'libsec/rc4.c', 'libsec/readcert.c', 'libsec/rsaalloc.c', 'libsec/rsadecrypt.c', 'libsec/rsaencrypt.c', 'libsec/secp256k1.c', 'libsec/secp256r1.c', 'libsec/secp384r1.c', 'libsec/sha1.c', 'libsec/sha1block.c', 'libsec/sha2_128.c', 'libsec/sha2_64.c', 'libsec/sha2block128.c', 'libsec/sha2block64.c', 'libsec/tlshand.c', 'libsec/tsmemcmp.c', 'libsec/x509.c', ], include_directories: inc, ) math = cc.find_library('m', required: false) common = static_library( 'drawterm', sources: [ 'aan.c', 'cpu.c', 'latin1.c', 'main.c', 'secstore.c', platform + '-factotum.c', 'posix-port/getcallerpc.c', 'posix-port/tas.c', ], include_directories: inc, link_with: [ audio, auth, authsrv, c, draw, exportfs, ip, kern, memdraw, memlayer, mp, sec, ], ) exeprefix = 'drawterm-' + sys foreach ui, libui: guis exename = exeprefix if ui != '' exename += '-' + ui endif exename += '-' + host_machine.cpu() executable( exename, sources: [ 'main.c', ] + extra_sources, dependencies: [ math, ], link_with: [ common, libui, ], include_directories: inc, install: true, ) endforeach