perf tools: Separate out GTK codes to libperf-gtk.so
authorNamhyung Kim <namhyung@kernel.org>
Fri, 13 Sep 2013 06:27:43 +0000 (15:27 +0900)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 9 Oct 2013 18:55:25 +0000 (15:55 -0300)
Separate out GTK codes to a shared object called libperf-gtk.so.  This
time only GTK codes are built with -fPIC and libperf remains as is.  Now
run GTK hist and annotation browser using libdl.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1379053663-13706-1-git-send-email-namhyung@kernel.org
[ Fix it up wrt Ingo's tools/perf build speedups ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Makefile.perf
tools/perf/builtin-annotate.c
tools/perf/builtin-report.c
tools/perf/config/Makefile
tools/perf/ui/gtk/annotate.c
tools/perf/ui/gtk/gtk.h
tools/perf/ui/setup.c
tools/perf/ui/ui.h
tools/perf/util/annotate.h
tools/perf/util/hist.h
tools/perf/util/util.h

index a24f6c280b95f968ad78cabce4b91f0d8680ec73..40c39c39ce80d6a73db085966ad42f0dfa8e2177 100644 (file)
@@ -114,6 +114,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
 BUILTIN_OBJS =
 LIB_H =
 LIB_OBJS =
+GTK_OBJS =
 PYRF_OBJS =
 SCRIPT_SH =
 
@@ -490,13 +491,19 @@ ifndef NO_SLANG
 endif
 
 ifndef NO_GTK2
-  LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/util.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
-  LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
+  ALL_PROGRAMS += $(OUTPUT)libperf-gtk.so
+
+  GTK_OBJS += $(OUTPUT)ui/gtk/browser.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/hists.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/setup.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/util.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/helpline.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/progress.o
+  GTK_OBJS += $(OUTPUT)ui/gtk/annotate.o
+
+install-gtk: $(OUTPUT)libperf-gtk.so
+       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'
+       $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)'
 endif
 
 ifndef NO_LIBPERL
@@ -550,6 +557,12 @@ $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
        $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
                $(BUILTIN_OBJS) $(LIBS) -o $@
 
+$(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H)
+       $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $<
+
+$(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS)
+       $(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS)
+
 $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
                '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
@@ -632,6 +645,9 @@ $(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS
 $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
 
+$(OUTPUT)ui/setup.o: ui/setup.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DLIBDIR='"$(libdir_SQ)"' $<
+
 $(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
 
@@ -673,7 +689,8 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
 
 # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
 # we depend the various files onto their directories.
-DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
+DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(GTK_OBJS)
+DIRECTORY_DEPS += $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
 $(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
 # In the second step, we make a rule to actually create these directories
 $(sort $(dir $(DIRECTORY_DEPS))):
@@ -786,7 +803,9 @@ check: $(OUTPUT)common-cmds.h
 
 ### Installation rules
 
-install-bin: all
+install-gtk:
+
+install-bin: all install-gtk
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
        $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
@@ -831,7 +850,8 @@ config-clean:
        @$(MAKE) -C config/feature-checks clean
 
 clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean
-       $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS)
+       $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(GTK_OBJS)
+       $(RM) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS)
        $(RM) $(ALL_PROGRAMS) perf
        $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
        $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
@@ -850,7 +870,7 @@ else
     GIT-HEAD-PHONY =
 endif
 
-.PHONY: all install clean config-clean strip
+.PHONY: all install clean config-clean strip install-gtk
 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
 .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS
 
index 0393d980051642dc57b968a6342259f1782da82e..94f9a8e78117b0dbeeb63e4af1a064b29485071e 100644 (file)
@@ -30,6 +30,7 @@
 #include "util/tool.h"
 #include "arch/common.h"
 
+#include <dlfcn.h>
 #include <linux/bitmap.h>
 
 struct perf_annotate {
@@ -142,8 +143,18 @@ find_next:
 
                if (use_browser == 2) {
                        int ret;
+                       int (*annotate)(struct hist_entry *he,
+                                       struct perf_evsel *evsel,
+                                       struct hist_browser_timer *hbt);
+
+                       annotate = dlsym(perf_gtk_handle,
+                                        "hist_entry__gtk_annotate");
+                       if (annotate == NULL) {
+                               ui__error("GTK browser not found!\n");
+                               return;
+                       }
 
-                       ret = hist_entry__gtk_annotate(he, evsel, NULL);
+                       ret = annotate(he, evsel, NULL);
                        if (!ret || !ann->skip_missing)
                                return;
 
@@ -247,8 +258,17 @@ static int __cmd_annotate(struct perf_annotate *ann)
                goto out_delete;
        }
 
-       if (use_browser == 2)
-               perf_gtk__show_annotations();
+       if (use_browser == 2) {
+               void (*show_annotations)(void);
+
+               show_annotations = dlsym(perf_gtk_handle,
+                                        "perf_gtk__show_annotations");
+               if (show_annotations == NULL) {
+                       ui__error("GTK browser not found!\n");
+                       goto out_delete;
+               }
+               show_annotations();
+       }
 
 out_delete:
        /*
index 06e1abe351dd4cd55cea64cb6c82172e96b80db9..21b5c2f54c2aee8851fd87e23ec8d83a3ae182d3 100644 (file)
@@ -35,6 +35,7 @@
 #include "util/hist.h"
 #include "arch/common.h"
 
+#include <dlfcn.h>
 #include <linux/bitmap.h>
 
 struct perf_report {
@@ -591,8 +592,19 @@ static int __cmd_report(struct perf_report *rep)
                                ret = 0;
 
                } else if (use_browser == 2) {
-                       perf_evlist__gtk_browse_hists(session->evlist, help,
-                                                     NULL, rep->min_percent);
+                       int (*hist_browser)(struct perf_evlist *,
+                                           const char *,
+                                           struct hist_browser_timer *,
+                                           float min_pcnt);
+
+                       hist_browser = dlsym(perf_gtk_handle,
+                                            "perf_evlist__gtk_browse_hists");
+                       if (hist_browser == NULL) {
+                               ui__error("GTK browser not found!\n");
+                               return ret;
+                       }
+                       hist_browser(session->evlist, help, NULL,
+                                    rep->min_percent);
                }
        } else
                perf_evlist__tty_browse_hists(session->evlist, rep, help);
index f5d661f5637dbece29922e784006c6391eb8322d..d9bba8d57c402c95d38e7aa445a04d874d06c1c2 100644 (file)
@@ -377,11 +377,11 @@ ifndef NO_GTK2
     NO_GTK2 := 1
   else
     ifeq ($(feature-gtk2-infobar), 1)
-      CFLAGS += -DHAVE_GTK_INFO_BAR_SUPPORT
+      GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT
     endif
     CFLAGS += -DHAVE_GTK2_SUPPORT
-    CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
-    EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
+    GTK_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
+    GTK_LIBS := $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
   endif
 endif
 
@@ -554,7 +554,12 @@ else
 sysconfdir = $(prefix)/etc
 ETC_PERFCONFIG = etc/perfconfig
 endif
+ifeq ($(IS_X86_64),1)
+lib = lib64
+else
 lib = lib
+endif
+libdir = $(prefix)/$(lib)
 
 # Shell quote (do not use $(call) to accommodate ancient setups);
 ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
@@ -567,6 +572,7 @@ template_dir_SQ = $(subst ','\'',$(template_dir))
 htmldir_SQ = $(subst ','\'',$(htmldir))
 prefix_SQ = $(subst ','\'',$(prefix))
 sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
+libdir_SQ = $(subst ','\'',$(libdir))
 
 ifneq ($(filter /%,$(firstword $(perfexecdir))),)
 perfexec_instdir = $(perfexecdir)
index f538794615dbb7c399371d93bd1b96cef77ea234..9c7ff8d31b274e32d22147664cb622437db514f1 100644 (file)
@@ -154,9 +154,9 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
        return 0;
 }
 
-int symbol__gtk_annotate(struct symbol *sym, struct map *map,
-                        struct perf_evsel *evsel,
-                        struct hist_browser_timer *hbt)
+static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
+                               struct perf_evsel *evsel,
+                               struct hist_browser_timer *hbt)
 {
        GtkWidget *window;
        GtkWidget *notebook;
@@ -226,6 +226,13 @@ int symbol__gtk_annotate(struct symbol *sym, struct map *map,
        return 0;
 }
 
+int hist_entry__gtk_annotate(struct hist_entry *he,
+                            struct perf_evsel *evsel,
+                            struct hist_browser_timer *hbt)
+{
+       return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
+}
+
 void perf_gtk__show_annotations(void)
 {
        GtkWidget *window;
index a72acbc565e0527a2e9b8c5976b8b3213fb89673..8576cf194872da1065e90eb63a40482ebb63479e 100644 (file)
@@ -20,6 +20,9 @@ struct perf_gtk_context {
        guint statbar_ctx_id;
 };
 
+int perf_gtk__init(void);
+void perf_gtk__exit(bool wait_for_ok);
+
 extern struct perf_gtk_context *pgctx;
 
 static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx)
@@ -48,4 +51,17 @@ static inline GtkWidget *perf_gtk__setup_info_bar(void)
 }
 #endif
 
+struct perf_evsel;
+struct perf_evlist;
+struct hist_entry;
+struct hist_browser_timer;
+
+int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
+                                 struct hist_browser_timer *hbt,
+                                 float min_pcnt);
+int hist_entry__gtk_annotate(struct hist_entry *he,
+                            struct perf_evsel *evsel,
+                            struct hist_browser_timer *hbt);
+void perf_gtk__show_annotations(void);
+
 #endif /* _PERF_GTK_H_ */
index 47d9a571f261da9c65e36aa82f8dbdb70a838acc..5df5140a9f29e466dd055b8873711e722875f646 100644 (file)
@@ -1,10 +1,64 @@
 #include <pthread.h>
+#include <dlfcn.h>
 
 #include "../util/cache.h"
 #include "../util/debug.h"
 #include "../util/hist.h"
 
 pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
+void *perf_gtk_handle;
+
+#ifdef HAVE_GTK2_SUPPORT
+static int setup_gtk_browser(void)
+{
+       int (*perf_ui_init)(void);
+
+       if (perf_gtk_handle)
+               return 0;
+
+       perf_gtk_handle = dlopen(PERF_GTK_DSO, RTLD_LAZY);
+       if (perf_gtk_handle == NULL) {
+               char buf[PATH_MAX];
+               scnprintf(buf, sizeof(buf), "%s/%s", LIBDIR, PERF_GTK_DSO);
+               perf_gtk_handle = dlopen(buf, RTLD_LAZY);
+       }
+       if (perf_gtk_handle == NULL)
+               return -1;
+
+       perf_ui_init = dlsym(perf_gtk_handle, "perf_gtk__init");
+       if (perf_ui_init == NULL)
+               goto out_close;
+
+       if (perf_ui_init() == 0)
+               return 0;
+
+out_close:
+       dlclose(perf_gtk_handle);
+       return -1;
+}
+
+static void exit_gtk_browser(bool wait_for_ok)
+{
+       void (*perf_ui_exit)(bool);
+
+       if (perf_gtk_handle == NULL)
+               return;
+
+       perf_ui_exit = dlsym(perf_gtk_handle, "perf_gtk__exit");
+       if (perf_ui_exit == NULL)
+               goto out_close;
+
+       perf_ui_exit(wait_for_ok);
+
+out_close:
+       dlclose(perf_gtk_handle);
+
+       perf_gtk_handle = NULL;
+}
+#else
+static inline int setup_gtk_browser(void) { return -1; }
+static inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {}
+#endif
 
 void setup_browser(bool fallback_to_pager)
 {
@@ -17,8 +71,11 @@ void setup_browser(bool fallback_to_pager)
 
        switch (use_browser) {
        case 2:
-               if (perf_gtk__init() == 0)
+               if (setup_gtk_browser() == 0)
                        break;
+               printf("GTK browser requested but could not find %s\n",
+                      PERF_GTK_DSO);
+               sleep(1);
                /* fall through */
        case 1:
                use_browser = 1;
@@ -39,7 +96,7 @@ void exit_browser(bool wait_for_ok)
 {
        switch (use_browser) {
        case 2:
-               perf_gtk__exit(wait_for_ok);
+               exit_gtk_browser(wait_for_ok);
                break;
 
        case 1:
index 1349d142a005d44d0c82be25a7f61730926cfd59..ab88383f8be85d5278dfaba5b6b6b07b11a6b2d2 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/compiler.h>
 
 extern pthread_mutex_t ui__lock;
+extern void *perf_gtk_handle;
 
 extern int use_browser;
 
@@ -23,17 +24,6 @@ static inline int ui__init(void)
 static inline void ui__exit(bool wait_for_ok __maybe_unused) {}
 #endif
 
-#ifdef HAVE_GTK2_SUPPORT
-int perf_gtk__init(void);
-void perf_gtk__exit(bool wait_for_ok);
-#else
-static inline int perf_gtk__init(void)
-{
-       return -1;
-}
-static inline void perf_gtk__exit(bool wait_for_ok __maybe_unused) {}
-#endif
-
 void ui__refresh_dimensions(bool force);
 
 #endif /* _PERF_UI_H_ */
index f0699e9bcc6f963fd0ad52ccec86dd29f750ec0f..834b7b57b7884f7b833291caa6bcaad2a1eff1d1 100644 (file)
@@ -165,30 +165,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
 }
 #endif
 
-#ifdef HAVE_GTK2_SUPPORT
-int symbol__gtk_annotate(struct symbol *sym, struct map *map,
-                        struct perf_evsel *evsel,
-                        struct hist_browser_timer *hbt);
-
-static inline int hist_entry__gtk_annotate(struct hist_entry *he,
-                                          struct perf_evsel *evsel,
-                                          struct hist_browser_timer *hbt)
-{
-       return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
-}
-
-void perf_gtk__show_annotations(void);
-#else
-static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
-                               struct perf_evsel *evsel __maybe_unused,
-                               struct hist_browser_timer *hbt __maybe_unused)
-{
-       return 0;
-}
-
-static inline void perf_gtk__show_annotations(void) {}
-#endif
-
 extern const char      *disassembler_style;
 
 #endif /* __PERF_ANNOTATE_H */
index ed4f90ebe0d516c0bbd4494bd1386610701b4c69..20b175808cd372c031f3e2cf2cc3ad0d49d8df70 100644 (file)
@@ -228,20 +228,5 @@ static inline int script_browse(const char *script_opt __maybe_unused)
 #define K_SWITCH_INPUT_DATA -3000
 #endif
 
-#ifdef HAVE_GTK2_SUPPORT
-int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
-                                 struct hist_browser_timer *hbt __maybe_unused,
-                                 float min_pcnt);
-#else
-static inline
-int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
-                                 const char *help __maybe_unused,
-                                 struct hist_browser_timer *hbt __maybe_unused,
-                                 float min_pcnt __maybe_unused)
-{
-       return 0;
-}
-#endif
-
 unsigned int hists__sort_list_width(struct hists *self);
 #endif /* __PERF_HIST_H */
index c29ecaabf4610ace8ac1d5fa90f8060b4b4488dd..7fd840bf6b62473e4d9a2803314cede538efa0be 100644 (file)
@@ -128,6 +128,8 @@ void put_tracing_file(char *file);
 #endif
 #endif
 
+#define PERF_GTK_DSO  "libperf-gtk.so"
+
 /* General helper functions */
 extern void usage(const char *err) NORETURN;
 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));