[Cmake-commits] [cmake-commits] david.cole committed BundleUtilities.cmake 1.1 1.2 GetPrerequisites.cmake 1.6 1.7
cmake-commits at cmake.org
cmake-commits at cmake.org
Wed Aug 5 14:59:16 EDT 2009
Update of /cvsroot/CMake/CMake/Modules
In directory public:/mounts/ram/cvs-serv7312
Modified Files:
BundleUtilities.cmake GetPrerequisites.cmake
Log Message:
Overhaul GetPrerequisites and BundleUtilities: make fixup_bundle do something useful on Windows and Linux.
Formerly, fixup_bundle was useful only on the Mac for making standalone bundle applications that could be drag-n-drop moved to anyplace in the file system. fixup_bundle is not just for the Mac any more. It will now analyze executable files on Windows and Linux, too, and copy necessary non-system dlls to the same folder that the executable is in. This should work with dlls that you build as part of your build and also with 3rd-party dlls as long as you give fixup_bundle the right list of directories to search for those dlls. Many thanks to Clinton Stimpson for his help in ironing out the details involved in making this work.
Index: BundleUtilities.cmake
===================================================================
RCS file: /cvsroot/CMake/CMake/Modules/BundleUtilities.cmake,v
retrieving revision 1.1
retrieving revision 1.2
diff -C 2 -d -r1.1 -r1.2
*** BundleUtilities.cmake 6 Sep 2008 16:20:07 -0000 1.1
--- BundleUtilities.cmake 5 Aug 2009 18:59:14 -0000 1.2
***************
*** 175,186 ****
if(is_executable)
get_dotapp_dir("${app}" dotapp_dir)
! if(EXISTS "${dotapp_dir}" AND EXISTS "${app}")
set(${bundle_var} "${dotapp_dir}" PARENT_SCOPE)
set(${executable_var} "${app}" PARENT_SCOPE)
set(valid 1)
! #message(STATUS "info: handled executable file case...")
! else(EXISTS "${dotapp_dir}" AND EXISTS "${app}")
! message(STATUS "warning: *NOT* handled - executable file case...")
! endif(EXISTS "${dotapp_dir}" AND EXISTS "${app}")
else(is_executable)
message(STATUS "warning: *NOT* handled - not .app dir, not executable file...")
--- 175,190 ----
if(is_executable)
get_dotapp_dir("${app}" dotapp_dir)
! if(EXISTS "${dotapp_dir}")
set(${bundle_var} "${dotapp_dir}" PARENT_SCOPE)
set(${executable_var} "${app}" PARENT_SCOPE)
set(valid 1)
! #message(STATUS "info: handled executable file in .app dir case...")
! else()
! get_filename_component(app_dir "${app}" PATH)
! set(${bundle_var} "${app_dir}" PARENT_SCOPE)
! set(${executable_var} "${app}" PARENT_SCOPE)
! set(valid 1)
! #message(STATUS "info: handled executable file in any dir case...")
! endif()
else(is_executable)
message(STATUS "warning: *NOT* handled - not .app dir, not executable file...")
***************
*** 231,234 ****
--- 235,241 ----
function(get_item_key item key_var)
get_filename_component(item_name "${item}" NAME)
+ if(WIN32)
+ string(TOLOWER "${item_name}" item_name)
+ endif()
string(REGEX REPLACE "\\." "_" ${key_var} "${item_name}")
set(${key_var} ${${key_var}} PARENT_SCOPE)
***************
*** 389,401 ****
# copy_resolved_item_into_bundle
#
! # Copy a resolved item into the bundle if necessary. Copy is not necessary if the resolved_item
! # is the same as the resolved_embedded_item.
#
function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item)
! if("${resolved_item}" STREQUAL "${resolved_embedded_item}")
message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
! else("${resolved_item}" STREQUAL "${resolved_embedded_item}")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
! endif("${resolved_item}" STREQUAL "${resolved_embedded_item}")
endfunction(copy_resolved_item_into_bundle)
--- 396,418 ----
# copy_resolved_item_into_bundle
#
! # Copy a resolved item into the bundle if necessary. Copy is not necessary if
! # the resolved_item is "the same as" the resolved_embedded_item.
#
function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item)
! if(WIN32)
! # ignore case on Windows
! string(TOLOWER "${resolved_item}" resolved_item_compare)
! string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
! else()
! set(resolved_item_compare "${resolved_item}")
! set(resolved_embedded_item_compare "${resolved_embedded_item}")
! endif()
!
! if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
! else()
! #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
! endif()
endfunction(copy_resolved_item_into_bundle)
***************
*** 504,510 ****
foreach(key ${keys})
math(EXPR i ${i}+1)
! message(STATUS "${i}/${n}: fixing up '${${key}_RESOLVED_EMBEDDED_ITEM}'")
! #message(STATUS " exepath='${exepath}'")
! fixup_bundle_item("${${key}_RESOLVED_EMBEDDED_ITEM}" "${exepath}" "${dirs}")
endforeach(key)
--- 521,530 ----
foreach(key ${keys})
math(EXPR i ${i}+1)
! if(APPLE)
! message(STATUS "${i}/${n}: fixing up '${${key}_RESOLVED_EMBEDDED_ITEM}'")
! fixup_bundle_item("${${key}_RESOLVED_EMBEDDED_ITEM}" "${exepath}" "${dirs}")
! else(APPLE)
! message(STATUS "${i}/${n}: fix-up not required on this platform '${${key}_RESOLVED_EMBEDDED_ITEM}'")
! endif(APPLE)
endforeach(key)
***************
*** 515,519 ****
verify_app("${app}")
else(valid)
! message(STATUS "error: fixup_bundle: not a valid bundle")
endif(valid)
--- 535,539 ----
verify_app("${app}")
else(valid)
! message(SEND_ERROR "error: fixup_bundle: not a valid bundle")
endif(valid)
***************
*** 551,578 ****
if(is_executable)
get_filename_component(exepath "${f}" PATH)
- message(STATUS "executable file: ${f}")
-
math(EXPR count "${count} + 1")
set(prereqs "")
get_prerequisites("${f}" prereqs 1 1 "${exepath}" "")
# "embedded" and "system" prerequisites are fine... anything else means
# the bundle's prerequisites are not verified (i.e., the bundle is not
# really "standalone")
#
set(external_prereqs "")
foreach(p ${prereqs})
set(p_type "")
gp_file_type("${f}" "${p}" p_type)
! if (NOT "${p_type}" STREQUAL "embedded" AND NOT "${p_type}" STREQUAL "system")
! set(external_prereqs ${external_prereqs} "${p}")
! endif (NOT "${p_type}" STREQUAL "embedded" AND NOT "${p_type}" STREQUAL "system")
endforeach(p)
if(external_prereqs)
! # Found non-system/non-embedded prerequisites:
set(result 0)
! set(info ${info} "non-system/non-embedded prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
endif(external_prereqs)
endif(is_executable)
--- 571,610 ----
if(is_executable)
get_filename_component(exepath "${f}" PATH)
math(EXPR count "${count} + 1")
+ message(STATUS "executable file ${count}: ${f}")
+
set(prereqs "")
get_prerequisites("${f}" prereqs 1 1 "${exepath}" "")
+ # On the Mac,
# "embedded" and "system" prerequisites are fine... anything else means
# the bundle's prerequisites are not verified (i.e., the bundle is not
# really "standalone")
#
+ # On Windows (and others? Linux/Unix/...?)
+ # "local" and "system" prereqs are fine...
+ #
set(external_prereqs "")
+
foreach(p ${prereqs})
set(p_type "")
gp_file_type("${f}" "${p}" p_type)
!
! if(APPLE)
! if(NOT "${p_type}" STREQUAL "embedded" AND NOT "${p_type}" STREQUAL "system")
! set(external_prereqs ${external_prereqs} "${p}")
! endif()
! else()
! if(NOT "${p_type}" STREQUAL "local" AND NOT "${p_type}" STREQUAL "system")
! set(external_prereqs ${external_prereqs} "${p}")
! endif()
! endif()
endforeach(p)
if(external_prereqs)
! # Found non-system/somehow-unacceptable prerequisites:
set(result 0)
! set(info ${info} "external prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
endif(external_prereqs)
endif(is_executable)
Index: GetPrerequisites.cmake
===================================================================
RCS file: /cvsroot/CMake/CMake/Modules/GetPrerequisites.cmake,v
retrieving revision 1.6
retrieving revision 1.7
diff -C 2 -d -r1.6 -r1.7
*** GetPrerequisites.cmake 4 Dec 2008 14:12:31 -0000 1.6
--- GetPrerequisites.cmake 5 Aug 2009 18:59:14 -0000 1.7
***************
*** 11,15 ****
# The following functions are provided by this script:
# gp_append_unique
- # gp_file_type
# is_file_executable
# gp_item_default_embedded_path
--- 11,14 ----
***************
*** 17,20 ****
--- 16,21 ----
# gp_resolve_item
# (projects can override with gp_resolve_item_override)
+ # gp_resolved_file_type
+ # gp_file_type
# get_prerequisites
# list_prerequisites
***************
*** 46,126 ****
- # gp_file_type original_file file type_var
- #
- # Return the type of ${file} with respect to ${original_file}. String
- # describing type of prerequisite is returned in variable named ${type_var}.
- #
- # Possible types are:
- # system
- # local
- # embedded
- # other
- #
- function(gp_file_type original_file file type_var)
- set(is_embedded 0)
- set(is_local 0)
- set(is_system 0)
-
- string(TOLOWER "${original_file}" original_lower)
- string(TOLOWER "${file}" lower)
-
- if("${file}" MATCHES "^@(executable|loader)_path")
- set(is_embedded 1)
- endif("${file}" MATCHES "^@(executable|loader)_path")
-
- if(NOT is_embedded)
- if(UNIX)
- if("${file}" MATCHES "^(/lib/|/lib32/|/lib64/)")
- set(is_system 1)
- endif("${file}" MATCHES "^(/lib/|/lib32/|/lib64/)")
- endif(UNIX)
-
- if(APPLE)
- if("${file}" MATCHES "^(/System/Library/|/usr/lib/)")
- set(is_system 1)
- endif("${file}" MATCHES "^(/System/Library/|/usr/lib/)")
- endif(APPLE)
-
- if(WIN32)
- string(TOLOWER "$ENV{SystemRoot}" sysroot)
- string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
-
- string(TOLOWER "$ENV{windir}" windir)
- string(REGEX REPLACE "\\\\" "/" windir "${windir}")
-
- if("${lower}" MATCHES "^(${sysroot}/system|${windir}/system|msvc[^/]+dll)")
- set(is_system 1)
- endif("${lower}" MATCHES "^(${sysroot}/system|${windir}/system|msvc[^/]+dll)")
- endif(WIN32)
-
- if(NOT is_system)
- get_filename_component(original_path "${original_lower}" PATH)
- get_filename_component(path "${lower}" PATH)
- if("${original_path}" STREQUAL "${path}")
- set(is_local 1)
- endif("${original_path}" STREQUAL "${path}")
- endif(NOT is_system)
- endif(NOT is_embedded)
-
- # Return type string based on computed booleans:
- #
- set(type "other")
-
- if(is_system)
- set(type "system")
- else(is_system)
- if(is_embedded)
- set(type "embedded")
- else(is_embedded)
- if(is_local)
- set(type "local")
- endif(is_local)
- endif(is_embedded)
- endif(is_system)
-
- set(${type_var} "${type}" PARENT_SCOPE)
- endfunction(gp_file_type)
-
-
# is_file_executable file result_var
#
--- 47,50 ----
***************
*** 205,241 ****
#
function(gp_item_default_embedded_path item default_embedded_path_var)
- #
- # The assumption here is that all executables in the bundle will be
- # in same-level-directories inside the bundle. The parent directory
- # of an executable inside the bundle should be MacOS or a sibling of
- # MacOS and all embedded paths returned from here will begin with
- # "@executable_path/../" and will work from all executables in all
- # such same-level-directories inside the bundle.
- #
! # By default, embed things right next to the main bundle executable:
#
! set(path "@executable_path/../../Contents/MacOS")
!
set(overridden 0)
! # Embed .dylibs right next to the main bundle executable:
#
! if(item MATCHES "\\.dylib$")
! set(path "@executable_path/../MacOS")
! set(overridden 1)
! endif(item MATCHES "\\.dylib$")
! # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
! #
! if(NOT overridden)
! if(item MATCHES "[^/]+\\.framework/")
! set(path "@executable_path/../Frameworks")
set(overridden 1)
! endif(item MATCHES "[^/]+\\.framework/")
! endif(NOT overridden)
! # Provide a hook so that projects can override the default embedded location of
! # any given library by whatever logic they choose:
#
if(COMMAND gp_item_default_embedded_path_override)
--- 129,175 ----
#
function(gp_item_default_embedded_path item default_embedded_path_var)
! # On Windows and Linux, "embed" prerequisites in the same directory
! # as the executable by default:
#
! set(path "@executable_path")
set(overridden 0)
! # On the Mac, relative to the executable depending on the type
! # of the thing we are embedding:
#
! if(APPLE)
! #
! # The assumption here is that all executables in the bundle will be
! # in same-level-directories inside the bundle. The parent directory
! # of an executable inside the bundle should be MacOS or a sibling of
! # MacOS and all embedded paths returned from here will begin with
! # "@executable_path/../" and will work from all executables in all
! # such same-level-directories inside the bundle.
! #
! # By default, embed things right next to the main bundle executable:
! #
! set(path "@executable_path/../../Contents/MacOS")
!
! # Embed .dylibs right next to the main bundle executable:
! #
! if(item MATCHES "\\.dylib$")
! set(path "@executable_path/../MacOS")
set(overridden 1)
! endif(item MATCHES "\\.dylib$")
! # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
! #
! if(NOT overridden)
! if(item MATCHES "[^/]+\\.framework/")
! set(path "@executable_path/../Frameworks")
! set(overridden 1)
! endif(item MATCHES "[^/]+\\.framework/")
! endif(NOT overridden)
! endif()
!
! # Provide a hook so that projects can override the default embedded location
! # of any given library by whatever logic they choose:
#
if(COMMAND gp_item_default_embedded_path_override)
***************
*** 277,281 ****
set(resolved_item "${ri}")
else(EXISTS "${ri}")
! message(STATUS "info: embedded item does not exist '${ri}'")
endif(EXISTS "${ri}")
endif(item MATCHES "@executable_path")
--- 211,215 ----
set(resolved_item "${ri}")
else(EXISTS "${ri}")
! message(STATUS "warning: embedded item does not exist '${ri}'")
endif(EXISTS "${ri}")
endif(item MATCHES "@executable_path")
***************
*** 297,301 ****
set(resolved_item "${ri}")
else(EXISTS "${ri}")
! message(STATUS "info: embedded item does not exist '${ri}'")
endif(EXISTS "${ri}")
endif(item MATCHES "@loader_path")
--- 231,235 ----
set(resolved_item "${ri}")
else(EXISTS "${ri}")
! message(STATUS "warning: embedded item does not exist '${ri}'")
endif(EXISTS "${ri}")
endif(item MATCHES "@loader_path")
***************
*** 304,310 ****
if(NOT resolved)
set(ri "ri-NOTFOUND")
! find_file(ri "${item}" ${dirs})
if(ri)
! #message(STATUS "info: found item in dirs (${ri})")
set(resolved 1)
set(resolved_item "${ri}")
--- 238,245 ----
if(NOT resolved)
set(ri "ri-NOTFOUND")
! find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
! find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
if(ri)
! #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
set(resolved 1)
set(resolved_item "${ri}")
***************
*** 322,326 ****
)
if(fw)
! #message(STATUS "info: found framework (${fw})")
set(resolved 1)
set(resolved_item "${fw}")
--- 257,261 ----
)
if(fw)
! #message(STATUS "info: 'find_file' found framework (${fw})")
set(resolved 1)
set(resolved_item "${fw}")
***************
*** 336,341 ****
if(NOT resolved)
set(ri "ri-NOTFOUND")
! find_program(ri "${item}" PATHS "${dirs}")
if(ri)
set(resolved 1)
set(resolved_item "${ri}")
--- 271,278 ----
if(NOT resolved)
set(ri "ri-NOTFOUND")
! find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
! find_program(ri "${item}" PATHS "${exepath};${dirs}")
if(ri)
+ #message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
set(resolved 1)
set(resolved_item "${ri}")
***************
*** 353,357 ****
if(NOT resolved)
! message(STATUS "warning: cannot resolve item '${item}'")
endif(NOT resolved)
--- 290,317 ----
if(NOT resolved)
! message(STATUS "
! warning: cannot resolve item '${item}'
!
! possible problems:
! need more directories?
! need to use InstallRequiredSystemLibraries?
! run in install tree instead of build tree?
! ")
! # message(STATUS "
! #******************************************************************************
! #warning: cannot resolve item '${item}'
! #
! # possible problems:
! # need more directories?
! # need to use InstallRequiredSystemLibraries?
! # run in install tree instead of build tree?
! #
! # context='${context}'
! # item='${item}'
! # exepath='${exepath}'
! # dirs='${dirs}'
! # resolved_item_var='${resolved_item_var}'
! #******************************************************************************
! #")
endif(NOT resolved)
***************
*** 360,363 ****
--- 320,451 ----
+ # gp_resolved_file_type original_file file exepath dirs type_var
+ #
+ # Return the type of ${file} with respect to ${original_file}. String
+ # describing type of prerequisite is returned in variable named ${type_var}.
+ #
+ # Use ${exepath} and ${dirs} if necessary to resolve non-absolute ${file}
+ # values -- but only for non-embedded items.
+ #
+ # Possible types are:
+ # system
+ # local
+ # embedded
+ # other
+ #
+ function(gp_resolved_file_type original_file file exepath dirs type_var)
+ #message(STATUS "**")
+
+ if(NOT IS_ABSOLUTE "${original_file}")
+ message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
+ endif()
+
+ set(is_embedded 0)
+ set(is_local 0)
+ set(is_system 0)
+
+ set(resolved_file "${file}")
+
+ if("${file}" MATCHES "^@(executable|loader)_path")
+ set(is_embedded 1)
+ endif()
+
+ if(NOT is_embedded)
+ if(NOT IS_ABSOLUTE "${file}")
+ gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
+ endif()
+
+ string(TOLOWER "${original_file}" original_lower)
+ string(TOLOWER "${resolved_file}" lower)
+
+ if(UNIX)
+ if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/)")
+ set(is_system 1)
+ endif()
+ endif()
+
+ if(APPLE)
+ if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
+ set(is_system 1)
+ endif()
+ endif()
+
+ if(WIN32)
+ string(TOLOWER "$ENV{SystemRoot}" sysroot)
+ string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
+
+ string(TOLOWER "$ENV{windir}" windir)
+ string(REGEX REPLACE "\\\\" "/" windir "${windir}")
+
+ if(lower MATCHES "^(${sysroot}/system|${windir}/system|(.*/)*msvc[^/]+dll)")
+ set(is_system 1)
+ endif()
+ endif()
+
+ if(NOT is_system)
+ get_filename_component(original_path "${original_lower}" PATH)
+ get_filename_component(path "${lower}" PATH)
+ if("${original_path}" STREQUAL "${path}")
+ set(is_local 1)
+ endif()
+ endif()
+ endif()
+
+ # Return type string based on computed booleans:
+ #
+ set(type "other")
+
+ if(is_system)
+ set(type "system")
+ elseif(is_embedded)
+ set(type "embedded")
+ elseif(is_local)
+ set(type "local")
+ endif()
+
+ #message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
+ #message(STATUS " type: '${type}'")
+
+ if(NOT is_embedded)
+ if(NOT IS_ABSOLUTE "${resolved_file}")
+ if(lower MATCHES "^msvc[^/]+dll" AND is_system)
+ message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
+ else()
+ message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
+ endif()
+ endif()
+ endif()
+
+ set(${type_var} "${type}" PARENT_SCOPE)
+
+ #message(STATUS "**")
+ endfunction()
+
+
+ # gp_file_type original_file file type_var
+ #
+ # Return the type of ${file} with respect to ${original_file}. String
+ # describing type of prerequisite is returned in variable named ${type_var}.
+ #
+ # Possible types are:
+ # system
+ # local
+ # embedded
+ # other
+ #
+ function(gp_file_type original_file file type_var)
+ if(NOT IS_ABSOLUTE "${original_file}")
+ message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
+ endif()
+
+ get_filename_component(exepath "${original_file}" PATH)
+
+ set(type "")
+ gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)
+
+ set(${type_var} "${type}" PARENT_SCOPE)
+ endfunction(gp_file_type)
+
+
# get_prerequisites target prerequisites_var exclude_system recurse dirs
#
***************
*** 478,481 ****
--- 566,577 ----
# </setup-gp_tool-vars>
+ if("${gp_tool}" STREQUAL "ldd")
+ set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
+ foreach(dir ${exepath} ${dirs})
+ set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}")
+ endforeach(dir)
+ endif("${gp_tool}" STREQUAL "ldd")
+
+
# Track new prerequisites at each new level of recursion. Start with an
# empty list at each level:
***************
*** 490,493 ****
--- 586,593 ----
)
+ if("${gp_tool}" STREQUAL "ldd")
+ set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
+ endif("${gp_tool}" STREQUAL "ldd")
+
if(verbose)
message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
***************
*** 536,540 ****
if(${exclude_system})
set(type "")
! gp_file_type("${target}" "${item}" type)
if("${type}" STREQUAL "system")
--- 636,640 ----
if(${exclude_system})
set(type "")
! gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
if("${type}" STREQUAL "system")
More information about the Cmake-commits
mailing list