-# Find the libunwind library
+# Search for libunwind and components, both includes and libraries
+#
+# Copyright (C) 2003-2022 The SimGrid Team.
+# This is distributed under the LGPL licence but please contact us for
+# relicensing if you need. This is merely free software, no matter the licence.
#
-# LIBUNWIND_FOUND - True if libunwind was found.
-# LIBUNWIND_LIBRARIES - The libraries needed to use libunwind
-# LIBUNWIND_INCLUDE_DIR - Location of unwind.h and libunwind.h
-
-# This file was downloaded from https://github.com/cmccabe/lksmith/blob/master/cmake_modules/FindLibunwind.cmake
-# Copyright (c) 2011-2012, the Locksmith authors.
-# All rights reserved.
#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
+# Input environment variables:
+# LIBUNWIND_HINT: path to libunwind installation (e.g., /usr)
+# (only needed for non-standard installs)
#
-# Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
+# You can tune the needed components here.
+# TODO: we should take this as a parameter if I knew how to do so.
+
+# SimGrid needs unwind-ptrace on Linux and FreeBSD
+if("${CMAKE_SYSTEM}" MATCHES "Linux|FreeBSD")
+ set(LIBUNWIND_COMPONENTS ${LIBUNWIND_COMPONENTS} unwind-ptrace unwind-generic)
+endif()
+
#
-# Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
+# Output variables:
+# HAVE_LIBUNWIND : if all components were found was found
+# LIBUNWIND_LIBRARIES: List of all libraries to load (-lunwind -lunwind-x86_64 and such)
#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# Other effects:
+# - Calls include_directories() on where libunwind.h lives
+# - Calls link_directories() on where the libs live
-# Modified by the SimGrid team for:
-# - Survive the fact that libunwind cannot be found (setting LIBUNWIND_FOUND correctly)
-# - Also search for the unwind-ptrace component (but survive when it's not here)
+# Of course also need the core lib
+set(LIBUNWIND_COMPONENTS ${LIBUNWIND_COMPONENTS} "unwind")
-set(LIBUNWIND_FOUND "1")
+message(STATUS "Looking for libunwind:")
+# Let's assume we have it, and invalidate if parts are missing
+SET(HAVE_LIBUNWIND 1)
-FIND_PATH(LIBUNWIND_INCLUDE_DIR libunwind.h)
-if(NOT LIBUNWIND_INCLUDE_DIR)
- message(WARNING "failed to find libunwind.h")
- set(LIBUNWIND_FOUND "")
-elseif(NOT EXISTS "${LIBUNWIND_INCLUDE_DIR}/unwind.h")
- message(WARNING "libunwind.h was found, but unwind.h was not found in that directory.")
- set(LIBUNWIND_FOUND "")
- SET(LIBUNWIND_INCLUDE_DIR "")
-endif()
+#
+# Search for the header file
+#
-FIND_LIBRARY(LIBUNWIND_GENERIC_LIBRARY "unwind")
-if (LIBUNWIND_GENERIC_LIBRARY)
- MESSAGE(STATUS "Found libunwind library: ${LIBUNWIND_GENERIC_LIBRARY}")
+find_path(PATH_LIBUNWIND_H "libunwind.h"
+ HINTS
+ $ENV{LIBUNWIND_HINT}
+ $ENV{LD_LIBRARY_PATH}
+ PATH_SUFFIXES include/ GnuWin32/include
+ PATHS /opt /opt/local /opt/csw /sw /usr)
+if(PATH_LIBUNWIND_H)
+ string(REGEX REPLACE "/libunwind.h" "" PATH_LIBUNWIND_H "${PATH_LIBUNWIND_H}")
+ message(" Found libunwind.h in ${PATH_LIBUNWIND_H}")
+ include_directories(${PATH_LIBUNWIND_H})
else()
- set(LIBUNWIND_FOUND "")
- MESSAGE(WARNING "failed to find unwind generic library")
-endif ()
-SET(LIBUNWIND_LIBRARIES ${LIBUNWIND_GENERIC_LIBRARY})
-unset(LIBUNWIND_GENERIC_LIBRARY)
+ message(" NOT FOUND libunwind.h")
+ SET(HAVE_LIBUNWIND 0)
+endif()
+mark_as_advanced(PATH_LIBUNWIND_H)
-FIND_LIBRARY(LIBUNWIND_PTRACE_LIBRARY "unwind-ptrace")
-if (LIBUNWIND_PTRACE_LIBRARY)
- MESSAGE(STATUS "Found libunwind-ptrace library: ${LIBUNWIND_PTRACE_LIBRARY}")
- SET(LIBUNWIND_LIBRARIES ${LIBUNWIND_LIBRARIES} ${LIBUNWIND_PTRACE_LIBRARY})
-else()
- MESSAGE(WARNING "Failed to find unwind-ptrace library. Proceeding anyway.")
-endif ()
-unset(LIBUNWIND_PTRACE_LIBRARY)
+#
+# Search for the library components
+#
-# For some reason, we have to link to two libunwind shared object files:
-# one arch-specific and one not.
-if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
- SET(LIBUNWIND_ARCH "arm")
-elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")
- SET(LIBUNWIND_ARCH "x86_64")
-elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
- SET(LIBUNWIND_ARCH "x86")
-endif()
+foreach(component ${LIBUNWIND_COMPONENTS})
+ find_library(PATH_LIBUNWIND_LIB_${component}
+ NAMES ${component}
+ HINTS
+ $ENV{LIBUNWIND_HINT}
+ $ENV{LD_LIBRARY_PATH}
+ PATH_SUFFIXES lib/ GnuWin32/lib lib/system
+ PATHS /opt /opt/local /opt/csw /sw /usr /usr/lib/)
+ if(PATH_LIBUNWIND_LIB_${component})
+ # message(" ${component} ${PATH_LIBUNWIND_LIB_${component}}")
+ string(REGEX REPLACE "/lib${component}.*[.]${LIB_EXE}$" "" PATH_LIBUNWIND_LIB_${component} "${PATH_LIBUNWIND_LIB_${component}}")
+ message(" Found lib${component}.${LIB_EXE} in ${PATH_LIBUNWIND_LIB_${component}}")
+ link_directories(${PATH_LIBUNWIND_LIB_${component}})
-if (LIBUNWIND_FOUND AND LIBUNWIND_ARCH)
- FIND_LIBRARY(LIBUNWIND_SPECIFIC_LIBRARY "unwind-${LIBUNWIND_ARCH}")
- if (LIBUNWIND_SPECIFIC_LIBRARY)
- MESSAGE(STATUS "Found libunwind-${LIBUNWIND_ARCH} library: ${LIBUNWIND_SPECIFIC_LIBRARY}")
+ if(${component} STREQUAL "unwind" AND APPLE)
+ # Apple forbids to link directly against its libunwind implementation
+ # So let's comply to that stupid restriction and link against the System framework
+ SET(LIBUNWIND_LIBRARIES "${LIBUNWIND_LIBRARIES} -lSystem")
else()
- MESSAGE(FATAL_ERROR "failed to find unwind-${LIBUNWIND_ARCH}")
- set(LIBUNWIND_FOUND "")
- endif ()
- SET(LIBUNWIND_LIBRARIES ${LIBUNWIND_LIBRARIES} ${LIBUNWIND_SPECIFIC_LIBRARY})
- unset(LIBUNWIND_SPECIFIC_LIBRARY)
-endif()
+ SET(LIBUNWIND_LIBRARIES "${LIBUNWIND_LIBRARIES} -l${component}")
+ endif()
-if (LIBUNWIND_FOUND)
- MESSAGE(STATUS "Found all required libunwind components.")
-endif()
+ else()
+ message(" Looking for lib${component}.${LIB_EXE} - not found")
+ SET(HAVE_LIBUNWIND 0)
+ endif()
+ mark_as_advanced(PATH_LIBUNWIND_LIB_${component})
+endforeach()
+unset(component)
+unset(LIBUNWIND_COMPONENTS)
-MARK_AS_ADVANCED(LIBUNWIND_LIBRARIES LIBUNWIND_INCLUDE_DIR)
+#
+# Conclude and cleanup
+#
+if(HAVE_LIBUNWIND)
+ message(STATUS "Dependencies induced by libunwind: ${LIBUNWIND_LIBRARIES}")
+else()
+ message(STATUS "Some libunwind components are missing")
+ set(LIBUNWIND_LIBRARIES "")
+endif()