diff options
author | Brad King <brad.king@kitware.com> | 2011-06-07 18:06:09 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2011-06-07 18:06:09 (GMT) |
commit | 40792a1a15f1ee3c0582486aac9182f8eaa1b316 (patch) | |
tree | 6f8dd3136a768559da114b04c00b40bc81ef6d72 | |
parent | 43d3048582e34a84cc061fddeb3e7967a2c7a576 (diff) | |
parent | 51e16c05f7c4e70d8bbf97a13243b1f1cfffa2d7 (diff) | |
download | CMake-40792a1a15f1ee3c0582486aac9182f8eaa1b316.zip CMake-40792a1a15f1ee3c0582486aac9182f8eaa1b316.tar.gz CMake-40792a1a15f1ee3c0582486aac9182f8eaa1b316.tar.bz2 |
Merge topic 'fix-12034-fixup-bundle-with-non-dotapp-exe'
51e16c0 BundleUtilities: Avoid test on Watcom dashboards (#12034)
41f962a Revert "BundleUtilities: Run test on Windows if either MSVC or dumpbin was found."
e17135e BundleUtilities: Add rpath to loadable modules in test.
8064044 BundleUtilities: Print reason for not loading module.so
f3de459 BundleUtilities: Run test on Windows if either MSVC or dumpbin was found.
900bf98 BundleUtilities: Disable running test on Windows unless using MSVC.
fa4dc08 BundleUtilities: Fix issues with custom target DEPENDS in test (#12034)
e40b79e BundleUtilities: Fix test when using xcode (#12034)
b68d3dc BundleUtilities: Fix regex to extract dependents from ldd (#12034)
7ac7b43 BundleUtilities: Work w/ non .app exes on Mac (#12034)
-rw-r--r-- | Modules/BundleUtilities.cmake | 51 | ||||
-rw-r--r-- | Modules/GetPrerequisites.cmake | 6 | ||||
-rw-r--r-- | Tests/BundleUtilities/CMakeLists.txt | 84 | ||||
-rw-r--r-- | Tests/BundleUtilities/bundleutils.cmake | 45 | ||||
-rw-r--r-- | Tests/BundleUtilities/framework.cpp | 8 | ||||
-rw-r--r-- | Tests/BundleUtilities/framework.h | 17 | ||||
-rw-r--r-- | Tests/BundleUtilities/module.cpp | 10 | ||||
-rw-r--r-- | Tests/BundleUtilities/module.h | 7 | ||||
-rw-r--r-- | Tests/BundleUtilities/shared.cpp | 8 | ||||
-rw-r--r-- | Tests/BundleUtilities/shared.h | 17 | ||||
-rw-r--r-- | Tests/BundleUtilities/shared2.cpp | 8 | ||||
-rw-r--r-- | Tests/BundleUtilities/shared2.h | 17 | ||||
-rw-r--r-- | Tests/BundleUtilities/testbundleutils1.cpp | 33 | ||||
-rw-r--r-- | Tests/BundleUtilities/testbundleutils2.cpp | 33 | ||||
-rw-r--r-- | Tests/CMakeLists.txt | 18 |
15 files changed, 333 insertions, 29 deletions
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake index 5e4bf46..0143d59 100644 --- a/Modules/BundleUtilities.cmake +++ b/Modules/BundleUtilities.cmake @@ -53,9 +53,8 @@ # # GET_DOTAPP_DIR(<exe> <dotapp_dir_var>) # Returns the nearest parent dir whose name ends with ".app" given the full -# path to an executable. If there is no such parent dir, then return a dir at -# the same level as the executable, named with the executable's base name and -# ending with ".app" +# path to an executable. If there is no such parent dir, then simply return +# the dir containing the executable. # # The returned directory may or may not exist. # @@ -227,35 +226,35 @@ endfunction(get_bundle_main_executable) function(get_dotapp_dir exe dotapp_dir_var) set(s "${exe}") - set(has_dotapp_parent 0) if(s MATCHES "^.*/.*\\.app/.*$") - set(has_dotapp_parent 1) - endif(s MATCHES "^.*/.*\\.app/.*$") - - set(done 0) - while(NOT ${done}) - get_filename_component(snamewe "${s}" NAME_WE) - get_filename_component(sname "${s}" NAME) - get_filename_component(sdir "${s}" PATH) - if(has_dotapp_parent) - # If there is a ".app" parent directory, - # ascend until we hit it: - # (typical of a Mac bundle executable) - # + # If there is a ".app" parent directory, + # ascend until we hit it: + # (typical of a Mac bundle executable) + # + set(done 0) + while(NOT ${done}) + get_filename_component(snamewe "${s}" NAME_WE) + get_filename_component(sname "${s}" NAME) + get_filename_component(sdir "${s}" PATH) set(s "${sdir}") if(sname MATCHES "\\.app$") set(done 1) set(dotapp_dir "${sdir}/${sname}") endif(sname MATCHES "\\.app$") - else(has_dotapp_parent) - # Otherwise use a directory named the same - # as the exe, but with a ".app" extension: - # (typical of a non-bundle executable on Mac, Windows or Linux) - # - set(done 1) - set(dotapp_dir "${sdir}/${snamewe}.app") - endif(has_dotapp_parent) - endwhile(NOT ${done}) + endwhile(NOT ${done}) + else(s MATCHES "^.*/.*\\.app/.*$") + # Otherwise use a directory containing the exe + # (typical of a non-bundle executable on Mac, Windows or Linux) + # + is_file_executable("${s}" is_executable) + if(is_executable) + get_filename_component(sdir "${s}" PATH) + set(dotapp_dir "${sdir}") + else(is_executable) + set(dotapp_dir "${s}") + endif(is_executable) + endif(s MATCHES "^.*/.*\\.app/.*$") + set(${dotapp_dir_var} "${dotapp_dir}" PARENT_SCOPE) endfunction(get_dotapp_dir) diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index 853b1a1..023b8b5 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -261,9 +261,9 @@ function(gp_resolve_item context item exepath dirs resolved_item_var) # Is it already resolved? # - if(EXISTS "${resolved_item}") + if(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}") set(resolved 1) - endif(EXISTS "${resolved_item}") + endif(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}") if(NOT resolved) if(item MATCHES "@executable_path") @@ -548,7 +548,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa if("${gp_tool}" STREQUAL "ldd") set(gp_cmd_args "") - set(gp_regex "^[\t ]*[^\t ]+ => ([^\t ]+).*${eol_char}$") + set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$") set(gp_regex_error "not found${eol_char}$") set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$") set(gp_regex_cmp_count 1) diff --git a/Tests/BundleUtilities/CMakeLists.txt b/Tests/BundleUtilities/CMakeLists.txt new file mode 100644 index 0000000..6209c8f --- /dev/null +++ b/Tests/BundleUtilities/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 2.8) +project(BundleUtilities) + +###### the various types of dependencies we can have + +# a shared library +add_library(shared SHARED shared.cpp shared.h) + +# another shared library +add_library(shared2 SHARED shared2.cpp shared2.h) + + +# a framework library +add_library(framework SHARED framework.cpp framework.h) +# TODO: fix problems with local frameworks without rpaths +#set_target_properties(framework PROPERTIES FRAMEWORK 1) + +# make sure rpaths are not helping BundleUtilities or the executables +set_target_properties(shared shared2 framework PROPERTIES + SKIP_BUILD_RPATH 1) + + +###### test a Bundle application using dependencies + +# a loadable module (depends on shared2) +# testbundleutils1 will load this at runtime +add_library(module1 MODULE module.cpp module.h) +set_target_properties(module1 PROPERTIES PREFIX "") +get_target_property(module_loc module1 LOCATION) +target_link_libraries(module1 shared2) + +# a bundle application +add_executable(testbundleutils1 MACOSX_BUNDLE testbundleutils1.cpp) +target_link_libraries(testbundleutils1 shared framework ${CMAKE_DL_LIBS}) +get_target_property(loc testbundleutils1 LOCATION) + +set_target_properties(testbundleutils1 module1 PROPERTIES + INSTALL_RPATH "${CMAKE_CURRENT_BINARY_DIR}/testdir1" + BUILD_WITH_INSTALL_RPATH 1) + +# add custom target to install and test the app +add_custom_target(testbundleutils1_test ALL + COMMAND ${CMAKE_COMMAND} + "-DINPUT=${loc}" + "-DMODULE=${module_loc}" + "-DINPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" + "-DOUTPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/testdir1" + -P "${CMAKE_CURRENT_SOURCE_DIR}/bundleutils.cmake" + DEPENDS testbundleutils1 module1 + ) + +add_dependencies(testbundleutils1_test testbundleutils1) + + + +###### test a non-Bundle application using dependencies + +# a loadable module (depends on shared2) +# testbundleutils2 will load this at runtime +add_library(module2 MODULE module.cpp module.h) +set_target_properties(module2 PROPERTIES PREFIX "") +get_target_property(module_loc module2 LOCATION) +target_link_libraries(module2 shared2) + +# a non-bundle application +add_executable(testbundleutils2 testbundleutils2.cpp) +target_link_libraries(testbundleutils2 shared framework ${CMAKE_DL_LIBS}) +get_target_property(loc testbundleutils2 LOCATION) + +set_target_properties(testbundleutils2 module2 PROPERTIES + INSTALL_RPATH "${CMAKE_CURRENT_BINARY_DIR}/testdir2" + BUILD_WITH_INSTALL_RPATH 1) + +# add custom target to install and test the app +add_custom_target(testbundleutils2_test ALL + COMMAND ${CMAKE_COMMAND} + "-DINPUT=${loc}" + "-DMODULE=${module_loc}" + "-DINPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" + "-DOUTPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/testdir2" + -P "${CMAKE_CURRENT_SOURCE_DIR}/bundleutils.cmake" + DEPENDS testbundleutils1 module2 + ) +add_dependencies(testbundleutils2_test testbundleutils2) diff --git a/Tests/BundleUtilities/bundleutils.cmake b/Tests/BundleUtilities/bundleutils.cmake new file mode 100644 index 0000000..46765e7 --- /dev/null +++ b/Tests/BundleUtilities/bundleutils.cmake @@ -0,0 +1,45 @@ + +# clean passed in arguments +get_filename_component(INPUT ${INPUT} ABSOLUTE) +get_filename_component(INPUTDIR ${INPUTDIR} ABSOLUTE) + +message("INPUT = ${INPUT}") +message("MODULE = ${MODULE}") +message("INPUTDIR = ${INPUTDIR}") +message("OUTPUTDIR = ${OUTPUTDIR}") + +# compute location to install/test things +file(RELATIVE_PATH relative_exe "${INPUTDIR}" "${INPUT}") +set(OUTPUT "${OUTPUTDIR}/${relative_exe}") +message("OUTPUT = ${OUTPUT}") +get_filename_component(EXE_DIR "${OUTPUT}" PATH) +get_filename_component(MODULE_NAME "${MODULE}" NAME) +set(OUTPUT_MODULE "${EXE_DIR}/${MODULE_NAME}") +message("OUTPUTMODULE = ${OUTPUT_MODULE}") + +# clean output dir +file(REMOVE_RECURSE "${OUTPUTDIR}") +# copy the app and plugin to installation/testing directory +configure_file("${INPUT}" "${OUTPUT}" COPYONLY) +configure_file("${MODULE}" "${OUTPUT_MODULE}" COPYONLY) + +# have BundleUtilities grab all dependencies and +# check that the app runs + +# for this test we'll override location to put all dependencies +# (in the same dir as the app) +# this shouldn't be necessary except for the non-bundle case on Mac +function(gp_item_default_embedded_path_override item path) + set(path "@executable_path" PARENT_SCOPE) +endfunction(gp_item_default_embedded_path_override) + +include(BundleUtilities) +fixup_bundle("${OUTPUT}" "${OUTPUT_MODULE}" "${INPUTDIR}") + +# make sure we can run the app +message("Executing ${OUTPUT} in ${EXE_DIR}") +execute_process(COMMAND "${OUTPUT}" RESULT_VARIABLE result OUTPUT_VARIABLE out ERROR_VARIABLE out WORKING_DIRECTORY "${EXE_DIR}") + +if(NOT result STREQUAL "0") + message(FATAL_ERROR " failed to execute test program\n${out}") +endif(NOT result STREQUAL "0") diff --git a/Tests/BundleUtilities/framework.cpp b/Tests/BundleUtilities/framework.cpp new file mode 100644 index 0000000..abda195 --- /dev/null +++ b/Tests/BundleUtilities/framework.cpp @@ -0,0 +1,8 @@ + +#include "framework.h" +#include "stdio.h" + +void framework() +{ + printf("framework\n"); +} diff --git a/Tests/BundleUtilities/framework.h b/Tests/BundleUtilities/framework.h new file mode 100644 index 0000000..bdd10f0 --- /dev/null +++ b/Tests/BundleUtilities/framework.h @@ -0,0 +1,17 @@ + +#ifndef framework_h +#define framework_h + +#ifdef WIN32 +# ifdef framework_EXPORTS +# define FRAMEWORK_EXPORT __declspec(dllexport) +# else +# define FRAMEWORK_EXPORT __declspec(dllimport) +# endif +#else +# define FRAMEWORK_EXPORT +#endif + +void FRAMEWORK_EXPORT framework(); + +#endif diff --git a/Tests/BundleUtilities/module.cpp b/Tests/BundleUtilities/module.cpp new file mode 100644 index 0000000..ee1b542 --- /dev/null +++ b/Tests/BundleUtilities/module.cpp @@ -0,0 +1,10 @@ + +#include "module.h" +#include "stdio.h" +#include "shared2.h" + +void module() +{ + printf("module\n"); + shared2(); +} diff --git a/Tests/BundleUtilities/module.h b/Tests/BundleUtilities/module.h new file mode 100644 index 0000000..0659bc7 --- /dev/null +++ b/Tests/BundleUtilities/module.h @@ -0,0 +1,7 @@ + +#ifndef module_h +#define module_h + +void module(); + +#endif diff --git a/Tests/BundleUtilities/shared.cpp b/Tests/BundleUtilities/shared.cpp new file mode 100644 index 0000000..e5e7dc5 --- /dev/null +++ b/Tests/BundleUtilities/shared.cpp @@ -0,0 +1,8 @@ + +#include "shared.h" +#include "stdio.h" + +void shared() +{ + printf("shared\n"); +} diff --git a/Tests/BundleUtilities/shared.h b/Tests/BundleUtilities/shared.h new file mode 100644 index 0000000..3588fb8 --- /dev/null +++ b/Tests/BundleUtilities/shared.h @@ -0,0 +1,17 @@ + +#ifndef shared_h +#define shared_h + +#ifdef WIN32 +# ifdef shared_EXPORTS +# define SHARED_EXPORT __declspec(dllexport) +# else +# define SHARED_EXPORT __declspec(dllimport) +# endif +#else +# define SHARED_EXPORT +#endif + +void SHARED_EXPORT shared(); + +#endif diff --git a/Tests/BundleUtilities/shared2.cpp b/Tests/BundleUtilities/shared2.cpp new file mode 100644 index 0000000..84af5d0 --- /dev/null +++ b/Tests/BundleUtilities/shared2.cpp @@ -0,0 +1,8 @@ + +#include "shared2.h" +#include "stdio.h" + +void shared2() +{ + printf("shared2\n"); +} diff --git a/Tests/BundleUtilities/shared2.h b/Tests/BundleUtilities/shared2.h new file mode 100644 index 0000000..d53546c --- /dev/null +++ b/Tests/BundleUtilities/shared2.h @@ -0,0 +1,17 @@ + +#ifndef shared2_h +#define shared2_h + +#ifdef WIN32 +# ifdef shared2_EXPORTS +# define SHARED2_EXPORT __declspec(dllexport) +# else +# define SHARED2_EXPORT __declspec(dllimport) +# endif +#else +# define SHARED2_EXPORT +#endif + +void SHARED2_EXPORT shared2(); + +#endif diff --git a/Tests/BundleUtilities/testbundleutils1.cpp b/Tests/BundleUtilities/testbundleutils1.cpp new file mode 100644 index 0000000..23d3cbd --- /dev/null +++ b/Tests/BundleUtilities/testbundleutils1.cpp @@ -0,0 +1,33 @@ + +#include "framework.h" +#include "shared.h" +#include "stdio.h" + +#if defined(WIN32) +#include <windows.h> +#else +#include "dlfcn.h" +#endif + +int main(int, char**) +{ + framework(); + shared(); + +#if defined(WIN32) + HANDLE lib = LoadLibraryA("module1.dll"); + if(!lib) + { + printf("Failed to open module1\n"); + } +#else + void* lib = dlopen("module1.so", RTLD_LAZY); + if(!lib) + { + printf("Failed to open module1\n%s\n", dlerror()); + } +#endif + + + return lib == 0 ? 1 : 0; +} diff --git a/Tests/BundleUtilities/testbundleutils2.cpp b/Tests/BundleUtilities/testbundleutils2.cpp new file mode 100644 index 0000000..319be89 --- /dev/null +++ b/Tests/BundleUtilities/testbundleutils2.cpp @@ -0,0 +1,33 @@ + +#include "framework.h" +#include "shared.h" +#include "stdio.h" + +#if defined(WIN32) +#include <windows.h> +#else +#include "dlfcn.h" +#endif + +int main(int, char**) +{ + framework(); + shared(); + +#if defined(WIN32) + HANDLE lib = LoadLibraryA("module2.dll"); + if(!lib) + { + printf("Failed to open module2\n"); + } +#else + void* lib = dlopen("module2.so", RTLD_LAZY); + if(!lib) + { + printf("Failed to open module2\n%s\n", dlerror()); + } +#endif + + + return lib == 0 ? 1 : 0; +} diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index bf08b52..1be2a24 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -193,6 +193,24 @@ IF(BUILD_TESTING) LIST(APPEND TEST_BUILD_DIRS ${CMake_TEST_INSTALL_PREFIX}) + + # run test for BundleUtilities on supported platforms/compilers + if(MSVC OR + CMAKE_SYSTEM_NAME MATCHES "Linux" OR + CMAKE_SYSTEM_NAME MATCHES "Darwin") + if(NOT "${CMAKE_TEST_GENERATOR}" STREQUAL "Watcom WMake") + ADD_TEST(BundleUtilities ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/BundleUtilities" + "${CMake_BINARY_DIR}/Tests/BundleUtilities" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-project BundleUtilities + ) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleUtilities") + endif() + endif() + SET(CMAKE_BUILD_TEST_SOURCE_DIR "${CMake_SOURCE_DIR}/Tests/COnly") SET(CMAKE_BUILD_TEST_BINARY_DIR "${CMake_BINARY_DIR}/Tests/CMakeBuildCOnly") CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CMakeBuildTest.cmake.in" |