From 33b654b9dd91cd9af8391b340ccef077c7dd7e04 Mon Sep 17 00:00:00 2001
From: Andrea Shepard <andrea@special-circumstanc.es>
Date: Mon, 9 Dec 2019 18:10:55 +0000
Subject: [PATCH] Support --gprof build flag

---
 SConstruct          | 19 +++++++++++++++++++
 examples/SConscript |  8 +++++++-
 src/SConscript      | 25 +++++++++++++++++++++----
 3 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/SConstruct b/SConstruct
index 8aa8c816..b2fb3638 100644
--- a/SConstruct
+++ b/SConstruct
@@ -73,6 +73,12 @@ AddOption('--coverage',
           action='store_true',
           help='Build with coverage instrumentation')
 
+AddOption('--gprof',
+          dest='gprof',
+          default=False,
+          action="store_true",
+          help='Build with profiling instrumentation for gprof')
+
 AddOption('--in-place',
           dest='in_place',
           default=False,
@@ -128,6 +134,19 @@ if GetOption('coverage'):
     else:
         env.ParseConfig('llvm-config --ldflags')
 
+if GetOption('gprof'):
+    if env['CC'] == 'gcc' and env['CXX'] == 'g++':
+        env.Append(CFLAGS=['-pg', '-fprofile-arcs'],
+                   CXXFLAGS=['-pg', '-fprofile-arcs'],
+		   LDFLAGS=['-pg', '-fprofile-arcs'],
+                   LINKFLAGS=['-pg', '-fprofile-arcs'])
+        env.Append(LIBS=['gcov'])
+        env['GPROF'] = 1
+    else:
+        print("Can only use gprof with gcc")
+        Exit(1)
+        
+
 dbg = env.Clone(VARIANT='debug')
 if env['CC'] == 'cl':
     dbg.Append(CCFLAGS=['/Z7'])
diff --git a/examples/SConscript b/examples/SConscript
index 8504b4bb..28c5734d 100644
--- a/examples/SConscript
+++ b/examples/SConscript
@@ -3,7 +3,13 @@ from __future__ import absolute_import, division, print_function
 Import('env')
 
 example = env.Clone()
-example.Append(LIBS="hammer", LIBPATH="../src")
+
+if 'GPROF' in env and env['GPROF'] == 1:
+    hammer_lib_name="hammer_pg"
+else:
+    hammer_lib_name="hammer"
+
+example.Append(LIBS=hammer_lib_name, LIBPATH="../src")
 
 dns = example.Program('dns', ['dns.c', 'rr.c', 'dns_common.c'])
 ttuser = example.Program('ttuser', 'ttuser.c')
diff --git a/src/SConscript b/src/SConscript
index 1a920a72..ccb6f5d8 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -99,9 +99,20 @@ if env['PLATFORM'] == 'win32':
     # prevent collision between .lib from dll and .lib for static lib
     static_library_name = 'hammer_s'
 
-libhammer_shared = env.SharedLibrary('hammer', parsers + backends + misc_hammer_parts)
-libhammer_static = env.StaticLibrary(static_library_name, parsers + backends + misc_hammer_parts)
+if 'GPROF' in env and env['GPROF'] == 1:
+    # Disable the shared library (it won't work with gprof) and rename the static one
+    build_shared_library=False
+    static_library_name = 'hammer_pg'
+
+# Markers for later
+libhammer_static = None
+libhammer_shared = None
+
 if build_shared_library:
+    libhammer_shared = env.SharedLibrary('hammer', parsers + backends + misc_hammer_parts)
+libhammer_static = env.StaticLibrary(static_library_name, parsers + backends + misc_hammer_parts)
+
+if libhammer_shared is not None:
     Default(libhammer_shared, libhammer_static)
     env.Install('$libpath', [libhammer_static, libhammer_shared])
 else:
@@ -116,14 +127,20 @@ env.Install('$pkgconfigpath', '../../../libhammer.pc')
 if GetOption('with_tests'):
     testenv = env.Clone()
     testenv.ParseConfig('pkg-config --cflags --libs glib-2.0')
-    testenv.Append(LIBS=['hammer'])
+    if libhammer_shared is not None:
+        testenv.Append(LIBS=['hammer'])
+    else:
+        testenv.Append(LIBS=[static_library_name])
     testenv.Prepend(LIBPATH=['.'])
     ctestexec = testenv.Program('test_suite', ctests + ['test_suite.c'], LINKFLAGS='--coverage' if testenv.GetOption('coverage') else None)
     ctest = Alias('testc', [ctestexec], ''.join(['env LD_LIBRARY_PATH=', os.path.dirname(ctestexec[0].path), ' ', ctestexec[0].path]))
     AlwaysBuild(ctest)
     testruns.append(ctest)
 
-Export('libhammer_static libhammer_shared')
+if libhammer_shared is not None:
+    Export('libhammer_static libhammer_shared')
+else:
+    Export('libhammer_static')
 
 for b in env['bindings']:
     env.SConscript(['bindings/%s/SConscript' % b])
-- 
GitLab