[CMake] Suspecting major install ordering issue (causing BundleUtilities fixup_bundle() / verify_app() failure)

Andreas Mohr andi at lisas.de
Wed Feb 22 11:25:13 EST 2012


Hello all,

in my project I'm doing the usual

    install(
      CODE "
        include(BundleUtilities)
        set(APPS ${APPS})
        message(\"CALLING fixup_bundle on ${APPS}! fixup_bundle_libs ${fixup_bundle_libs}, DIRS ${DIRS}, DESTDIR is \$ENV{DESTDIR}\")
        fixup_bundle(\"\${APPS}\" \"${fixup_bundle_libs}\" \"${DIRS}\")
        message(\"CALLED fixup_bundle!\")
        verify_app( \"\${APPS}\" )
      "
      COMPONENT Runtime
    )

and found that I'm having severe issues getting fixup_bundle() / verify_app() to work.

The major reason AFAICS is that content of my root cmake_install.cmake looks like:

= = = = = = = = = =
  IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Runtime")

          include(BundleUtilities)
          set(APPS $ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib/.../bin/[MY_APP_BINARY])
          message("CALLING fixup_bundle on $ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib/.../bin/[MY_APP_BINARY]! fixup_bundle_libs , DIRS [MY_CMAKE_BINARY_DIR];[MY_CMAKE_BINARY_DIR]/lib;/usr/local/lib, DESTDIR is $ENV{DESTDIR}")
          fixup_bundle("${APPS}" "" "[MY_CMAKE_BINARY_DIR];[MY_CMAKE_BINARY_DIR]/lib;/usr/local/lib")
          message("CALLED fixup_bundle!")
          verify_app( "${APPS}" )

  ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Runtime")
  .
  .
  .
  IF(NOT CMAKE_INSTALL_LOCAL_ONLY)
    # Include the install script for each subdirectory.
    INCLUDE("[MY_CMAKE_BINARY_DIR]/[MY_APP_DEPENDENCY1]/cmake_install.cmake")
    INCLUDE("[MY_CMAKE_BINARY_DIR]/[MY_APP_DEPENDENCY2]/cmake_install.cmake")
    INCLUDE("[MY_CMAKE_BINARY_DIR]/[MY_APP_DEPENDENCY3]/cmake_install.cmake")
    INCLUDE("[MY_CMAKE_BINARY_DIR]/[MY_APP_DEPENDENCY4]/cmake_install.cmake")

  ENDIF(NOT CMAKE_INSTALL_LOCAL_ONLY)
= = = = = = = = = =


I have to state right ahead that my main app
that relies on the dependencies (libraries) in various sub directories
_UNFORTUNATELY_ sits in the source _root_ directory and not any sub directory
(which might be contributing to this problem).


Now the problem is that of course the sub directory cmake_install.cmake:s
do contain their install(TARGETS ...) handling, yet this happens _too late_,
long after after fixup_bundle() has actually been executed.

CMake git cmLocalGenerator.cxx cmLocalGenerator::GenerateInstallRules()
proceeds with executing the CMAKE_INSTALL_LOCAL_ONLY part (executing sub directory installs)
only _after_ any local install code (i.e. the manually added
fixup_bundle() etc.) has been executed.


In my case I notice strong effects,
since my main app is configured to be installed into bin/ and libraries into lib/,
yet BundleUtilities notices missing (not-installed!!) dependencies
in CMAKE_BINARY_DIR/lib (as passed into fixup_bundle() in my code shown above!)
and thus causes cpack to copy them nearby the main binary, i.e. into bin/ !!

I suspect that with many other setups (either non-split lib/bin paths
or no build tree library dependencies to be installed _locally_) this
fixup_bundle() ordering issue simply didn't show up.



https://github.com/nolden/bundle-test.git from
  "Re: [CMake] Question about BundleUtilities" http://www.mail-archive.com/cmake@cmake.org/msg32256.html
generates a cmake_install.cmake which does:

IF(NOT CMAKE_INSTALL_LOCAL_ONLY)
  # Include the install script for each subdirectory.
  INCLUDE("/home/amoh/oss/git/bundle-test/build/libB/cmake_install.cmake")
  INCLUDE("/home/amoh/oss/git/bundle-test/build/libC/cmake_install.cmake")
  INCLUDE("/home/amoh/oss/git/bundle-test/build/libA/cmake_install.cmake")
  INCLUDE("/home/amoh/oss/git/bundle-test/build/main/cmake_install.cmake")

ENDIF(NOT CMAKE_INSTALL_LOCAL_ONLY)

where it's the main/cmake_install.cmake install script which contains the fixup_bundle() code,
so (by accident!?) order here is ok
(one of the sub directories contains the main app which depends on the other library sub directories).

Note also that the INCLUDE("...cmake_install.cmake") lines
as generated from a source tree
do NOT occur in the order of their dependencies
(target_link_libraries(parent_lib dependency_lib)) either,
but rather seemingly random.


I'm strongly pondering submitting this as a grave installation order bug in CMake tracker
- unless someone can enlighten me about my crappy configuration
and "very unusual" (indeed, to put it mildly!!) project tree.


I assume that CMake handling (as invoked by Process Script mode, cmake -P cmake_install.cmake)
will NOT first finish parsing entire recursive content of root cmake_install.cmake and
THEN execute all collected information, but rather execute all statements linearly,
in which case wrong ordering as observed by me would occur.


!!!
And, to think about it in a more high-level way, IMHO it's absolutely
not "ok" for CMake to generate cmake_install.cmake in a way
which _first_ adds custom local content (install(CODE ...) i.e. fixup_bundle() etc.)
and _then_ calls all sub directories'
(i.e. all parts which the parent project part often happens to depend on!!)
install code. Required dependencies' install() handling
should predominantly be processed _first_
and _then_ any custom code of the parent config should be executed.
While a (parent) cmake_install.cmake should be configurable for insertion
of custom code either at the beginning or end of a cmake_install.cmake,
_only_ inserting custom commands before install()ing sub
cmake_install.cmake:s IMHO is a problem.
!!!

Or does that mean that fixup_bundle() _always_ needs to be executed
in some kind of post-install hook? How? Where?

Any thoughts? (other than disabling fixup_bundle() for now...)

Thanks,

Andreas Mohr


More information about the CMake mailing list