Преглед на файлове

CTKCore - Add library options and implement a more robust detection of libbfd

Two advanced CMake options associated with CTKCore library are now exposed to
the developer:
 CTK_LIB_Core_WITH_BFD_STATIC
 CTK_LIB_Core_WITH_BFD_SHARED

Enabling one of these options will build CTKCore library with BFD support,
in other words, that means the CTKCore will include the class ctkBinaryFileDescriptor.h
(See CTK/Libs/Core/ctkBinaryFileDescriptor.h)

More detailed regarding Binary File Descriptor are available here:
http://en.wikipedia.org/wiki/Binary_File_Descriptor_library

If CTK_LIB_Core_WITH_BFD_STATIC is enabled, the static version of bfd library
will be searched (libbfd.a) so that CTKCore can be linked against it.
 If not found or if the library header are not installed or if the
associated "try_compile" failed to pass, a CMake Warning will be displayed.
For example:

//------------------
CMake Warning at Libs/Core/CMake/ctkMacroBFDCheck.cmake:69 (MESSAGE):
  warning: CTKCore: Failed to enable BFD support.  Disabling CTKCore
  WITH_BFD_STATIC library option.  See
  /home/jchris/Projects/CTK-Superbuild-Debug/CTK-build/Libs/Core/CMake/TestBDF-build-log.txt
  for more details.
Call Stack (most recent call first):  Libs/Core/CMakeLists.txt:12 (INCLUDE)
-- CTKCore: BFD support disabled
//------------------


Similarly, if CTK_LIB_Core_WITH_BFD_SHARED is enabled, the shared version of
the library will try to be used (libbfd.so)


Let's also note that these two options are mutually exclusive.
If enabled simultaneously, a CMake Fatal error will be displayed.

For example:

//------------------
CMake Error at Libs/Core/CMake/ctkMacroBFDCheck.cmake:7 (MESSAGE):
  error: Options WITH_BFD_STATIC and WITH_BFD_SHARED are mutually exclusive !
  hint: Enable either WITH_BFD_STATIC or WITH_BFD_SHARED.
Call Stack (most recent call first):  Libs/Core/CMakeLists.txt:12 (INCLUDE)
//------------------


The rational ...

Before that change a call to "find_package(bfd)" was used in TestBFD
try_compile test.

Either the static or dynamic version of the library were found.

In case only the static version of the library was found and if CTK was
build as shared library, this was causing error like the one reported below:

//------------------
/usr/bin/ld: error: /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libbfd.a(format.o): requires unsupported dynamic reloc; recompile with -fPIC
...
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libbfd.a(bfd.o): in function bfd_errmsg:../../bfd/bfd.c:484: error: undefined reference to 'xstrerror'
...
//------------------

These link errors are due to the fact the static version of the bfd
library installed on the system is not built using the "-fPIC" flag.

As explained in [1]:
"Usually, shared libraries must be compiled in a special way, for position-independence (PIC).
Because a shared library may be mapped into memory at different locations
each time it is loaded, addresses within the library would be variable.
Therefore, all addresses inside the library are stored zero-based,
relative to the beginning of the library. A register is then set aside
to contain that address, so that all references in the library can be
easily computed at runtime.

This is also a frequent source of errors: Using non-PIC code in a shared
library does not always cause an error. It even works sometimes, but may
cause weird problems on occasion. However, it is never a problem to use
PIC code outside a shared library.
"
[1] http://www.fpx.de/fp/Software/tcl-c++/tcl-c++.html

See also http://www.physics.uq.edu.au/people/foster/amd64_porting.html


To conclude, providing these two new CTKCore options:
 WITH_BFD_STATIC and WITH_BFD_SHARED
allows a better control over the build of CTK and enforce the fact that
BFD support has to be explicitly enabled.

This approach is also more deterministic and ensure to have a similar
default build configuration. Indeed, BFD support in CTKCore will be enabled
on demand instead of being enabled if possible.



On unix, option WITH_SHARED could be easily tested using the following one-liner:
Note: Make sure to update the location of qmake before running this one liner

git clone git://github.com/commontk/CTK.git CTK-BFD-WithShared-Test  && cd CTK-BFD-WithShared-Test && git checkout origin/ctkcore-implement-robust-libbfd-test && cd .. && mkdir CTK-BFD-WithShared-Test-build && cd CTK-BFD-WithShared-Test-build && cmake -DQT_QMAKE_EXECUTABLE:PATH=/home/jchris/Projects/qtsdk-2010.05/qt/bin/qmake -DCTK_LIB_PluginFramework:BOOL=OFF -DCTK_LIB_Core_WITH_BFD_SHARED:BOOL=ON -DCTK_LIB_Core_WITH_BFD_STATIC:BOOL=OFF -DBUILD_TESTING:BOOL=OFF ../CTK-BFD-WithShared-Test && make -j4 && cd ..


On unix, option WITH_STATIC could be easily tested using the following one-liner:
Note: Make sure to update the location of qmake before running this one liner

git clone git://github.com/commontk/CTK.git CTK-BFD-WithStatic-Test  && cd CTK-BFD-WithStatic-Test && git checkout origin/ctkcore-implement-robust-libbfd-test && cd .. && mkdir CTK-BFD-WithStatic-Test-build && cd CTK-BFD-WithStatic-Test-build && cmake -DQT_QMAKE_EXECUTABLE:PATH=/home/jchris/Projects/qtsdk-2010.05/qt/bin/qmake -DCTK_LIB_PluginFramework:BOOL=OFF -DCTK_LIB_Core_WITH_BFD_SHARED:BOOL=OFF -DCTK_LIB_Core_WITH_BFD_STATIC:BOOL=ON -DBUILD_TESTING:BOOL=OFF ../CTK-BFD-WithStatic-Test && make -j4 && cd ..
Jean-Christophe Fillion-Robin преди 14 години
родител
ревизия
3140588349
променени са 4 файла, в които са добавени 94 реда и са изтрити 29 реда
  1. 7 1
      Libs/Core/CMake/TestBFD/CMakeLists.txt
  2. 5 2
      Libs/Core/CMake/TestBFD/TestBFD.cpp
  3. 67 26
      Libs/Core/CMake/ctkMacroBFDCheck.cmake
  4. 15 0
      Libs/Core/ctk_library_options.cmake

+ 7 - 1
Libs/Core/CMake/TestBFD/CMakeLists.txt

@@ -2,7 +2,13 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
 
 PROJECT(TestBFD)
 
-FIND_LIBRARY(BDF_LIBRARY bfd)
+# Sanity checks
+IF("${BDF_LIBRARY_NAME}" STREQUAL "")
+  MESSAGE(FATAL_ERROR "error: ${v} variable is an empty string !")
+ENDIF()
+
+UNSET(BDF_LIBRARY CACHE)
+FIND_LIBRARY(BDF_LIBRARY ${BDF_LIBRARY_NAME})
 
 ADD_EXECUTABLE(TestBFD TestBFD.cpp)
 TARGET_LINK_LIBRARIES(TestBFD ${BDF_LIBRARY})

+ 5 - 2
Libs/Core/CMake/TestBFD/TestBFD.cpp

@@ -9,8 +9,11 @@ int main(int /*argc*/, char * /*argv*/[])
   bfd *abfd = 0;
   asymbol *symbol = 0;
   asection *p = 0;
-
   bfd_init();
-  
+  abfd = bfd_openr("/path/to/library", 0);
+  if (!abfd)
+    {
+    return false;
+    }
   return EXIT_SUCCESS;
 }

+ 67 - 26
Libs/Core/CMake/ctkMacroBFDCheck.cmake

@@ -3,34 +3,75 @@
 #                          HAVE_BFD will be defined if libbfd is available.
 #
 
+IF(CTK_LIB_Core_WITH_BFD_STATIC AND CTK_LIB_Core_WITH_BFD_SHARED)
+  MESSAGE(FATAL_ERROR "error: Options WITH_BFD_STATIC and WITH_BFD_SHARED are mutually exclusive ! "
+                      "hint: Enable either WITH_BFD_STATIC or WITH_BFD_SHARED.")
+ENDIF()
+
+IF(NOT CTK_BUILD_SHARED_LIBS AND CTK_LIB_Core_WITH_BFD_SHARED)
+  MESSAGE(FATAL_ERROR "error: Options CTK_BUILD_SHARED_LIBS and WITH_BFD_STATIC are mutually exclusive ! "
+                      "hint: Disable WITH_BFD_SHARED and enable WITH_BFD_STATIC if needed.")
+ENDIF()
+
 SET(BFD_LIBRARIES)
-UNSET(HAVE_BFD)
-
-IF(NOT WIN32)
-  INCLUDE(CheckIncludeFile)
-  CHECK_INCLUDE_FILE(bfd.h HAVE_BFD_HEADER)
-
-  FIND_LIBRARY(BDF_LIBRARY bfd)
-
-  IF(HAVE_BFD_HEADER AND BDF_LIBRARY)
-    # make sure we can build with libbfd
-    #MESSAGE(STATUS "Checking libbfd")
-    TRY_COMPILE(HAVE_BFD
-      ${CMAKE_CURRENT_BINARY_DIR}/CMake/TestBFD
-      ${CMAKE_CURRENT_SOURCE_DIR}/CMake/TestBFD
-      TestBFD
-      CMAKE_FLAGS
-      -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
-      -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-      OUTPUT_VARIABLE OUTPUT)
-    #MESSAGE(${OUTPUT})
-
-    IF(HAVE_BFD)
-      SET(BFD_LIBRARIES ${BDF_LIBRARY})
-      MESSAGE(STATUS "CTKCore: libbfd is available [${BDF_LIBRARY}]")
-    ELSE()
-      MESSAGE(STATUS "CTKCore: libbfd is *NOT* available")
+UNSET(HAVE_BFD CACHE)
+
+SET(TestBFD_BUILD_LOG "${CMAKE_CURRENT_BINARY_DIR}/CMake/TestBDF-build-log.txt")
+
+if(CTK_LIB_Core_WITH_BFD_STATIC OR CTK_LIB_Core_WITH_BFD_SHARED)
+  IF(WIN32)
+    MESSAGE(FATAL_ERROR "error: Options WITH_BFD_STATIC or WITH_BFD_SHARED are not support on Windows !")
+  ENDIF()
+
+  IF(NOT WIN32)
+    INCLUDE(CheckIncludeFile)
+    CHECK_INCLUDE_FILE(bfd.h HAVE_BFD_HEADER)
+
+    SET(BDF_LIBRARY_NAME libbfd.a)
+    SET(TestBFD_LIBRARY_MODE STATIC)
+    IF(CTK_LIB_Core_WITH_BFD_SHARED)
+      SET(BDF_LIBRARY_NAME libbfd${CMAKE_SHARED_LIBRARY_SUFFIX})
+      SET(TestBFD_LIBRARY_MODE SHARED)
     ENDIF()
+    UNSET(BDF_LIBRARY CACHE)
+    FIND_LIBRARY(BDF_LIBRARY ${BDF_LIBRARY_NAME})
+
+    IF(HAVE_BFD_HEADER AND BDF_LIBRARY)
+      # make sure we can build with libbfd
+      #MESSAGE(STATUS "Checking libbfd")
+      TRY_COMPILE(HAVE_BFD
+        ${CMAKE_CURRENT_BINARY_DIR}/CMake/TestBFD
+        ${CMAKE_CURRENT_SOURCE_DIR}/CMake/TestBFD
+        TestBFD
+        CMAKE_FLAGS
+        -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
+        -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+        -DBDF_LIBRARY_NAME:STRING=${BDF_LIBRARY_NAME}
+        OUTPUT_VARIABLE OUTPUT)
+      FILE(WRITE ${TestBFD_BUILD_LOG} ${OUTPUT})
+      #MESSAGE(${OUTPUT})
 
+      IF(HAVE_BFD)
+        SET(BFD_LIBRARIES ${BDF_LIBRARY})
+      ENDIF()
+    ENDIF()
   ENDIF()
+
+ENDIF()
+
+IF(CTK_LIB_Core_WITH_BFD_SHARED AND NOT HAVE_BFD)
+  MESSAGE(WARNING "warning: CTKCore: Failed to enable BFD support. Disabling CTKCore WITH_BFD_SHARED library option.  "
+                  "See ${TestBFD_BUILD_LOG} for more details.")
+  SET(CTK_LIB_Core_WITH_BFD_SHARED OFF CACHE BOOL "Enable CTKCore Library WITH_BFD_SHARED option" FORCE)
+ENDIF()
+IF(CTK_LIB_Core_WITH_BFD_STATIC AND NOT HAVE_BFD)
+  MESSAGE(WARNING "warning: CTKCore: Failed to enable BFD support. Disabling CTKCore WITH_BFD_STATIC library option. "
+                  "See ${TestBFD_BUILD_LOG} for more details.")
+  SET(CTK_LIB_Core_WITH_BFD_STATIC OFF CACHE BOOL "Enable CTKCore Library WITH_BFD_STATIC option" FORCE)
+endif()
+
+IF(HAVE_BFD)
+  MESSAGE(STATUS "CTKCore: BFD support enabled [${BFD_LIBRARIES}]")
+ELSE()
+  MESSAGE(STATUS "CTKCore: BFD support disabled")
 ENDIF()

+ 15 - 0
Libs/Core/ctk_library_options.cmake

@@ -0,0 +1,15 @@
+#
+# See CMake/ctkMacroAddCtkLibraryOptions.cmake
+# 
+# This file should list of options available for considered CTK library
+# For example: MYOPT1:OFF MYOPT2:ON
+# 
+
+# Note: Options WITH_BFD_SHARED and WITH_BFD_STATIC are mutually exclusive. 
+#       Enabling both options will trigger a configuration error.
+
+SET(ctk_library_options
+  WITH_BFD_SHARED:OFF
+  WITH_BFD_STATIC:OFF
+  )
+