[DynInst_API:] [PATCH 2/2] Clean up library linkage


Date: Fri, 14 Mar 2014 17:44:47 -0700
From: Josh Stone <jistone@xxxxxxxxxx>
Subject: [DynInst_API:] [PATCH 2/2] Clean up library linkage
- Add -Wl,--no-undefined to gnu link flags, so it's a link-time error if
  any library doesn't declare everything it uses.

- Add a 'target_link_private_libraries' function to set LINK_PRIVATE, so
  dependencies aren't implicitly propagated.  Each library must thus
  explicitly declare its link needs.  This only works for CMake 2.8.7+,
  but falls back gracefully otherwise.

- All libraries are now whittled down to link only against their direct
  dependencies to satisfy used symbols.  Check this with "ldd -r -u".
  The only extras now are libelf in libdynDwarf, because libdwarf
  doesn't always link libelf itself, and libm is always added by g++.
---
 cmake/optimization.cmake      |  2 ++
 cmake/packages.cmake          |  6 +++++-
 cmake/shared.cmake            |  9 +++++++++
 common/CMakeLists.txt         |  6 +-----
 dwarf/CMakeLists.txt          |  4 +++-
 dyninstAPI/CMakeLists.txt     | 18 ++++++++----------
 elf/CMakeLists.txt            |  2 +-
 instructionAPI/CMakeLists.txt |  2 +-
 parseAPI/CMakeLists.txt       | 12 ++++--------
 patchAPI/CMakeLists.txt       |  6 +++---
 proccontrol/CMakeLists.txt    | 10 +++++-----
 stackwalk/CMakeLists.txt      | 14 ++++++++------
 symlite/CMakeLists.txt        |  6 +++++-
 symtabAPI/CMakeLists.txt      |  6 +++---
 14 files changed, 58 insertions(+), 45 deletions(-)

diff --git a/cmake/optimization.cmake b/cmake/optimization.cmake
index f24f17196f39..423f19dada1d 100644
--- a/cmake/optimization.cmake
+++ b/cmake/optimization.cmake
@@ -5,6 +5,8 @@ set (CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
 set (CMAKE_CXX_FLAGS_RELEASE "-O2")
 set (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
 set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
+# Ensure each library is fully linked
+set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
 else (MSVC)
 set (CMAKE_C_FLAGS_DEBUG "/Od /Zi")
 set (CMAKE_C_FLAGS_RELEASE "/O2")
diff --git a/cmake/packages.cmake b/cmake/packages.cmake
index 2f8a4cc022bb..51bedcc0a5dd 100644
--- a/cmake/packages.cmake
+++ b/cmake/packages.cmake
@@ -42,10 +42,14 @@ if (UNIX)
       INSTALL_COMMAND mkdir -p <INSTALL_DIR>/include && mkdir -p <INSTALL_DIR>/lib && install <SOURCE_DIR>/libdwarf/libdwarf.h <INSTALL_DIR>/include && install <SOURCE_DIR>/libdwarf/dwarf.h <INSTALL_DIR>/include && install <BINARY_DIR>/libdwarf.so <INSTALL_DIR>/lib
       )
     add_dependencies(LibDwarf libelf_imp)
-    target_link_libraries(LibDwarf libelf_imp)
+    target_link_private_libraries(LibDwarf libelf_imp)
     #ExternalProject_Get_Property(LibDwarf 
     set(LIBDWARF_INCLUDE_DIR ${CMAKE_BINARY_DIR}/libdwarf/include)
     set(LIBDWARF_LIBRARIES ${CMAKE_BINARY_DIR}/libdwarf/lib/libdwarf.so)
+  else()
+    # Unfortunately, libdwarf doesn't always link to libelf itself.
+    # (e.g. https://bugzilla.redhat.com/show_bug.cgi?id=1061432)
+    set(LIBDWARF_LIBRARIES ${LIBDWARF_LIBRARIES} ${LIBELF_LIBRARIES})
   endif()
 
   add_library(libdwarf_imp SHARED IMPORTED)
diff --git a/cmake/shared.cmake b/cmake/shared.cmake
index a980f05849e8..e1d1aeb6a7ca 100644
--- a/cmake/shared.cmake
+++ b/cmake/shared.cmake
@@ -9,6 +9,15 @@ set (SOVERSION "${DYNINST_MAJOR_VERSION}.${DYNINST_MINOR_VERSION}")
 set (LIBVERSION "${SOVERSION}.${DYNINST_PATCH_VERSION}")
 set (DYNINST_VERSION "${LIBVERSION}")
 
+# Link libraries privately when possible
+function (target_link_private_libraries target)
+  if(${CMAKE_VERSION} VERSION_LESS "2.8.7")
+    target_link_libraries (${target} ${ARGN})
+  else()
+    target_link_libraries (${target} LINK_PRIVATE ${ARGN})
+  endif()
+endfunction ()
+
 #Change to switch between libiberty/libstdc++ demangler
 #set(USE_GNU_DEMANGLER 1)
 
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index b4b314edb947..92c99341b16f 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -108,11 +108,7 @@ FILE (GLOB headers "h/*.h")
 set_target_properties (common common_static PROPERTIES PUBLIC_HEADER "${headers}")
 
 if (${IBERTY_LIBRARY} MATCHES iberty)
-if(${CMAKE_VERSION} VERSION_LESS "2.8")
-target_link_libraries (common ${IBERTY_LIBRARY})
-else()
-target_link_libraries (common LINK_PRIVATE ${IBERTY_LIBRARY})
-endif()
+target_link_private_libraries (common ${IBERTY_LIBRARY})
 endif()
 
 if(PLATFORM MATCHES nt OR PLATFORM MATCHES windows)
diff --git a/dwarf/CMakeLists.txt b/dwarf/CMakeLists.txt
index 400212ba8539..a42bf907fc85 100644
--- a/dwarf/CMakeLists.txt
+++ b/dwarf/CMakeLists.txt
@@ -18,7 +18,9 @@ set (SRC_LIST
 
 add_library (dynDwarf ${SRC_LIST})
 add_library (dynDwarf_static STATIC ${SRC_LIST})
-target_link_libraries (dynDwarf ${LIBDWARF_LIBRARIES})
+target_link_private_libraries (dynDwarf ${LIBDWARF_LIBRARIES})
+target_link_private_libraries (dynDwarf dynElf)
+target_link_private_libraries (dynDwarf common)
 
 FILE (GLOB headers "h/*.h")
 set_target_properties (dynDwarf dynDwarf_static PROPERTIES PUBLIC_HEADER "${headers}")
diff --git a/dyninstAPI/CMakeLists.txt b/dyninstAPI/CMakeLists.txt
index 39fa4c831830..287ee58f94c2 100644
--- a/dyninstAPI/CMakeLists.txt
+++ b/dyninstAPI/CMakeLists.txt
@@ -170,18 +170,16 @@ add_library (dyninstAPI ${SRC_LIST})
 add_library (dyninstAPI_static STATIC ${SRC_LIST})
 
 
-target_link_libraries (dyninstAPI stackwalk)
-target_link_libraries (dyninstAPI pcontrol)
-target_link_libraries (dyninstAPI patchAPI)
-target_link_libraries (dyninstAPI parseAPI)
-target_link_libraries (dyninstAPI symtabAPI)
+target_link_private_libraries (dyninstAPI common)
+target_link_private_libraries (dyninstAPI instructionAPI)
+target_link_private_libraries (dyninstAPI stackwalk)
+target_link_private_libraries (dyninstAPI pcontrol)
+target_link_private_libraries (dyninstAPI patchAPI)
+target_link_private_libraries (dyninstAPI parseAPI)
+target_link_private_libraries (dyninstAPI symtabAPI)
 
 if (UNIX)
-target_link_libraries (dyninstAPI dynElf)
-target_link_libraries (dyninstAPI dynDwarf)
-target_link_libraries (dyninstAPI ${LIBELF_LIBRARIES})
-target_link_libraries (dyninstAPI ${LIBDWARF_LIBRARIES})
-target_link_libraries (dyninstAPI pthread)
+target_link_private_libraries (dyninstAPI pthread)
 endif()
 
 FILE (GLOB headers "h/*.h")
diff --git a/elf/CMakeLists.txt b/elf/CMakeLists.txt
index e9977dcafadb..43ffca73e3ad 100644
--- a/elf/CMakeLists.txt
+++ b/elf/CMakeLists.txt
@@ -25,7 +25,7 @@ add_definitions(-DDYNELF_LIB)
 
 FILE (GLOB headers "h/*.h")
 set_target_properties (dynElf dynElf_static PROPERTIES PUBLIC_HEADER "${headers}")
-target_link_libraries (dynElf ${LIBELF_LIBRARIES})
+target_link_private_libraries (dynElf ${LIBELF_LIBRARIES})
 
 INSTALL (TARGETS dynElf dynElf_static
         EXPORT DyninstTargets
diff --git a/instructionAPI/CMakeLists.txt b/instructionAPI/CMakeLists.txt
index d48299dbb503..4a81231436f1 100644
--- a/instructionAPI/CMakeLists.txt
+++ b/instructionAPI/CMakeLists.txt
@@ -26,7 +26,7 @@ ADD_DEFINITIONS(-DINSTRUCTION_LIB)
 
 add_library (instructionAPI ${SRC_LIST})
 add_library (instructionAPI_static STATIC ${SRC_LIST})
-target_link_libraries (instructionAPI common)
+target_link_private_libraries (instructionAPI common)
 FILE (GLOB headers "h/*.h")
 set_target_properties (instructionAPI instructionAPI_static PROPERTIES PUBLIC_HEADER "${headers}")
 
diff --git a/parseAPI/CMakeLists.txt b/parseAPI/CMakeLists.txt
index b2fda92af364..d164c8e3a288 100644
--- a/parseAPI/CMakeLists.txt
+++ b/parseAPI/CMakeLists.txt
@@ -80,17 +80,13 @@ ADD_DEFINITIONS(-DDATAFLOW_LIB)
 
 add_library (parseAPI ${SRC_LIST})
 add_library (parseAPI_static STATIC ${SRC_LIST})
-target_link_libraries(parseAPI common)
-target_link_libraries(parseAPI instructionAPI)
-
-if (UNIX)
-target_link_libraries(parseAPI ${LIBELF_LIBRARIES})
-endif()
+target_link_private_libraries(parseAPI common)
+target_link_private_libraries(parseAPI instructionAPI)
 
 if (LIGHTWEIGHT_SYMTAB)
-target_link_libraries(parseAPI symLite)
+target_link_private_libraries(parseAPI symLite)
 else()
-target_link_libraries(parseAPI symtabAPI)
+target_link_private_libraries(parseAPI symtabAPI)
 endif()
 
 FILE (GLOB headers "h/*.h")
diff --git a/patchAPI/CMakeLists.txt b/patchAPI/CMakeLists.txt
index 1753674527dd..61450df9e724 100644
--- a/patchAPI/CMakeLists.txt
+++ b/patchAPI/CMakeLists.txt
@@ -28,9 +28,9 @@ ADD_DEFINITIONS(-DPATCHAPI_LIB)
 
 add_library (patchAPI ${SRC_LIST})
 add_library (patchAPI_static STATIC ${SRC_LIST})
-target_link_libraries(patchAPI common)
-target_link_libraries(patchAPI instructionAPI)
-target_link_libraries(patchAPI parseAPI)
+target_link_private_libraries(patchAPI common)
+target_link_private_libraries(patchAPI instructionAPI)
+target_link_private_libraries(patchAPI parseAPI)
 
 FILE (GLOB headers "h/*.h")
 set_target_properties (patchAPI patchAPI_static PROPERTIES PUBLIC_HEADER "${headers}")
diff --git a/proccontrol/CMakeLists.txt b/proccontrol/CMakeLists.txt
index 79515444b2a9..9c2b915dd22a 100644
--- a/proccontrol/CMakeLists.txt
+++ b/proccontrol/CMakeLists.txt
@@ -82,17 +82,17 @@ ADD_DEFINITIONS(-DPROCCONTROL_EXPORTS)
 
 add_library (pcontrol ${SRC_LIST})
 add_library (pcontrol_static STATIC ${SRC_LIST})
-target_link_libraries(pcontrol common)
-target_link_libraries(pcontrol ${CMAKE_DL_LIBS})
+target_link_private_libraries(pcontrol common)
+target_link_private_libraries(pcontrol ${CMAKE_DL_LIBS})
 
 if (UNIX)
-target_link_libraries(pcontrol dynElf)
+target_link_private_libraries(pcontrol pthread)
 endif()
 
 if (LIGHTWEIGHT_SYMTAB)
-target_link_libraries(pcontrol symLite)
+target_link_private_libraries(pcontrol symLite)
 else()
-target_link_libraries(pcontrol symtabAPI)
+target_link_private_libraries(pcontrol symtabAPI)
 endif()
 
 FILE (GLOB headers "h/*.h")
diff --git a/stackwalk/CMakeLists.txt b/stackwalk/CMakeLists.txt
index 751281b85b94..9666f6a6f9d9 100644
--- a/stackwalk/CMakeLists.txt
+++ b/stackwalk/CMakeLists.txt
@@ -83,21 +83,23 @@ ADD_DEFINITIONS(-DSTACKWALKER_EXPORTS)
 add_library (stackwalk ${SRC_LIST})
 add_library (stackwalk_static STATIC ${SRC_LIST})
 
-target_link_libraries (stackwalk pcontrol)
+target_link_private_libraries (stackwalk common)
+target_link_private_libraries (stackwalk instructionAPI)
+target_link_private_libraries (stackwalk pcontrol)
 
 if (UNIX)
-target_link_libraries (stackwalk ${LIBELF_LIBRARIES})
-target_link_libraries (stackwalk ${LIBDWARF_LIBRARIES})
+target_link_private_libraries (stackwalk dynDwarf)
+target_link_private_libraries (stackwalk dynElf)
 endif()
 
 if (LIGHTWEIGHT_SYMTAB)
-target_link_libraries(stackwalk symLite)
+target_link_private_libraries(stackwalk symLite)
 else()
-target_link_libraries(stackwalk symtabAPI)
+target_link_private_libraries(stackwalk symtabAPI)
 endif()
 
 if (SW_ANALYSIS_STEPPER)
-target_link_libraries(stackwalk parseAPI)
+target_link_private_libraries(stackwalk parseAPI)
 endif()
 
 FILE (GLOB headers "h/*.h")
diff --git a/symlite/CMakeLists.txt b/symlite/CMakeLists.txt
index dd45f5d71d30..fbc8421d6ef3 100644
--- a/symlite/CMakeLists.txt
+++ b/symlite/CMakeLists.txt
@@ -18,7 +18,11 @@ add_library (symLite_static STATIC ${SRC_LIST})
 FILE (GLOB headers "h/*.h")
 set_target_properties (symLite symLite_static PROPERTIES PUBLIC_HEADER "${headers}")
 
-target_link_libraries (symLite ${LIBELF_LIBRARIES})
+target_link_private_libraries (symLite common)
+
+if (UNIX)
+target_link_private_libraries (symLite dynElf)
+endif()
 
 INSTALL (TARGETS symLite symLite_static
         EXPORT DyninstTargets
diff --git a/symtabAPI/CMakeLists.txt b/symtabAPI/CMakeLists.txt
index b7a98d7090e4..7feccb8bc008 100644
--- a/symtabAPI/CMakeLists.txt
+++ b/symtabAPI/CMakeLists.txt
@@ -84,14 +84,14 @@ ADD_DEFINITIONS(-DSYMTAB_LIB)
 
 add_library (symtabAPI ${SRC_LIST})
 add_library (symtabAPI_static STATIC  ${SRC_LIST})
-target_link_libraries (symtabAPI common)
+target_link_private_libraries (symtabAPI common)
 
 FILE (GLOB headers "h/*.h")
 set_target_properties (symtabAPI symtabAPI_static PROPERTIES PUBLIC_HEADER "${headers}")
 
 if (UNIX)
-  target_link_libraries (symtabAPI dynElf ${LIBELF_LIBRARIES})
-  target_link_libraries (symtabAPI dynDwarf ${LIBDWARF_LIBRARIES})
+  target_link_private_libraries (symtabAPI dynElf ${LIBELF_LIBRARIES})
+  target_link_private_libraries (symtabAPI dynDwarf ${LIBDWARF_LIBRARIES})
 endif()
 
 INSTALL (TARGETS symtabAPI symtabAPI_static
-- 
1.8.5.3

[← Prev in Thread] Current Thread [Next in Thread→]