summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2011-06-07 18:06:09 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2011-06-07 18:06:09 (GMT)
commit40792a1a15f1ee3c0582486aac9182f8eaa1b316 (patch)
tree6f8dd3136a768559da114b04c00b40bc81ef6d72
parent43d3048582e34a84cc061fddeb3e7967a2c7a576 (diff)
parent51e16c05f7c4e70d8bbf97a13243b1f1cfffa2d7 (diff)
downloadCMake-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.cmake51
-rw-r--r--Modules/GetPrerequisites.cmake6
-rw-r--r--Tests/BundleUtilities/CMakeLists.txt84
-rw-r--r--Tests/BundleUtilities/bundleutils.cmake45
-rw-r--r--Tests/BundleUtilities/framework.cpp8
-rw-r--r--Tests/BundleUtilities/framework.h17
-rw-r--r--Tests/BundleUtilities/module.cpp10
-rw-r--r--Tests/BundleUtilities/module.h7
-rw-r--r--Tests/BundleUtilities/shared.cpp8
-rw-r--r--Tests/BundleUtilities/shared.h17
-rw-r--r--Tests/BundleUtilities/shared2.cpp8
-rw-r--r--Tests/BundleUtilities/shared2.h17
-rw-r--r--Tests/BundleUtilities/testbundleutils1.cpp33
-rw-r--r--Tests/BundleUtilities/testbundleutils2.cpp33
-rw-r--r--Tests/CMakeLists.txt18
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"