summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorPatrick Griffis <tingping@tingping.se>2016-12-13 16:12:03 -0500
committerPatrick Griffis <tingping@tingping.se>2017-06-13 23:54:51 -0400
commit628100c19f5d82747170acdf2917cba8c119ccbf (patch)
tree351a7e9714a1a58390ba349808df5703cef25c3e /src
parent2edf50d4ddc61ce6f73bf02263c9bdd09632c66b (diff)
build: Replace Autotools with Meson
Quick rundown of benefits:

- Much faster:
  - Autotools (with autogen): 22 seconds
  - Meson: 7 seconds
  - Meson (with ccache): 2 seconds

- Simpler:
  - ~1000 lines smaller
  - Single simple language

- Potentially better Windows (Visual Studio) support

What is not done:

- Complete Windows support
- OSX support (easy)

Closes #2013
Closes #1937
Closes #1803
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am17
-rw-r--r--src/common/Makefile.am89
-rw-r--r--src/common/cfgfiles.c20
-rw-r--r--src/common/dbus/Makefile.am35
-rw-r--r--src/common/dbus/meson.build44
-rwxr-xr-xsrc/common/make-te.py55
-rw-r--r--src/common/meson.build116
-rw-r--r--src/common/sysinfo/win32/backend.c19
-rw-r--r--src/common/util.c12
-rw-r--r--src/fe-gtk/Makefile.am64
-rw-r--r--src/fe-gtk/meson.build79
-rw-r--r--src/fe-text/Makefile.am9
-rw-r--r--src/fe-text/fe-text.c2
-rw-r--r--src/fe-text/meson.build7
-rw-r--r--src/htm/Makefile.am15
-rw-r--r--src/htm/htm-mono.csproj144
-rw-r--r--src/htm/meson.build33
-rw-r--r--src/htm/thememan.HTM.resourcesbin0 -> 10228 bytes
-rwxr-xr-x[-rw-r--r--]src/htm/thememan.in0
-rw-r--r--src/meson.build13
20 files changed, 374 insertions, 399 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644
index d870aa0d..00000000
--- a/src/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-EXTRA_DIST = version-script
-
-if DO_TEXT
-text_fe = fe-text
-endif
-
-if DO_GTK
-gtk_fe = fe-gtk
-endif
-
-SUBDIRS = common $(gtk_fe) $(text_fe)
-
-if WITH_TM
-SUBDIRS += htm
-endif
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
deleted file mode 100644
index cdab7925..00000000
--- a/src/common/Makefile.am
+++ /dev/null
@@ -1,89 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-include $(top_srcdir)/m4/clang-analyze.am
-
-noinst_LIBRARIES = libhexchatcommon.a
-
-AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(top_srcdir)
-
-EXTRA_DIST = \
-	cfgfiles.h \
-	chanopt.h \
-	ctcp.h \
-	dcc.h \
-	fe.h \
-	hexchat.h \
-	hexchatc.h \
-	hexchat-plugin.h \
-	history.h \
-	ignore.h \
-	inbound.h \
-	inet.h \
-	make-te.c \
-	marshalers.list \
-	modes.h \
-	network.h \
-	notify.h \
-	outbound.h \
-	plugin.h \
-	plugin-identd.h \
-	plugin-timer.h \
-	proto-irc.h \
-	server.h \
-	servlist.h \
-	ssl.h \
-	ssl.c	\
-	text.h \
-	typedef.h \
-	textenums.h \
-	textevents.h \
-	textevents.in \
-	tree.h \
-	url.h \
-	userlist.h \
-	util.h
-
-if USE_OPENSSL
-ssl_c = ssl.c
-endif
-
-if USE_DBUS
-dbusdir = dbus
-libhexchatcommon_a_LIBADD =				\
-	$(top_builddir)/src/common/dbus/dbus-*.$(OBJEXT)
-endif
-SUBDIRS = $(dbusdir) .
-
-if DO_PLUGIN
-include_HEADERS = hexchat-plugin.h
-endif
-
-noinst_PROGRAMS = make-te
-
-libhexchatcommon_a_SOURCES = cfgfiles.c chanopt.c ctcp.c dcc.c hexchat.c \
-	history.c ignore.c inbound.c marshal.c modes.c network.c notify.c \
-	outbound.c plugin.c plugin-identd.c plugin-timer.c proto-irc.c server.c servlist.c \
-	$(ssl_c) text.c tree.c url.c userlist.c util.c
-libhexchatcommon_a_CFLAGS = $(LIBPROXY_CFLAGS)
-
-textenums.h: textevents.h
-
-textevents.h: $(srcdir)/textevents.in make-te
-	$(AM_V_GEN) ./make-te < $< > $@ 2> textenums.h
-
-marshal.h: $(srcdir)/marshalers.list
-	$(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=_hexchat_marshal --header $< > $@
-
-marshal.c: $(srcdir)/marshalers.list
-	$(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=_hexchat_marshal --body $< > $@
-
-
-if DO_STATIC_ANALYSIS
-analyze_plists = $(libhexchatcommon_a_SOURCES:%.c=%.plist)
-all-local: $(analyze_plists)
-MOSTLYCLEANFILES = $(analyze_plists)
-endif
-
-BUILT_SOURCES = textenums.h textevents.h marshal.c marshal.h
-
-CLEANFILES = $(BUILT_SOURCES)
diff --git a/src/common/cfgfiles.c b/src/common/cfgfiles.c
index 9ca54869..b90f5a69 100644
--- a/src/common/cfgfiles.c
+++ b/src/common/cfgfiles.c
@@ -291,8 +291,8 @@ cfg_get_int (char *cfg, char *var)
 char *xdir = NULL;	/* utf-8 encoding */
 
 #ifdef WIN32
-#include <Windows.h>
-#include <ShlObj.h>
+#include <windows.h>
+#include <shlobj.h>
 #endif
 
 char *
@@ -552,7 +552,7 @@ const struct prefs vars[] =
 	{"stamp_text", P_OFFINT (hex_stamp_text), TYPE_BOOL},
 	{"stamp_text_format", P_OFFSET (hex_stamp_text_format), TYPE_STR},
 
-	{"text_autocopy_color", P_OFFINT (hex_text_autocopy_color), TYPE_BOOL},	
+	{"text_autocopy_color", P_OFFINT (hex_text_autocopy_color), TYPE_BOOL},
 	{"text_autocopy_stamp", P_OFFINT (hex_text_autocopy_stamp), TYPE_BOOL},
 	{"text_autocopy_text", P_OFFINT (hex_text_autocopy_text), TYPE_BOOL},
 	{"text_background", P_OFFSET (hex_text_background), TYPE_STR},
@@ -635,7 +635,7 @@ get_default_language (void)
 	if (!locale)
 		locale = g_getenv ("LANG") ? g_getenv ("LANG") : "en";
 
-	/* we might end up with something like "en_US.UTF-8".  We will try to 
+	/* we might end up with something like "en_US.UTF-8".  We will try to
 	 * search for "en_US"; if it fails we search for "en".
 	 */
 	lang = g_strdup (locale);
@@ -735,7 +735,7 @@ load_default_config(void)
 	memset (&prefs, 0, sizeof (struct hexchatprefs));
 
 	/* put in default values, anything left out is automatically zero */
-	
+
 	/* BOOLEANS */
 	prefs.hex_away_show_once = 1;
 	prefs.hex_away_track = 1;
@@ -918,7 +918,7 @@ make_config_dirs (void)
 
 	if (g_mkdir_with_parents (get_xdir (), 0700) != 0)
 		return -1;
-	
+
 	buf = g_build_filename (get_xdir (), "addons", NULL);
 	if (g_mkdir (buf, 0700) != 0)
 	{
@@ -926,7 +926,7 @@ make_config_dirs (void)
 		return -1;
 	}
 	g_free (buf);
-	
+
 	buf = g_build_filename (get_xdir (), HEXCHAT_SOUND_DIR, NULL);
 	if (g_mkdir (buf, 0700) != 0)
 	{
@@ -983,7 +983,7 @@ load_config (void)
 		i++;
 	}
 	while (vars[i].name);
-	
+
 	g_free (cfg);
 
 	if (prefs.hex_gui_win_height < 138)
@@ -1009,7 +1009,7 @@ save_config (void)
 
 	config = default_file ();
 	new_config = g_strconcat (config, ".new", NULL);
-	
+
 	fh = g_open (new_config, OFLAGS | O_TRUNC | O_WRONLY | O_CREAT, 0600);
 	if (fh == -1)
 	{
@@ -1023,7 +1023,7 @@ save_config (void)
 		g_free (new_config);
 		return 0;
 	}
-		
+
 	i = 0;
 	do
 	{
diff --git a/src/common/dbus/Makefile.am b/src/common/dbus/Makefile.am
deleted file mode 100644
index 869c283e..00000000
--- a/src/common/dbus/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-noinst_LIBRARIES = libhexchatdbus.a
-libhexchatdbus_a_SOURCES =			\
-	dbus-plugin.c				\
-	dbus-plugin.h				\
-	dbus-client.c				\
-	dbus-client.h
-
-EXTRA_DIST =				\
-	remote-object.xml		\
-	example.py			\
-	org.hexchat.service.service.in
-
-BUILT_SOURCES =				\
-	remote-object-glue.h
-
-# Dbus service file
-servicedir = $(DBUS_SERVICES_DIR)
-service_in_files = org.hexchat.service.service.in
-service_DATA = $(service_in_files:.service.in=.service)
-
-CLEANFILES = $(BUILT_SOURCES) $(service_DATA)
-
-AM_CPPFLAGS = -I$(top_srcdir)/src/common $(COMMON_CFLAGS) $(DBUS_CFLAGS)
-
-noinst_PROGRAMS = example
-example_SOURCES = example.c
-example_LDADD = $(DBUS_LIBS) $(GLIB_LIBS)
-
-remote-object-glue.h: remote-object.xml
-	$(AM_V_GEN) $(LIBTOOL) --mode=execute $(DBUS_BINDING_TOOL) --prefix=remote_object --mode=glib-server --output=$@ $<
-
-# Rule to make the service file with bindir expanded
-$(service_DATA): $(service_in_files) Makefile
-	@sed -e "s|\@bindir\@|$(bindir)|" $< > $@
-
diff --git a/src/common/dbus/meson.build b/src/common/dbus/meson.build
new file mode 100644
index 00000000..56443377
--- /dev/null
+++ b/src/common/dbus/meson.build
@@ -0,0 +1,44 @@
+dbus_deps = [
+  dependency('dbus-glib-1')
+]
+
+dbus_sources = [
+  'dbus-plugin.c',
+  'dbus-client.c'
+]
+
+dbus_includes = [
+ include_directories('..'),
+ config_h_include
+]
+
+dbus_service_dir = join_paths(get_option('datadir'), 'dbus-1/services')
+
+dbus_conf = configuration_data()
+dbus_conf.set('bindir', join_paths(get_option('prefix'), get_option('bindir')))
+configure_file(
+  input: 'org.hexchat.service.service.in',
+  output: 'org.hexchat.service.service',
+  configuration: dbus_conf,
+  install: true,
+  install_dir: dbus_service_dir
+)
+
+dbus_binding_tool = find_program('dbus-binding-tool')
+dbus_remote_object = custom_target('remote-object-glue',
+  input: 'remote-object.xml',
+  output: 'remote-object-glue.h',
+  command: [dbus_binding_tool, '--prefix=remote_object', '--mode=glib-server',
+            '--output=@OUTPUT@', '@INPUT@']
+)
+
+hexchat_dbus = static_library('hexchatdbus',
+  sources: [dbus_remote_object, marshal] + dbus_sources,
+  dependencies: common_deps + dbus_deps,
+  include_directories: dbus_includes,
+  pic: true
+)
+
+hexchat_dbus_dep = declare_dependency(
+  link_with: hexchat_dbus
+)
diff --git a/src/common/make-te.py b/src/common/make-te.py
new file mode 100755
index 00000000..a1da5643
--- /dev/null
+++ b/src/common/make-te.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python3
+
+import sys
+
+inf = open(sys.argv[1])
+eventf = open(sys.argv[2], 'w')
+enumsf = open(sys.argv[3], 'w')
+
+enumsf.write(\
+'''
+/* this file is auto generated, edit textevents.in instead! */
+
+enum
+{
+''')
+
+eventf.write(\
+'''
+/* this file is auto generated, edit textevents.in instead! */
+
+const struct text_event te[] = {
+''')
+
+try:
+	while True:
+		name = inf.readline().strip()
+		event_enum = inf.readline().strip()
+		event_help = inf.readline().strip()
+		event_str = inf.readline().strip()
+		args = inf.readline().strip()
+		translate = True
+
+		if args[0] == 'n':
+			args = int(args[1]) | 128
+			translate = False
+		else:
+			args = int(args)
+
+		if translate:
+			event_str = 'N_("%s")' %event_str
+		else:
+			event_str = '"%s"' %event_str
+
+		enumsf.write('\t%s,\n' %event_enum)
+		eventf.write('\n{"%s", %s, %u,\n%s},\n' %(
+			name, event_help, args, event_str,
+		))
+
+		inf.readline() # whitespace
+except IndexError:
+    pass
+
+enumsf.write('\tNUM_XP\n};\n')
+eventf.write('};\n')
+
diff --git a/src/common/meson.build b/src/common/meson.build
new file mode 100644
index 00000000..ef59ffc3
--- /dev/null
+++ b/src/common/meson.build
@@ -0,0 +1,116 @@
+common_sources = [
+  'cfgfiles.c',
+  'chanopt.c',
+  'ctcp.c',
+  'dcc.c',
+  'hexchat.c',
+  'history.c',
+  'ignore.c',
+  'inbound.c',
+  'modes.c',
+  'network.c',
+  'notify.c',
+  'outbound.c',
+  'plugin.c',
+  'plugin-identd.c',
+  'plugin-timer.c',
+  'proto-irc.c',
+  'server.c',
+  'servlist.c',
+	'text.c',
+  'tree.c',
+  'url.c',
+  'userlist.c',
+  'util.c'
+]
+
+common_deps = [
+  libgio_dep,
+]
+
+common_includes = [
+  config_h_include,
+  include_directories('.')
+]
+
+common_cflags = [
+  '-DHAVE_CONFIG_H',
+]
+
+if host_machine.system() == 'windows'
+  common_deps += [
+    cc.find_library('ws2_32'), # winsock
+    cc.find_library('winmm'), # playsound
+    cc.find_library('wbemuuid'), # sysinfo
+  ]
+
+  common_sources += 'sysinfo/win32/backend.c'
+  common_includes += include_directories('sysinfo')
+endif
+
+marshal = gnome.genmarshal('marshal',
+  sources: 'marshalers.list',
+  prefix: '_hexchat_marshal',
+  internal: true
+)
+
+make_te = find_program('make-te.py')
+
+textevents = custom_target('textevents',
+  input: 'textevents.in',
+  output: ['textevents.h', 'textenums.h'],
+  command: [make_te, '@INPUT@', '@OUTPUT0@', '@OUTPUT1@']
+)
+
+# TODO:
+#   LOOKUPD
+#   SIGACTION
+#   HAVE_GTK_MAC
+
+if get_option('with-ssl')
+  common_sources += 'ssl.c'
+  common_deps += libssl_dep
+endif
+
+if get_option('with-libproxy')
+  common_deps += dependency('libproxy-1.0')
+endif
+
+if get_option('with-libcanberra')
+  common_deps += dependency('libcanberra', version: '>= 0.22')
+endif
+
+if get_option('with-dbus')
+  subdir('dbus')
+  common_deps += hexchat_dbus_dep
+  common_includes += include_directories('dbus')
+endif
+
+if get_option('with-plugin')
+  common_deps += libgmodule_dep
+  common_cflags += '-DHEXCHATLIBDIR="@0@"'.format(join_paths(get_option('prefix'),
+                                                  get_option('libdir'),
+                                                  'hexchat/plugins'))
+
+  install_headers('hexchat-plugin.h')
+endif
+
+hexchat_common = static_library('hexchatcommon',
+  sources: [textevents] + marshal + common_sources,
+  include_directories: config_h_include,
+  dependencies: common_deps,
+  c_args: common_cflags,
+  pic: true
+)
+
+hexchat_common_dep = declare_dependency(
+  link_with: hexchat_common,
+  include_directories: common_includes,
+  compile_args: common_cflags,
+  dependencies: libgio_dep,
+)
+
+hexchat_plugin_dep = declare_dependency(
+  include_directories: common_includes,
+  compile_args: common_cflags,
+)
diff --git a/src/common/sysinfo/win32/backend.c b/src/common/sysinfo/win32/backend.c
index c4e686a7..64e9405a 100644
--- a/src/common/sysinfo/win32/backend.c
+++ b/src/common/sysinfo/win32/backend.c
@@ -21,6 +21,7 @@
  */
 
 #include <stdio.h>
+#include <wchar.h>
 #include <windows.h>
 #include <wbemidl.h>
 
@@ -41,17 +42,17 @@ typedef enum
 	QUERY_WMI_HDD,
 } QueryWmiType;
 
-char *query_wmi (QueryWmiType mode);
-char *read_os_name (IWbemClassObject *object);
-char *read_cpu_info (IWbemClassObject *object);
-char *read_vga_name (IWbemClassObject *object);
+static char *query_wmi (QueryWmiType mode);
+static char *read_os_name (IWbemClassObject *object);
+static char *read_cpu_info (IWbemClassObject *object);
+static char *read_vga_name (IWbemClassObject *object);
 
-guint64 hdd_capacity;
-guint64 hdd_free_space;
-char *read_hdd_info (IWbemClassObject *object);
+static guint64 hdd_capacity;
+static guint64 hdd_free_space;
+static char *read_hdd_info (IWbemClassObject *object);
 
-char *bstr_to_utf8 (BSTR bstr);
-guint64 variant_to_uint64 (VARIANT *variant);
+static char *bstr_to_utf8 (BSTR bstr);
+static guint64 variant_to_uint64 (VARIANT *variant);
 
 char *
 sysinfo_get_cpu (void)
diff --git a/src/common/util.c b/src/common/util.c
index bf1acb05..8f4c3abe 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -48,7 +48,7 @@
 #include <ctype.h>
 #include "util.h"
 
-#if defined (USING_FREEBSD) || defined (__APPLE__)
+#if defined (__FreeBSD__) || defined (__APPLE__)
 #include <sys/sysctl.h>
 #endif
 
@@ -360,13 +360,13 @@ strip_hidden_attribute (char *src, char *dst)
 	return len;
 }
 
-#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) || defined (__CYGWIN__)
+#if defined (__linux__) || defined (__FreeBSD__) || defined (__APPLE__) || defined (__CYGWIN__)
 
 static void
 get_cpu_info (double *mhz, int *cpus)
 {
 
-#if defined(USING_LINUX) || defined (__CYGWIN__)
+#if defined(__linux__) || defined (__CYGWIN__)
 
 	char buf[256];
 	int fh;
@@ -404,7 +404,7 @@ get_cpu_info (double *mhz, int *cpus)
 		*cpus = 1;
 
 #endif
-#ifdef USING_FREEBSD
+#ifdef __FreeBSD__
 
 	int mib[2], ncpu;
 	u_long freq;
@@ -495,7 +495,7 @@ get_sys_str (int with_cpu)
 char *
 get_sys_str (int with_cpu)
 {
-#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) || defined (__CYGWIN__)
+#if defined (__linux__) || defined (__FreeBSD__) || defined (__APPLE__) || defined (__CYGWIN__)
 	double mhz;
 #endif
 	int cpus = 1;
@@ -507,7 +507,7 @@ get_sys_str (int with_cpu)
 
 	uname (&un);
 
-#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) || defined (__CYGWIN__)
+#if defined (__linux__) || defined (__FreeBSD__) || defined (__APPLE__) || defined (__CYGWIN__)
 	get_cpu_info (&mhz, &cpus);
 	if (mhz && with_cpu)
 	{
diff --git a/src/fe-gtk/Makefile.am b/src/fe-gtk/Makefile.am
deleted file mode 100644
index 269eaa55..00000000
--- a/src/fe-gtk/Makefile.am
+++ /dev/null
@@ -1,64 +0,0 @@
-
-include $(top_srcdir)/m4/clang-analyze.am
-
-localedir = $(datadir)/locale
-
-bin_PROGRAMS = hexchat
-
-AM_CPPFLAGS = $(GUI_CFLAGS) -DLOCALEDIR=\"$(localedir)\"
-
-hexchat_LDADD = $(top_builddir)/src/common/libhexchatcommon.a $(GUI_LIBS)
-
-EXTRA_DIST = \
-	ascii.h banlist.h chanlist.h chanview.h chanview-tabs.c \
-	chanview-tree.c custom-list.h editlist.h fe-gtk.h fkeys.h gtkutil.h joind.h \
-	maingui.h menu.h notifygui.h  notifications palette.h pixmaps.h plugin-notification.h \
-	plugin-tray.h plugingui.c plugingui.h rawlog.h servlistgui.h setup.h sexy-iso-codes.h \
-	sexy-spell-entry.h textgui.h urlgrab.h userlistgui.h xtext.h
-
-BUILT_SOURCES = resources.h resources.c
-
-CLEANFILES = $(BUILT_SOURCES)
-
-if DO_PLUGIN
-plugingui_c = plugingui.c
-endif
-
-if HAVE_ISO_CODES
-iso_codes_c = sexy-iso-codes.c
-endif
-
-if USE_LIBNOTIFY
-notify_c = notifications/notification-libnotify.c
-else
-if HAVE_GTK_MAC
-notify_c = notifications/notification-osx.m
-hexchat_LDFLAGS = -framework Foundation
-else
-notify_c = notifications/notification-dummy.c
-endif
-endif
-
-nodist_hexchat_SOURCES = resources.h resources.c
-hexchat_SOURCES = ascii.c banlist.c chanlist.c chanview.c custom-list.c \
-	dccgui.c editlist.c fe-gtk.c fkeys.c gtkutil.c ignoregui.c joind.c menu.c \
-	maingui.c notifygui.c $(notify_c) palette.c pixmaps.c plugin-tray.c $(plugingui_c) \
-	plugin-notification.c rawlog.c servlistgui.c setup.c $(iso_codes_c) \
-	sexy-spell-entry.c textgui.c urlgrab.c userlistgui.c xtext.c
-hexchat_CPPFLAGS = -I$(top_builddir)/src/common $(AM_CPPFLAGS)
-
-resources_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(top_srcdir)/data --generate-dependencies $(top_srcdir)/data/hexchat.gresource.xml)
-
-resources.h: $(top_srcdir)/data/hexchat.gresource.xml $(resources_files)
-	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(top_srcdir)/data --generate-header --manual-register $<
-
-resources.c: $(top_srcdir)/data/hexchat.gresource.xml $(resources_files)
-	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(top_srcdir)/data --generate-source --manual-register $<
-
-EXTRA_DIST += $(resources_files)
-
-if DO_STATIC_ANALYSIS
-analyze_plists = $(hexchat_SOURCES:%.c=%.plist)
-all-local: $(analyze_plists)
-MOSTLYCLEANFILES = $(analyze_plists)
-endif
diff --git a/src/fe-gtk/meson.build b/src/fe-gtk/meson.build
new file mode 100644
index 00000000..731709b1
--- /dev/null
+++ b/src/fe-gtk/meson.build
@@ -0,0 +1,79 @@
+hexchat_gtk_sources = [
+  'ascii.c',
+  'banlist.c',
+  'chanlist.c',
+  'chanview.c',
+  'custom-list.c',
+  'dccgui.c',
+  'editlist.c',
+  'fe-gtk.c',
+  'fkeys.c',
+  'gtkutil.c',
+  'ignoregui.c',
+  'joind.c',
+  'menu.c',
+  'maingui.c',
+  'notifygui.c',
+  'palette.c',
+  'pixmaps.c',
+  'plugin-tray.c',
+  'plugin-notification.c',
+  'rawlog.c',
+  'servlistgui.c',
+  'setup.c',
+  'sexy-spell-entry.c',
+  'textgui.c',
+  'urlgrab.c',
+  'userlistgui.c',
+  'xtext.c'
+]
+
+hexchat_gtk_deps = [
+  hexchat_common_dep,
+  libgmodule_dep, # used by libsexy
+  dependency('gtk+-2.0', version: '>= 2.24.0')
+]
+
+hexchat_gtk_cflags = [
+  '-fPIE'
+]
+
+hexchat_gtk_ldflags = [
+  '-pie'
+]
+
+if get_option('with-libnotify')
+  hexchat_gtk_sources += 'notifications/notification-libnotify.c'
+  hexchat_gtk_deps += dependency('libnotify')
+elif false # TODO HAVE_GTK_MAC
+else
+  hexchat_gtk_sources += 'notifications/notification-dummy.c'
+endif
+
+iso_codes = dependency('iso-codes', required: false)
+if iso_codes.found()
+  hexchat_gtk_sources += 'sexy-iso-codes.c'
+  iso_codes_prefix = iso_codes.get_pkgconfig_variable('prefix')
+  hexchat_gtk_cflags += '-DISO_CODES_PREFIX="@0@"'.format(iso_codes_prefix)
+  hexchat_gtk_cflags += '-DISO_CODES_LOCALEDIR="@0@"'.format(
+                        join_paths(iso_codes_prefix, 'share/locale'))
+endif
+
+if get_option('with-plugin')
+  hexchat_gtk_sources += 'plugingui.c'
+endif
+
+resources = gnome.compile_resources('resources',
+  '../../data/hexchat.gresource.xml',
+  source_dir: '../../data', # TODO: Fix upstream
+  c_name: 'hexchat',
+  extra_args: ['--manual-register']
+)
+
+executable('hexchat',
+  sources:  resources + hexchat_gtk_sources,
+  dependencies: hexchat_gtk_deps,
+  c_args: hexchat_gtk_cflags,
+  link_args: hexchat_gtk_ldflags,
+  install: true
+)
diff --git a/src/fe-text/Makefile.am b/src/fe-text/Makefile.am
deleted file mode 100644
index 0243e16f..00000000
--- a/src/fe-text/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-localedir = $(datadir)/locale
-
-bin_PROGRAMS = hexchat-text
-
-AM_CPPFLAGS = $(COMMON_CFLAGS) -DLOCALEDIR=\"$(localedir)\"
-
-hexchat_text_LDADD = $(top_builddir)/src/common/libhexchatcommon.a $(COMMON_LIBS)
-hexchat_text_SOURCES = fe-text.c fe-text.h
-
diff --git a/src/fe-text/fe-text.c b/src/fe-text/fe-text.c
index 323cf6dc..3d29533d 100644
--- a/src/fe-text/fe-text.c
+++ b/src/fe-text/fe-text.c
@@ -502,7 +502,7 @@ fe_args (int argc, char *argv[])
 
 	if (arg_show_version)
 	{
-		printf (PACKAGE_TARNAME" "PACKAGE_VERSION"\n");
+		printf (PACKAGE_NAME" "PACKAGE_VERSION"\n");
 		return 0;
 	}
 
diff --git a/src/fe-text/meson.build b/src/fe-text/meson.build
new file mode 100644
index 00000000..705d8852
--- /dev/null
+++ b/src/fe-text/meson.build
@@ -0,0 +1,7 @@
+executable('hexchat-text',
+  sources: [
+    'fe-text.c',
+  ],
+  dependencies: hexchat_common_dep,
+  install: true,
+)
diff --git a/src/htm/Makefile.am b/src/htm/Makefile.am
deleted file mode 100644
index e524bf27..00000000
--- a/src/htm/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-theme_SCRIPTS = thememan.exe thememan
-themedir = $(bindir)
-
-mdtool_verbose = $(mdtool_verbose_$(V))
-mdtool_verbose_ = $(mdtool_verbose_$(AM_DEFAULT_VERBOSITY))
-mdtool_verbose_0 = @echo "  MDTOOL  " $@; $(MDTOOL) build $< > /dev/null;
-mdtool_verbose_1 = $(MDTOOL) --verbose build $<;
-
-thememan.exe: htm-mono.csproj
-	$(mdtool_verbose)
-
-clean-local:
-	rm -f thememan.exe thememan.exe.config thememan.exe.mdb thememan Main.resources
-
-EXTRA_DIST = thememan.in
diff --git a/src/htm/htm-mono.csproj b/src/htm/htm-mono.csproj
deleted file mode 100644
index 7bed3d97..00000000
--- a/src/htm/htm-mono.csproj
+++ /dev/null
@@ -1,144 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <PropertyGroup>

-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

-    <ProductVersion>8.0.30703</ProductVersion>

-    <SchemaVersion>2.0</SchemaVersion>

-    <ProjectGuid>{DE87FFCA-9606-4116-B747-062D88A56A28}</ProjectGuid>

-    <OutputType>WinExe</OutputType>

-    <AppDesignerFolder>Properties</AppDesignerFolder>

-    <RootNamespace>thememan</RootNamespace>

-    <FileAlignment>512</FileAlignment>

-    <IsWebBootstrapper>false</IsWebBootstrapper>

-    <PublishUrl>publish\</PublishUrl>

-    <Install>true</Install>

-    <InstallFrom>Disk</InstallFrom>

-    <UpdateEnabled>false</UpdateEnabled>

-    <UpdateMode>Foreground</UpdateMode>

-    <UpdateInterval>7</UpdateInterval>

-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>

-    <UpdatePeriodically>false</UpdatePeriodically>

-    <UpdateRequired>false</UpdateRequired>

-    <MapFileExtensions>true</MapFileExtensions>

-    <AutorunEnabled>true</AutorunEnabled>

-    <ApplicationRevision>1</ApplicationRevision>

-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>

-    <UseApplicationTrust>false</UseApplicationTrust>

-    <PublishWizardCompleted>true</PublishWizardCompleted>

-    <BootstrapperEnabled>true</BootstrapperEnabled>

-    <AssemblyName>thememan</AssemblyName>

-  </PropertyGroup>

-  <PropertyGroup>

-    <ApplicationIcon>Resources\htm.ico</ApplicationIcon>

-  </PropertyGroup>

-  <PropertyGroup>

-    <ManifestCertificateThumbprint>25412E3EF25458D894050F8209E4D9DCCDF432D7</ManifestCertificateThumbprint>

-  </PropertyGroup>

-  <PropertyGroup>

-    <ManifestKeyFile>htm_TemporaryKey.pfx</ManifestKeyFile>

-  </PropertyGroup>

-  <PropertyGroup>

-    <GenerateManifests>false</GenerateManifests>

-  </PropertyGroup>

-  <PropertyGroup>

-    <SignManifests>false</SignManifests>

-  </PropertyGroup>

-  <PropertyGroup>

-    <TargetZone>LocalIntranet</TargetZone>

-  </PropertyGroup>

-  <PropertyGroup />

-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

-    <DebugSymbols>True</DebugSymbols>

-    <DebugType>full</DebugType>

-    <Optimize>False</Optimize>

-    <OutputPath>.</OutputPath>

-    <WarningLevel>4</WarningLevel>

-  </PropertyGroup>

-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

-    <DebugType>none</DebugType>

-    <Optimize>True</Optimize>

-    <OutputPath>.</OutputPath>

-    <WarningLevel>4</WarningLevel>

-  </PropertyGroup>

-  <ItemGroup>

-    <Reference Include="System" />

-    <Reference Include="System.Core" />

-    <Reference Include="System.Xml.Linq" />

-    <Reference Include="System.Data.DataSetExtensions" />

-    <Reference Include="Microsoft.CSharp" />

-    <Reference Include="System.Data" />

-    <Reference Include="System.Drawing" />

-    <Reference Include="System.Windows.Forms" />

-    <Reference Include="System.Xml" />

-    <Reference Include="WindowsBase" />

-  </ItemGroup>

-  <ItemGroup>

-    <Compile Include="Main.cs">

-      <SubType>Form</SubType>

-    </Compile>

-    <Compile Include="Main.Designer.cs">

-      <DependentUpon>Main.cs</DependentUpon>

-    </Compile>

-    <Compile Include="Program.cs" />

-    <Compile Include="Properties\AssemblyInfo.cs" />

-    <EmbeddedResource Include="Main.resx">

-      <DependentUpon>Main.cs</DependentUpon>

-    </EmbeddedResource>

-    <EmbeddedResource Include="Properties\Resources.resx">

-      <Generator>ResXFileCodeGenerator</Generator>

-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>

-      <SubType>Designer</SubType>

-    </EmbeddedResource>

-    <Compile Include="Properties\Resources.Designer.cs">

-      <AutoGen>True</AutoGen>

-      <DependentUpon>Resources.resx</DependentUpon>

-      <DesignTime>True</DesignTime>

-    </Compile>

-    <None Include="app.config">

-      <SubType>Designer</SubType>

-    </None>

-    <None Include="Properties\Settings.settings">

-      <Generator>SettingsSingleFileGenerator</Generator>

-      <LastGenOutput>Settings.Designer.cs</LastGenOutput>

-    </None>

-    <Compile Include="Properties\Settings.Designer.cs">

-      <AutoGen>True</AutoGen>

-      <DependentUpon>Settings.settings</DependentUpon>

-      <DesignTimeSharedInput>True</DesignTimeSharedInput>

-    </Compile>

-  </ItemGroup>

-  <ItemGroup>

-    <BootstrapperPackage Include=".NETFramework,Version=v4.0">

-      <Visible>False</Visible>

-      <ProductName>Microsoft .NET Framework 4 Full Profile %28x86 and x64%29</ProductName>

-      <Install>true</Install>

-    </BootstrapperPackage>

-    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">

-      <Visible>False</Visible>

-      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>

-      <Install>false</Install>

-    </BootstrapperPackage>

-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">

-      <Visible>False</Visible>

-      <ProductName>.NET Framework 3.5 SP1</ProductName>

-      <Install>false</Install>

-    </BootstrapperPackage>

-    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">

-      <Visible>False</Visible>

-      <ProductName>Windows Installer 3.1</ProductName>

-      <Install>true</Install>

-    </BootstrapperPackage>

-  </ItemGroup>

-  <ItemGroup>

-    <Content Include="Resources\htm.ico" />

-  </ItemGroup>

-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

-       Other similar extension points exist, see Microsoft.Common.targets.

-  <Target Name="BeforeBuild">

-  </Target>

-  <Target Name="AfterBuild">

-  </Target>

-  -->

-</Project>
\ No newline at end of file
diff --git a/src/htm/meson.build b/src/htm/meson.build
new file mode 100644
index 00000000..8fa93b03
--- /dev/null
+++ b/src/htm/meson.build
@@ -0,0 +1,33 @@
+add_languages('cs')
+
+executable('thememan',
+  sources: [
+    'Program.cs',
+    'Main.cs',
+    'Main.Designer.cs',
+  ],
+  resources: [
+    # 'Main.resx', # FIXME: Allow setting resource id
+    'thememan.HTM.resources',
+  ],
+  cs_args: [
+    '-r:WindowsBase',
+    '-r:System.Data',
+    '-r:System.Drawing',
+    '-r:System.Windows.Forms',
+    '-win32icon:' + meson.current_source_dir() + '/Resources/htm.ico'
+  ],
+  install: true,
+)
+
+thememan_conf = configuration_data()
+thememan_conf.set('exec_prefix', get_option('prefix'))
+thememan_conf.set('bindir', join_paths(get_option('prefix'), get_option('bindir')))
+
+configure_file(
+  input: 'thememan.in',
+  output: 'thememan',
+  configuration: thememan_conf,
+  install: true,
+  install_dir: get_option('bindir'),
+)
diff --git a/src/htm/thememan.HTM.resources b/src/htm/thememan.HTM.resources
new file mode 100644
index 00000000..39374ac0
--- /dev/null
+++ b/src/htm/thememan.HTM.resources
Binary files differdiff --git a/src/htm/thememan.in b/src/htm/thememan.in
index f6f80df6..f6f80df6 100644..100755
--- a/src/htm/thememan.in
+++ b/src/htm/thememan.in
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 00000000..ff2c8871
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,13 @@
+subdir('common')
+
+if get_option('with-gtk')
+  subdir('fe-gtk')
+endif
+
+if get_option('with-text')
+  subdir('fe-text')
+endif
+
+if get_option('with-theme-manager')
+  subdir('htm')
+endif