View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0012629CMakeCMakeSetuppublic2011-12-15 19:282012-09-03 16:02
ReporterMark Abraham 
Assigned ToBrad King 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionfixed 
PlatformanyOSanyOS Versionany
Product VersionCMake 2.8.4 
Target VersionCMake 2.8.8Fixed in VersionCMake 2.8.8 
Summary0012629: bootstrap of CMake can fail when a wrong libmd is found
DescriptionUtilities/cmlibarchive/CMakeLists.txt uses

IF(CRYPTO_LIBRARY)
  LIST(APPEND ADDITIONAL_LIBS ${CRYPTO_LIBRARY})
ELSE(CRYPTO_LIBRARY)
  IF(NOT OPENSSL_FOUND)
    FIND_LIBRARY(MD_LIBRARY NAMES md)
    IF(MD_LIBRARY)
      LIST(APPEND ADDITIONAL_LIBS ${MD_LIBRARY})
    ENDIF(MD_LIBRARY)
  ENDIF(NOT OPENSSL_FOUND)
ENDIF(CRYPTO_LIBRARY)

This fails if libmd exists in the search path but is actually from the GROMACS simulation package, rather than the crypto message digest library. A try_compile() test after a successful find_library() would allow the CMake bootstrap to be more robust.
Steps To Reproduce1. Use ./bootstrap on a system with GROMACS (http://www.gromacs.org [^]) installed and http://martin.hinner.info/libmd/ [^] not installed.

2. Do make

3. Observe that CMake tools cannot link because of the unsatisfied dependencies of the inappropriate -lmd.
Additional InformationI was able to successfully build CMake on this system by removing the resulting "-lmd" from all the links.txt files, using a combination of sed -i and find.
TagsNo tags attached.
Attached Files

- Relationships Relation Graph ] Dependency Graph ]

-  Notes
(0027991)
Brad King (manager)
2011-12-16 08:44

We cannot possibly try_compile for every symbol we need from every library just to be sure it will succeed at link time and in case the user's system provides a library named like we need but that comes from another package.

You can build by telling CMake not to look for MD_LIBRARY:

$ mkdir CMake-build && cd CMake-build
$ echo 'set(MD_LIBRARY "" CACHE FILEPATH "" FORCE)' > Init.cmake
$ ../CMake/bootstrap --init=Init.cmake


OR

$ mkdir CMake-build && cd CMake-build
$ echo 'MD_LIBRARY:FILEPATH=' > CMakeCache.txt
$ ../CMake/bootstrap
(0027992)
Mark Abraham (reporter)
2011-12-16 08:59

> We cannot possibly try_compile for every symbol we need from every library just to be sure it will succeed at link time and in case the user's system provides a library named like we need but that comes from another package.

Sure, you might not wish do that for every library "just in case", but where there's a known instance of a failing case, why not seek to avoid further failing cases?

I'd offer a try_compile() patch, but there seems to be nothing that is actually required to be linked. The quoted code seems to impose an arbitrary requirement to link libmd if found, and on at least some platforms (such as the one I was using) nothing later actually links to libmd (because removing -lmd worked) and somehow this creates unsatisified dependencies (because not removing -lmd didn't work).
(0027993)
Brad King (manager)
2011-12-16 09:07

The code in question comes from a third-party project (libarchive). It looks like the upstream has changed the way they look for md to do something like you suggest:

http://code.google.com/p/libarchive/source/browse/trunk/CMakeLists.txt?r=3925#331 [^]

Eventually CMake will update to a more recent libarchive snapshot and then we'll get those changes for free. Until then perhaps you can port their approach over to CMake's version.
(0027996)
Mark Abraham (reporter)
2011-12-16 19:49

I looked at their approach, but porting seemed complex. Instead, here's a patch in the same spirit. It requires the crypto library only after it's been proved to link something useful.


--- cmake-2.8.4/Utilities/cmlibarchive/CMakeLists.txt 2011-02-16 06:47:39.000000000 +1300
+++ cmake-2.8.4-fixed/Utilities/cmlibarchive/CMakeLists.txt 2011-12-17 13:39:29.416308848 +1300
@@ -297,6 +297,11 @@ LA_CHECK_INCLUDE_FILE("sha1.h" HAVE_SHA1
 LA_CHECK_INCLUDE_FILE("sha2.h" HAVE_SHA2_H)
 LA_CHECK_INCLUDE_FILE("sha256.h" HAVE_SHA256_H)
 
+# The libmd name can clash with a non-crypto library, so
+# we don't want to require linking against it unless it
+# provides the necessary function.
+SET(ADDITIONAL_CRYPTO_LIBS)
+SET(COMBINED_ADDITIONAL_LIBS)
 #
 # Find MD5/RMD160/SHA library
 #
@@ -306,19 +311,21 @@ ELSE()
   SET(CRYPTO_LIBRARY "")
 ENDIF()
 IF(CRYPTO_LIBRARY)
- LIST(APPEND ADDITIONAL_LIBS ${CRYPTO_LIBRARY})
+ LIST(APPEND ADDITIONAL_CRYPTO_LIBS ${CRYPTO_LIBRARY})
 ELSE(CRYPTO_LIBRARY)
   IF(NOT OPENSSL_FOUND)
     FIND_LIBRARY(MD_LIBRARY NAMES md)
     IF(MD_LIBRARY)
- LIST(APPEND ADDITIONAL_LIBS ${MD_LIBRARY})
+ LIST(APPEND ADDITIONAL_CRYPTO_LIBS ${MD_LIBRARY})
     ENDIF(MD_LIBRARY)
   ENDIF(NOT OPENSSL_FOUND)
 ENDIF(CRYPTO_LIBRARY)
 #
 # Check MD5/RMD160/SHA functions
 #
-SET(CMAKE_REQUIRED_LIBRARIES ${ADDITIONAL_LIBS})
+LIST(APPEND COMBINED_ADDITIONAL_LIBS ${ADDITIONAL_LIBS})
+LIST(APPEND COMBINED_ADDITIONAL_LIBS ${ADDITIONAL_CRYPTO_LIBS})
+SET(CMAKE_REQUIRED_LIBRARIES ${COMBINED_ADDITIONAL_LIBS})
 CHECK_FUNCTION_EXISTS(MD5_Init HAVE_MD5_Init)
 IF(NOT HAVE_MD5_Init)
   CHECK_FUNCTION_EXISTS(MD5Init HAVE_MD5Init)
@@ -362,6 +369,15 @@ CHECK_FUNCTION_EXISTS(SHA256_Init HAVE_S
 CHECK_FUNCTION_EXISTS(SHA384_Init HAVE_SHA384)
 CHECK_FUNCTION_EXISTS(SHA512_Init HAVE_SHA512)
 
+# If crypto libs can be linked against, then require them to be linked
+IF(HAVE_MD5 OR HAVE_RMD160 OR HAVE_SHA1 OR HAVE_SHA256 OR HAVE_SHA384 OR HAVE_SHA512)
+ LIST(APPEND ADDITIONAL_LIBS ${ADDITIONAL_CRYPTO_LIBS})
+ SET(CMAKE_REQUIRED_LIBRARIES ${ADDITIONAL_LIBS})
+ELSE(HAVE_MD5 OR HAVE_RMD160 OR HAVE_SHA1 OR HAVE_SHA256 OR HAVE_SHA384 OR HAVE_SHA512)
+ SET(CMAKE_REQUIRED_LIBRARIES ${ADDITIONAL_LIBS})
+ENDIF(HAVE_MD5 OR HAVE_RMD160 OR HAVE_SHA1 OR HAVE_SHA256 OR HAVE_SHA384 OR HAVE_SHA512)
+
+
 #
 # Check functions
 #

This works on my system with the non-crypto libmd.
(0028011)
Brad King (manager)
2011-12-19 11:57

I think all you need is the

  CHECK_LIBRARY_EXISTS(md "MD5Init" "" LIBMD_FOUND)

line to detect md in place of the current assumption that it exists.
(0028244)
Brad King (manager)
2012-01-10 15:46

We've merged a topic to master that updates libarchive from upstream:

  http://cmake.org/gitweb?p=cmake.git;a=commit;h=5a5c32e1 [^]

The new version uses a better approach to detect these libraries and I do not think it has this problem.
(0028250)
Mark Abraham (reporter)
2012-01-10 18:35

Yes, the git version of CMake builds on the problem system, so this issue looks fixed.
(0030898)
David Cole (manager)
2012-09-03 16:02

Closing resolved issues that have not been updated in more than 4 months.

- Issue History
Date Modified Username Field Change
2011-12-15 19:28 Mark Abraham New Issue
2011-12-16 08:44 Brad King Note Added: 0027991
2011-12-16 08:59 Mark Abraham Note Added: 0027992
2011-12-16 09:07 Brad King Note Added: 0027993
2011-12-16 19:49 Mark Abraham Note Added: 0027996
2011-12-19 11:57 Brad King Note Added: 0028011
2012-01-10 15:46 Brad King Note Added: 0028244
2012-01-10 15:46 Brad King Status new => resolved
2012-01-10 15:46 Brad King Resolution open => fixed
2012-01-10 15:46 Brad King Assigned To => Brad King
2012-01-10 18:35 Mark Abraham Note Added: 0028250
2012-01-10 18:35 Mark Abraham Status resolved => feedback
2012-01-10 18:35 Mark Abraham Resolution fixed => reopened
2012-01-11 07:56 Brad King Status feedback => resolved
2012-01-11 07:56 Brad King Fixed in Version => CMake 2.8.8
2012-01-11 07:56 Brad King Resolution reopened => fixed
2012-04-30 09:31 David Cole Target Version => CMake 2.8.8
2012-09-03 16:02 David Cole Note Added: 0030898
2012-09-03 16:02 David Cole Status resolved => closed


Copyright © 2000 - 2017 MantisBT Team
Powered by Mantis Bugtracker