diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..3a70c4e0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf + +[*.[ch]] +indent_size = 2 +indent_style = space +insert_final_newline = true + +[meson.build] +indent_size = 2 +indent_style = space + diff --git a/config.h.meson b/config.h.meson new file mode 100644 index 00000000..2d8c8fb4 --- /dev/null +++ b/config.h.meson @@ -0,0 +1,36 @@ +/* Look for global separate debug info in this path */ +#mesondefine DEBUGDIR + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#mesondefine ENABLE_NLS + +/* GETTEXT package name */ +#mesondefine GETTEXT_PACKAGE + +/* Define if perf supports clockid */ +#mesondefine HAVE_PERF_CLOCKID + +/* Name of package */ +#mesondefine PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#mesondefine PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#mesondefine PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#mesondefine PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#mesondefine PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#mesondefine PACKAGE_URL + +/* Define to the version of this package. */ +#mesondefine PACKAGE_VERSION + +/* Version number of package */ +#mesondefine VERSION diff --git a/daemon/meson.build b/daemon/meson.build new file mode 100644 index 00000000..81f2484a --- /dev/null +++ b/daemon/meson.build @@ -0,0 +1,21 @@ +if get_option('with_sysprofd') == 'bundled' + +sysprofd_sources = [ + 'sysprofd.c', + 'sd-bus-helper.c', + 'sd-bus-helper.h', +] + +# NOTE: This is used in data/meson.build +pkglibexecdir = join_paths(get_option('prefix'), get_option('libexecdir'), 'sysprof') + +sysprofd = executable('sysprofd', + sysprofd_sources, + c_args: exe_c_args, + link_args: exe_link_args, + dependencies: dependency('libsystemd', version: '>=222'), + install: true, + install_dir: pkglibexecdir, +) + +endif diff --git a/data/meson.build b/data/meson.build new file mode 100644 index 00000000..9951945f --- /dev/null +++ b/data/meson.build @@ -0,0 +1,86 @@ +datadir = get_option('datadir') + +install_data('sysprof-mime.xml', + install_dir: join_paths(datadir, 'mime/packages') +) + +install_data('org.gnome.Sysprof2.desktop', + install_dir: join_paths(datadir, 'applications') +) + +install_data('org.gnome.sysprof2.gschema.xml', + install_dir: join_paths(datadir, 'glib-2.0/schemas') +) + + +pkgconf = configuration_data() +pkgconf.set('VERSION', meson.project_version()) +pkgconf.set('API_VERSION', libsysprof_api_version) +pkgconf.set('prefix', get_option('prefix')) + +pkgconfigdir = join_paths(get_option('libdir'), 'pkgconfig') +configure_file( + input: 'sysprof.pc.in', + output: 'sysprof-@0@.pc'.format(libsysprof_api_version), + configuration: pkgconf, + install: true, + install_dir: pkgconfigdir, +) +if get_option('enable_gtk') + configure_file( + input: 'sysprof-ui.pc.in', + output: 'sysprof-ui-@0@.pc'.format(libsysprof_api_version), + configuration: pkgconf, + install: true, + install_dir: pkgconfigdir, + ) + + icon_sizes = ['16x16', '24x24', '32x32', '48x48', '256x256', 'scalable'] + foreach size: icon_sizes + install_subdir('icons/' + size, + install_dir: join_paths(datadir, 'icons/hicolor') + ) + endforeach +endif + +if get_option('with_sysprofd') != 'none' + + sysprofdconf = configuration_data() + sysprofdconf.set('sysprofdprivdir', pkglibexecdir) + + configure_file( + input: 'org.gnome.Sysprof2.service.in', + output: 'org.gnome.Sysprof2.service', + configuration: sysprofdconf, + install: true, + install_dir: join_paths(datadir, 'dbus-1/system-services'), + ) + configure_file( + input: 'org.gnome.Sysprof2.conf.in', + output: 'org.gnome.Sysprof2.conf', + configuration: sysprofdconf, + install: true, + install_dir: join_paths(datadir, 'dbus-1/system.d'), + ) + + systemdunitdir = get_option('systemdunitdir') + if systemdunitdir == '' + systemdunitdir = dependency('systemd').get_pkgconfig_variable('systemdsystemunitdir') + endif + configure_file( + input: 'sysprof2.service.in', + output: 'sysprof2.service', + configuration: sysprofdconf, + install: true, + install_dir: systemdunitdir, + ) + + configure_file( + input: 'org.gnome.sysprof2.policy.in', + output: 'org.gnome.sysprof2.policy', + configuration: sysprofdconf, + install: true, + install_dir: join_paths(datadir, 'polkit-1/actions'), + ) + +endif diff --git a/help/meson.build b/help/meson.build new file mode 100644 index 00000000..74c44709 --- /dev/null +++ b/help/meson.build @@ -0,0 +1,4 @@ +gnome.yelp('sysprof', + ['index.page', 'introduction.page', 'legal.xml', 'profiling.page'], + languages: ['cs', 'de', 'pt_BR', 'sv'], +) diff --git a/lib/meson.build b/lib/meson.build new file mode 100644 index 00000000..f6999549 --- /dev/null +++ b/lib/meson.build @@ -0,0 +1,243 @@ + +# Both the profiler library and the UI library need to share some +# data-structures. Notably, the StackStash. So we build a private +# static library that can be used from both. It adds a little bit +# of overhead in terms of duplicated procedures, but they should +# always be installed in sync, and therefore no big deal. + +libutil_sources = [ + 'util/binfile.c', + 'util/binfile.h', + 'util/demangle.cpp', + 'util/demangle.h', + 'util/elfparser.c', + 'util/elfparser.h', + 'util/pointcache.c', + 'util/pointcache.h', + 'util/stackstash.c', + 'util/stackstash.h', +] + +libutil_deps = [ + dependency('gio-unix-2.0', version: '>=2.44.0') +] + +libutil_includes = [ + # https://github.com/mesonbuild/meson/issues/974 + join_paths(meson.current_source_dir(), 'util'), +] + +libutil = static_library('util', + libutil_sources, + include_directories: include_directories(libutil_includes), + dependencies: libutil_deps, + pic: true, +) + +libutil_dep = declare_dependency( + link_with: libutil, + dependencies: libutil_deps, + include_directories: include_directories(libutil_includes), +) + +# We split up the library code into two libraries. One containing the +# minimum necessary to do profiling on a particular host (that might not +# have GTK+ installed), and the library containing reusable GTK +# components (for IDE integration). + +libsysprof_api_version = '2' + +libsysprof_version_conf = configuration_data() +libsysprof_version = meson.project_version().split('.') +libsysprof_version_conf.set('MAJOR_VERSION', libsysprof_version[0]) +libsysprof_version_conf.set('MINOR_VERSION', libsysprof_version[1]) +libsysprof_version_conf.set('MICRO_VERSION', libsysprof_version[2]) +libsysprof_version_conf.set('VERSION', meson.project_version()) + +configure_file( + input: 'sysprof-version.h.in', + output: 'sysprof-version.h', + configuration: libsysprof_version_conf, + install: true, + install_dir: join_paths(get_option('includedir'), + 'sysprof-' + libsysprof_api_version) +) + +libsysprof_headers = [ + 'sysprof.h', + 'sp-address.h', + 'sp-callgraph-profile.h', + 'sp-capture-condition.h', + 'sp-capture-cursor.h', + 'sp-capture-reader.h', + 'sp-capture-writer.h', + 'sp-capture-types.h', + 'sp-clock.h', + 'sp-elf-symbol-resolver.h', + 'sp-error.h', + 'sp-gjs-source.h', + 'sp-hostinfo-source.h', + 'sp-jitmap-symbol-resolver.h', + 'sp-kernel-symbol.h', + 'sp-kernel-symbol-resolver.h', + 'sp-local-profiler.h', + 'sp-map-lookaside.h', + 'sp-perf-source.h', + 'sp-proc-source.h', + 'sp-profile.h', + 'sp-profiler.h', + 'sp-selection.h', + 'sp-source.h', + 'sp-symbol-resolver.h', +] + +libsysprof_sources = [ + 'sp-address.c', + 'sp-callgraph-profile.c', + 'sp-callgraph-profile-private.h', + 'sp-capture-condition.c', + 'sp-capture-cursor.c', + 'sp-capture-reader.c', + 'sp-capture-writer.c', + 'sp-clock.c', + 'sp-elf-symbol-resolver.c', + 'sp-error.c', + 'sp-gjs-source.c', + 'sp-hostinfo-source.c', + 'sp-jitmap-symbol-resolver.c', + 'sp-kernel-symbol.c', + 'sp-kernel-symbol-resolver.c', + 'sp-line-reader.c', + 'sp-line-reader.h', + 'sp-local-profiler.c', + 'sp-map-lookaside.c', + 'sp-perf-counter.c', + 'sp-perf-counter.h', + 'sp-perf-source.c', + 'sp-platform.c', + 'sp-platform.h', + 'sp-proc-source.c', + 'sp-profile.c', + 'sp-profiler.c', + 'sp-selection.c', + 'sp-source.c', + 'sp-symbol-resolver.c', +] + +cxx = meson.get_compiler('cpp') + +libsysprof_deps = [ + libutil_dep, + cxx.find_library('stdc++'), +] + +version_link_arg = '-Wl,--version-script,' + join_paths(meson.current_source_dir(), 'sysprof.map') +libsysprof_c_args = [] + +if get_option('with_sysprofd') != 'none' + libsysprof_deps += dependency('polkit-gobject-1') + libsysprof_c_args += '-DENABLE_POLKIT' +endif + +libsysprof = shared_library('sysprof-' + libsysprof_api_version, + libsysprof_sources, + dependencies: libsysprof_deps, + c_args: libsysprof_c_args, + link_args: version_link_arg, + link_depends: 'sysprof.map', + install: true, +) + +install_headers(libsysprof_headers, + subdir: 'sysprof-' + libsysprof_api_version, +) + +libsysprof_dep = declare_dependency( + include_directories: include_directories('.'), + link_with: libsysprof, + dependencies: libsysprof_deps, +) + +if get_option('enable_gtk') + # This is our GTK library containing the widgets suitable for viewing + # and manipulating the various profiler API in libsysprof. This is + # meant to be used by IDEs and the sysprof gui. + + libsysprof_ui_headers = [ + 'sp-callgraph-view.h', + 'sp-cell-renderer-percent.h', + 'sp-cpu-visualizer-row.h', + 'sp-empty-state-view.h', + 'sp-failed-state-view.h', + 'sp-line-visualizer-row.h', + 'sp-model-filter.h', + 'sp-multi-paned.h', + 'sp-process-model.h', + 'sp-process-model-item.h', + 'sp-process-model-row.h', + 'sp-profiler-menu-button.h', + 'sp-recording-state-view.h', + 'sp-visualizer-row.h', + 'sp-visualizer-view.h', + 'sp-zoom-manager.h', + 'sysprof-ui.h', + ] + + libsysprof_ui_sources = [ + 'sp-callgraph-view.c', + 'sp-cell-renderer-percent.c', + 'sp-color-cycle.c', + 'sp-color-cycle.h', + 'sp-cpu-visualizer-row.c', + 'sp-empty-state-view.c', + 'sp-failed-state-view.c', + 'sp-line-visualizer-row.c', + 'sp-model-filter.c', + 'sp-multi-paned.c', + 'sp-process-model.c', + 'sp-process-model-item.c', + 'sp-process-model-row.c', + 'sp-profiler-menu-button.c', + 'sp-recording-state-view.c', + 'sp-theme-manager.c', + 'sp-theme-manager.h', + 'sp-visualizer-list.c', + 'sp-visualizer-list.h', + 'sp-visualizer-row.c', + 'sp-visualizer-row-private.h', + 'sp-visualizer-ticks.c', + 'sp-visualizer-ticks.h', + 'sp-visualizer-view.c', + 'sp-zoom-manager.c', + ] + + libsysprof_ui_resources = gnome.compile_resources( + 'sp-ui-resources', 'resources/libsysprof.gresource.xml', + source_dir: 'resources', + c_name: 'sp', + ) + + libsysprof_ui_deps = [ + libsysprof_dep, + dependency('gtk+-3.0', version: '>=3.21.5'), + ] + + libsysprof_ui = shared_library('sysprof-ui-' + libsysprof_api_version, + libsysprof_ui_resources + libsysprof_ui_sources, + dependencies: libsysprof_ui_deps, + link_args: version_link_arg, + link_depends: 'sysprof.map', + install: true, + ) + + install_headers(libsysprof_ui_headers, + subdir: 'sysprof-' + libsysprof_api_version, + ) + + libsysprof_ui_dep = declare_dependency( + dependencies: libsysprof_ui_deps, + link_with: libsysprof_ui, + include_directories: include_directories('.'), + ) + +endif diff --git a/lib/sysprof.map b/lib/sysprof.map new file mode 100644 index 00000000..ccd07a89 --- /dev/null +++ b/lib/sysprof.map @@ -0,0 +1,6 @@ +{ +global: + sp_*; +local: + *; +}; diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..9cbe7d16 --- /dev/null +++ b/meson.build @@ -0,0 +1,122 @@ +project('sysprof', ['c', 'cpp'], + license: ['GPL3+', 'GPL2+'], + version: '3.22.3', + meson_version: '>=0.36.0', + default_options: [ + 'c_std=gnu11', + 'cpp_std=c++03', + 'warning_level=2', + ] +) + +cc = meson.get_compiler('c') +config = configuration_data() + +config.set_quoted('PACKAGE_NAME', 'sysprof') +config.set_quoted('PACKAGE_VERSION', meson.project_version()) +config.set_quoted('PACKAGE_STRING', 'sysprof-' + meson.project_version()) +config.set_quoted('PACKAGE_BUGREPORT', 'https://bugzilla.gnome.org/enter_bug.cgi?product=sysprof') +config.set('PACKAGE_TARNAME', 'PACKAGE_STRING') +config.set('PACKAGE', 'PACKAGE_NAME') +config.set('VERSION', 'PACKAGE_VERSION') +# PACKAGE_URL + +debugdir = get_option('debugdir') +if debugdir == '' + debugdir = join_paths(get_option('prefix'), get_option('libdir'), 'debug') +endif +config.set_quoted('DEBUGDIR', debugdir) + +config.set_quoted('GETTEXT_PACKAGE', 'sysprof') +config.set10('ENABLE_NLS', true) + +has_use_clockid = cc.has_member('struct perf_event_attr', 'use_clockid', prefix: '#include ') +has_clockid = cc.has_member('struct perf_event_attr', 'clockid', prefix: '#include ') +if has_use_clockid and has_clockid + config.set10('HAVE_PERF_CLOCKID', true) +endif + +configure_file( + input: 'config.h.meson', + output: 'config.h', + configuration: config +) + +add_global_arguments([ + '-DHAVE_CONFIG_H', + '-I' + meson.build_root(), # config.h +], language: 'c') + + +c_args_tests = [ + '-Wno-unused-parameter', + '-Wno-missing-field-initializers', +] +foreach arg: c_args_tests + if cc.has_argument(arg) + add_global_arguments(arg, language: 'c') + endif +endforeach + +global_link_args = [] +test_link_args = [ + '-Wl,-z,relro', + '-Wl,-z,now', +] +if not get_option('buildtype').startswith('debug') + + # TODO: Maybe reuse 'b_ndebug' option + add_global_arguments([ + '-DG_DISABLE_CAST_CHECKS', + '-DG_DISABLE_ASSERT', + '-DG_DISABLE_CHECKS', + ], language: 'c') + + test_link_args += [ + '-Wl,-Bsymbolic', + '-fno-plt', + ] + +endif + +foreach arg: test_link_args + if cc.has_argument(arg) + global_link_args += arg + endif +endforeach +add_global_link_arguments( + global_link_args, + language: 'c' +) + +if not cc.links(''' +#include +int main(void) { + atomic_thread_fence(memory_order_acquire); + atomic_thread_fence(memory_order_seq_cst); + return 0; +} +''') + error('Sysprof requires a C compiler with stdatomic support such as GCC 4.9 or newer') +endif + +exe_c_args = [] +exe_link_args = [] +if cc.has_argument('-fPIE') + exe_c_args += '-fPIE' + exe_link_args += '-fpie' +endif + +gnome = import('gnome') + +subdir('lib') +subdir('daemon') +subdir('src') +subdir('tools') +subdir('tests') + +subdir('data') +subdir('help') +subdir('po') + +meson.add_install_script('meson_post_install.sh') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..797b231d --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,11 @@ +option('enable_gtk', type: 'boolean') +option('with_sysprofd', type: 'combo', + choices: ['host', 'bundled', 'none'], + value: 'bundled', +) +option('systemdunitdir', type: 'string', + description: 'Directory for systemd service files' +) +option('debugdir', type: 'string', + description: 'Look for global separate debug info in this path' +) diff --git a/meson_post_install.sh b/meson_post_install.sh new file mode 100755 index 00000000..6fe3c177 --- /dev/null +++ b/meson_post_install.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +if [ -z $MESON_INSTALL_PREFIX ]; then + echo 'This is meant to be ran from Meson only!' + exit 1 +fi + +if [ -z $DESTDIR ]; then + + echo 'Compiling GSchema' + glib-compile-schemas "$MESON_INSTALL_PREFIX/share/glib-2.0/schemas" + echo 'Updating mime database' + update-mime-database "$MESON_INSTALL_PREFIX/share/mime" + + if [ -e "$MESON_INSTALL_PREFIX/bin/sysprof" ]; then + + echo 'Updating icon cache' + gtk-update-icon-cache -qtf "$MESON_INSTALL_PREFIX/share/icons/hicolor" + echo 'Updating desktop database' + update-desktop-database -q "$MESON_INSTALL_PREFIX/share/applications" + + fi + +fi diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 00000000..7d0b74ce --- /dev/null +++ b/po/meson.build @@ -0,0 +1,24 @@ +i18n = import('i18n') + +i18n.gettext('sysprof', + languages: [ + 'cs', + 'de', + 'es', + 'fi', + 'hu', + 'pl', + 'pt', + 'pt_BR', + 'sl', + 'sk', + 'sr', + 'sv' + ], + args: [ + '--from-code=UTF-8', + '--keyword=g_dngettext:2,3', + '--add-comments', + '--msgid-bugs-address=https://bugzilla.gnome.org/enter_bug.cgi?product=sysprof&keywords=I18N+L10N&component=general', + ], +) diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..15cd93f2 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,31 @@ +if get_option('enable_gtk') + +sysprof_sources = [ + 'sysprof.c', + 'sp-application.c', + 'sp-application.h', + 'sp-credits.h', + 'sp-window.c', + 'sp-window.h', + 'sp-window-settings.c', + 'sp-window-settings.h', +] + +sysprof_resources = gnome.compile_resources( + 'sp-resources', 'resources/sysprof.gresource.xml', + source_dir: 'resources', + c_name: 'sysprof', +) + +sysprof = executable('sysprof', + sysprof_resources + sysprof_sources, + dependencies: [ + libsysprof_ui_dep, + cc.find_library('m', required: false), + ], + c_args: exe_c_args, + link_args: exe_link_args, + install: true, +) + +endif diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..a7ada760 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,35 @@ +test_env = [ + 'G_TEST_SRCDIR="@0@"'.format(meson.current_source_dir()), + 'G_TEST_BUILDDIR="@0@"'.format(meson.current_build_dir()), + 'G_DEBUG=gc-friendly', + 'GSETTINGS_BACKEND=memory', + 'MALLOC_CHECK_=2', +] + +test_capture = executable('test-capture', + 'test-capture.c', + dependencies: libsysprof_dep, +) +test('test-capture', test_capture, env: test_env) + +test_capture_cursor = executable('test-capture-cursor', + 'test-capture-cursor.c', + dependencies: libsysprof_dep, +) +test('test-capture-cursor', test_capture_cursor, env: test_env) + +if get_option('enable_gtk') + + test_model_filter = executable('test-model_filter', + 'test-model-filter.c', + dependencies: libsysprof_ui_dep, + ) + test('test-model-filter', test_model_filter, env: test_env) + + test_zoom = executable('test-zoom', + 'test-zoom.c', + dependencies: libsysprof_ui_dep, + ) + test('test-zoom', test_zoom, env: test_env) + +endif diff --git a/tools/meson.build b/tools/meson.build new file mode 100644 index 00000000..f7900461 --- /dev/null +++ b/tools/meson.build @@ -0,0 +1,14 @@ +sysprof_cli = executable('sysprof-cli', + 'sysprof-cli.c', + dependencies: libsysprof_dep, + c_args: exe_c_args, + link_args: exe_link_args, + install: true, +) + +sysprof_dump = executable('sysprof-dump', + 'sysprof-dump.c', + dependencies: libsysprof_dep, + c_args: exe_c_args, + link_args: exe_link_args, +)