Move libunwind CMake logic into FindLibunwind.cmake
authorMilian Wolff <mail@milianw.de>
Sat, 21 Jan 2017 12:40:21 +0000 (13:40 +0100)
committerMilian Wolff <mail@milianw.de>
Sat, 21 Jan 2017 12:43:23 +0000 (13:43 +0100)
This fixes a build regression when using a clean build folder.

The find script is copied from zbackup, cf.:

https://raw.githubusercontent.com/zbackup/zbackup/master/cmake/FindLibUnwind.cmake

It was slightly adapted to find the symbols required for heaptrack
and not depend on symbols we don't actually need here.

While at it, extract the configuration defines out into its own
libunwind_config.h.

3rdparty/libbacktrace/CMakeLists.txt
CMakeLists.txt
cmake/FindLibunwind.cmake [new file with mode: 0644]
src/track/libheaptrack.cpp
src/util/CMakeLists.txt
src/util/config.h.cmake
src/util/libunwind_config.h.cmake [new file with mode: 0644]

index 1b62c4a..81e23b5 100644 (file)
@@ -151,11 +151,6 @@ check_function_exists (strnlen HAVE_DECL_STRNLEN)
 
 check_function_exists (getexecname HAVE_GETEXECNAME)
 
-find_library(LIBUNWIND_LIBRARY NAMES unwind libunwind REQUIRE)
-
-include (CheckLibraryExists)
-check_library_exists (${LIBUNWIND_LIBRARY} unw_backtrace_skip "" HAVE_UNW_BACKTRACE_SKIP)
-
 include (CheckIncludeFile)
 find_path(DWARF_INCLUDE_DIR dwarf.h
       PATH_SUFFIXES libdwarf)
@@ -168,8 +163,6 @@ configure_file (backtrace-supported.h.in backtrace-supported.h)
 
 configure_file (config.h.in.cmake config.h)
 
-find_path(LIBUNWIND_INCLUDE_DIR libunwind.h)
-
 include_directories (BEFORE
     ${CMAKE_CURRENT_BINARY_DIR}
 )
index 6b323bb..8fb2cf0 100644 (file)
@@ -13,13 +13,14 @@ set(HEAPTRACK_VERSION_PATCH 0)
 set(HEAPTRACK_LIB_VERSION 1.0.0)
 set(HEAPTRACK_LIB_SOVERSION 1)
 
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+
+find_package(Libunwind REQUIRED)
 find_package(Boost 1.41.0 REQUIRED COMPONENTS iostreams program_options)
 find_package(Threads REQUIRED)
 find_package(ZLIB REQUIRED)
 include(FeatureSummary)
 
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-
 option(
   HEAPTRACK_BUILD_GUI
   "Disable this option to skip building the Qt5 / KF5 based GUI for heaptrack."
@@ -41,13 +42,6 @@ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wpedantic")
 
-check_library_exists (${LIBUNWIND_LIBRARY} unw_backtrace "" HAVE_UNW_BACKTRACE)
-if (NOT HAVE_UNW_BACKTRACE)
-    message(FATAL_ERROR "Your libunwind version is apparently too old and does not have the unw_backtrace function.")
-endif()
-
-check_library_exists (${LIBUNWIND_LIBRARY} _ULx86_64_set_cache_size "" HAVE_UNW_SET_CACHE_SIZE)
-
 include (CheckCXXSourceCompiles)
 check_cxx_source_compiles(
     "#include <unordered_map>
diff --git a/cmake/FindLibunwind.cmake b/cmake/FindLibunwind.cmake
new file mode 100644 (file)
index 0000000..a6d8844
--- /dev/null
@@ -0,0 +1,83 @@
+#.rst:
+# FindLibUnwind
+# -----------
+#
+# Find LibUnwind
+#
+# Find LibUnwind headers and library
+#
+# ::
+#
+#   LIBUNWIND_FOUND                     - True if libunwind is found.
+#   LIBUNWIND_INCLUDE_DIRS              - Directory where libunwind headers are located.
+#   LIBUNWIND_LIBRARIES                 - Unwind libraries to link against.
+#   LIBUNWIND_HAS_UNW_GETCONTEXT        - True if unw_getcontext() is found (optional).
+#   LIBUNWIND_HAS_UNW_INIT_LOCAL        - True if unw_init_local() is found (optional).
+#   LIBUNWIND_HAS_UNW_BACKTRACE         - True if unw_backtrace() is found (required).
+#   LIBUNWIND_HAS_UNW_BACKTRACE_SKIP    - True if unw_backtrace_skip() is found (optional).
+#   LIBUNWIND_HAS_UNW_SET_CACHE_SIZE    - True if unw_set_cache_size() is found (optional).
+#   LIBUNWIND_VERSION_STRING            - version number as a string (ex: "5.0.3")
+
+#=============================================================================
+# Copyright 2014 ZBackup contributors
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+
+find_path(LIBUNWIND_INCLUDE_DIR libunwind.h )
+if(NOT EXISTS "${LIBUNWIND_INCLUDE_DIR}/unwind.h")
+  MESSAGE("Found libunwind.h but corresponding unwind.h is absent!")
+  SET(LIBUNWIND_INCLUDE_DIR "")
+endif()
+
+find_library(LIBUNWIND_LIBRARY unwind)
+
+if(LIBUNWIND_INCLUDE_DIR AND EXISTS "${LIBUNWIND_INCLUDE_DIR}/libunwind-common.h")
+  file(STRINGS "${LIBUNWIND_INCLUDE_DIR}/libunwind-common.h" LIBUNWIND_HEADER_CONTENTS REGEX "#define UNW_VERSION_[A-Z]+\t[0-9]*")
+
+  string(REGEX REPLACE ".*#define UNW_VERSION_MAJOR\t([0-9]*).*" "\\1" LIBUNWIND_VERSION_MAJOR "${LIBUNWIND_HEADER_CONTENTS}")
+  string(REGEX REPLACE ".*#define UNW_VERSION_MINOR\t([0-9]*).*" "\\1" LIBUNWIND_VERSION_MINOR "${LIBUNWIND_HEADER_CONTENTS}")
+  string(REGEX REPLACE ".*#define UNW_VERSION_EXTRA\t([0-9]*).*" "\\1" LIBUNWIND_VERSION_EXTRA "${LIBUNWIND_HEADER_CONTENTS}")
+
+  if(LIBUNWIND_VERSION_EXTRA)
+    set(LIBUNWIND_VERSION_STRING "${LIBUNWIND_VERSION_MAJOR}.${LIBUNWIND_VERSION_MINOR}.${LIBUNWIND_VERSION_EXTRA}")
+  else(not LIBUNWIND_VERSION_EXTRA)
+    set(LIBUNWIND_VERSION_STRING "${LIBUNWIND_VERSION_MAJOR}.${LIBUNWIND_VERSION_MINOR}")
+  endif()
+  unset(LIBUNWIND_HEADER_CONTENTS)
+endif()
+
+if (LIBUNWIND_LIBRARY)
+  include (CheckLibraryExists)
+  set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
+  set(CMAKE_REQUIRED_QUIET ${LibUnwind_FIND_QUIETLY})
+  check_library_exists(${LIBUNWIND_LIBRARY} unw_getcontext "" LIBUNWIND_HAS_UNW_GETCONTEXT)
+  check_library_exists(${LIBUNWIND_LIBRARY} unw_init_local "" LIBUNWIND_HAS_UNW_INIT_LOCAL)
+  check_library_exists(${LIBUNWIND_LIBRARY} unw_backtrace "" LIBUNWIND_HAS_UNW_BACKTRACE)
+  check_library_exists (${LIBUNWIND_LIBRARY} unw_backtrace_skip "" LIBUNWIND_HAS_UNW_BACKTRACE_SKIP)
+  # TODO: find the symbol name on 32bit/arm platforms
+  check_library_exists (${LIBUNWIND_LIBRARY} _ULx86_64_set_cache_size "" LIBUNWIND_HAS_UNW_SET_CACHE_SIZE)
+  set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
+endif ()
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibUnwind  REQUIRED_VARS  LIBUNWIND_INCLUDE_DIR
+                                                            LIBUNWIND_LIBRARY
+                                                            LIBUNWIND_HAS_UNW_BACKTRACE
+                                             VERSION_VAR    LIBUNWIND_VERSION_STRING
+                                 )
+
+if (LIBUNWIND_FOUND)
+  set(LIBUNWIND_LIBRARIES ${LIBUNWIND_LIBRARY})
+  set(LIBUNWIND_INCLUDE_DIRS ${LIBUNWIND_INCLUDE_DIR})
+endif ()
+
+mark_as_advanced( LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARY )
index 3ad985e..ba9c03a 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "tracetree.h"
 #include "util/config.h"
+#include "util/libunwind_config.h"
 
 /**
  * uncomment this to get extended debug code for known pointers
@@ -229,7 +230,7 @@ public:
             if (unw_set_caching_policy(unw_local_addr_space, UNW_CACHE_PER_THREAD)) {
                 fprintf(stderr, "WARNING: Failed to enable per-thread libunwind caching.\n");
             }
-            #if HAVE_UNW_SET_CACHE_SIZE
+            #if LIBUNWIND_HAS_UNW_SET_CACHE_SIZE
             if (unw_set_cache_size(unw_local_addr_space, 1024)) {
                 fprintf(stderr, "WARNING: Failed to set libunwind cache size.\n");
             }
index 1a49311..942673d 100644 (file)
@@ -4,4 +4,10 @@ else()
     set(HEAPTRACK_DEBUG_BUILD 0)
 endif()
 
-configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+configure_file(config.h.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/config.h
+)
+
+configure_file(libunwind_config.h.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/libunwind_config.h
+)
index aacfc22..f3497f1 100644 (file)
 #ifndef HEAPTRACK_CONFIG_H
 #define HEAPTRACK_CONFIG_H
 
-#cmakedefine01 HAVE_UNW_SET_CACHE_SIZE
+#cmakedefine01 LIBUNWIND_HAS_UNW_SET_CACHE_SIZE
 
-#cmakedefine01 HAVE_UNW_BACKTRACE
+#cmakedefine01 LIBUNWIND_HAS_UNW_BACKTRACE
 
-#cmakedefine01 HAVE_UNW_BACKTRACE_SKIP
+#cmakedefine01 LIBUNWIND_HAS_UNW_BACKTRACE_SKIP
 
 #define HEAPTRACK_VERSION_STRING "@HEAPTRACK_VERSION_MAJOR@.@HEAPTRACK_VERSION_MINOR@.@HEAPTRACK_VERSION_PATCH@"
 #define HEAPTRACK_VERSION_MAJOR @HEAPTRACK_VERSION_MAJOR@
diff --git a/src/util/libunwind_config.h.cmake b/src/util/libunwind_config.h.cmake
new file mode 100644 (file)
index 0000000..ed0e681
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2017 Milian Wolff <mail@milianw.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LIBUNWIND_CONFIG_H
+#define LIBUNWIND_CONFIG_H
+
+#cmakedefine01 LIBUNWIND_HAS_UNW_SET_CACHE_SIZE
+
+#cmakedefine01 LIBUNWIND_HAS_UNW_BACKTRACE
+
+#cmakedefine01 LIBUNWIND_HAS_UNW_BACKTRACE_SKIP
+
+#endif // LIBUNWIND_CONFIG_H
+