diff options
| author | Mike Taves <mwtoews@gmail.com> | 2021-12-09 00:45:03 +1300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-09 00:45:03 +1300 |
| commit | 7a9b6566ac02d8c408f4f3758bfa5fcc3e90b552 (patch) | |
| tree | d71d0771cc9f95d5a8ea96bd975bbd4164188813 /test/postinstall | |
| parent | 1b18defb63c7d2420d18e4375348663874247838 (diff) | |
| download | PROJ-7a9b6566ac02d8c408f4f3758bfa5fcc3e90b552.tar.gz PROJ-7a9b6566ac02d8c408f4f3758bfa5fcc3e90b552.zip | |
Refactor post-install suite to test shared and static projlib (#2972)
Diffstat (limited to 'test/postinstall')
30 files changed, 743 insertions, 268 deletions
diff --git a/test/postinstall/README.md b/test/postinstall/README.md new file mode 100644 index 00000000..3bda47b5 --- /dev/null +++ b/test/postinstall/README.md @@ -0,0 +1,41 @@ +# Post-install tests + +The purpose of these tests is to check if an installed PROJ library can be used to configure and build other applications. It provides additional test coverage for the CMake config files and with `proj.pc` used for pkg-config. + +## Applications + +The two trivial applications `c_app` and `cpp_app` use C and C++ compilers, respectively. They function similarly, taking only one flag `-t` for an example coordinate transform, `-s` to show searchpath, and `-v` for the version of PROJ. + +## Configure method + +Each configure method is driven using a script with two arguments: +1. Path to a PROJ install prefix (containing `bin`, `lib`, etc.) +2. An optional build mode `shared` (default) or `static` + +### CMake + +Use `test_cmake.sh` for Unix-like or `test_cmake.bat` for Windows. This checks that `find_package(PROJ)` (or legacy `find_package(PROJ4)`) can be used with `target_link_libraries(mytarget PRIVATE PROJ::proj)`. The C-based app enables C++ when linking to static libproj. These scripts will only work with PROJ built using CMake, and will not work with PROJ built using Autotools. + +### Makefile / pkg-config + +`test_pkg-config.sh` uses a simple Makefile named `makefile.mak` (so it can co-exist with Autotools) that calls pkg-config to get include and library paths. If static linking is requested on Linux, `LDFLAGS` is modified to specify `-Wl,-Bstatic -lproj -Wl,-Bdynamic`. + +### Autotools / pkg-config + +`test_autotools.sh` uses Autoconf's `PKG_CHECK_MODULES([PROJ], [proj])` to get include and library paths for Automake. Static linking to libproj is enabled with `--enable-static-proj` configure option, which modifies `PROJ_LIBS` similar to the Makefile example. + +## Build mode + +Two build modes are tested with each configure method: +1. `shared` for dynamic linking with libproj (or proj.dll for MSVC) +2. `static` for static linking with libproj (or proj.lib for MSVC); note that static linking of dependants is out-of-scope with these tests, so only libproj is assumed to be static + +## Tests + +All configure methods share the same suite of tests for `c_app` and `cpp_app`: + +- `test_ldd` - examines the shared object dependencies to see if "libproj" is found with the correct path (for `shared` build mode), or not listed as a dependency for builds with static libproj. +- `test_transform` - example coordinate transform to ensure basic functions work as expected. +- `test_searchpath` - compares `searchpath` (from `proj_info()`) to either `datadir` via pkg-config or relative path `PROJ_DIR/../../../share/proj` via CMake. +- `test_version` - compares PROJ version components from `proj_info()` to the version from pkg-config or CMake. + diff --git a/test/postinstall/c_app/CMakeLists.txt b/test/postinstall/c_app/CMakeLists.txt new file mode 100644 index 00000000..a493849b --- /dev/null +++ b/test/postinstall/c_app/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.5) +project(C_APP LANGUAGES C) + +set(USE_PROJ_NAME "PROJ" + CACHE STRING "Either PROJ (default) or PROJ4") + +find_package(${USE_PROJ_NAME} REQUIRED CONFIG) + +include(CMakePrintHelpers) +cmake_print_properties( + TARGETS ${USE_PROJ_NAME}::proj + PROPERTIES + LOCATION + INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_LINK_LIBRARIES + INTERFACE_COMPILE_FEATURES +) + +add_executable(c_app c_app.c) +target_link_libraries(c_app PRIVATE ${USE_PROJ_NAME}::proj) + +get_target_property(PROJLIB_LOCATION ${USE_PROJ_NAME}::proj LOCATION) +if(PROJLIB_LOCATION MATCHES ".*\.(lib|a)$") + # Used for static linking (is there a better way?) + enable_language(CXX) + set_target_properties(c_app PROPERTIES LINKER_LANGUAGE CXX) +endif() + +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/..) +include(common) +add_test_ldd(c_app proj) +add_test_transform(c_app) +add_test_searchpath(c_app) +add_test_version(c_app) diff --git a/test/postinstall/c_app/Makefile.am b/test/postinstall/c_app/Makefile.am new file mode 100644 index 00000000..356034ba --- /dev/null +++ b/test/postinstall/c_app/Makefile.am @@ -0,0 +1,9 @@ +bin_PROGRAMS = c_app +c_app_SOURCES = c_app.c +c_app_CFLAGS = $(PROJ_CFLAGS) +c_app_LDADD = $(PROJ_LIBS) +TESTS = \ + test_ldd.sh \ + test_transform.sh \ + test_searchpath.sh \ + test_version.sh diff --git a/test/postinstall/c_app/c_app.c b/test/postinstall/c_app/c_app.c new file mode 100644 index 00000000..58d7e135 --- /dev/null +++ b/test/postinstall/c_app/c_app.c @@ -0,0 +1,43 @@ +#include <stdio.h> +#include <proj.h> + +int test_transform() { + PJ *P; + PJ_COORD a, b; + P = proj_create_crs_to_crs( + PJ_DEFAULT_CTX, + "EPSG:4326", + "+proj=utm +zone=32 +datum=WGS84", /* or EPSG:32632 */ + NULL); + if (0 == P) { + fprintf(stderr, "Oops\n"); + return 1; + } + /* Copenhagen: 55d N, 12d E */ + a = proj_coord(55, 12, 0, 0); + b = proj_trans(P, PJ_FWD, a); + printf("easting: %.2f, northing: %.2f, ", b.enu.e, b.enu.n); + b = proj_trans(P, PJ_INV, b); + printf("latitude: %.2f, longitude: %.2f\n", b.lp.lam, b.lp.phi); + proj_destroy(P); + return 0; +} + +int main(int argc, char *argv[]) { + PJ_INFO info; + info = proj_info(); + if(argc == 2 && argv[1][0] == '-') { + switch(argv[1][1]) { + case 't': + return(test_transform()); + case 's': + printf("%s\n", info.searchpath); + return(0); + case 'v': + printf("%d.%d.%d\n", info.major, info.minor, info.patch); + return(0); + } + } + fprintf(stderr, "Use option -t, -s or -v\n"); + return(1); +} diff --git a/test/postinstall/c_app/configure.ac b/test/postinstall/c_app/configure.ac new file mode 100644 index 00000000..43ae4835 --- /dev/null +++ b/test/postinstall/c_app/configure.ac @@ -0,0 +1,18 @@ +AC_INIT([c_app], [0.1]) +AM_INIT_AUTOMAKE +AC_PROG_CC +AC_CONFIG_MACRO_DIR([../../../m4]) + +PKG_CHECK_MODULES([PROJ], [proj]) + +AC_ARG_ENABLE([static-proj], + AS_HELP_STRING([--enable-static-proj], + [Enable linking to static PROJ library])) + +# If enabled, force static linking for Linux +if test "x$enable_static_proj" = "xyes" -a "x$(uname)" = "xLinux"; then + PROJ_LIBS=$(echo "$PROJ_LIBS" | sed 's/-lproj/-Wl,-Bstatic -lproj -Wl,-Bdynamic/') +fi + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/test/postinstall/c_app/makefile.mak b/test/postinstall/c_app/makefile.mak new file mode 100644 index 00000000..d6c1c8de --- /dev/null +++ b/test/postinstall/c_app/makefile.mak @@ -0,0 +1,34 @@ +PROGRAM = c_app +OBJECTS = $(addsuffix .o,$(PROGRAM)) +TESTS = \ + test_ldd.sh \ + test_transform.sh \ + test_searchpath.sh \ + test_version.sh + +override CFLAGS += -g -Wall -Werror $(shell pkg-config proj --cflags) + +ifeq ($(BUILD_MODE),static) + UNAME_S := $(shell uname -s) + _ldflags := $(shell pkg-config proj --libs --static) + ifeq ($(UNAME_S),Linux) + # force static linking to libproj + _ldflags := $(shell echo $(_ldflags) | sed 's/-lproj/-Wl,-Bstatic -lproj -Wl,-Bdynamic/') + endif + override LDFLAGS += $(_ldflags) +else # default is shared + override LDFLAGS += $(shell pkg-config proj --libs) +endif + +all: $(PROGRAM) + +$(PROGRAM): $(OBJECTS) + $(CC) -o $@ $< $(LDFLAGS) + +test: $(PROGRAM) + set -e; for t in $(TESTS); do ./$$t; done + +clean: + $(RM) $(PROGRAM) $(OBJECTS) + +.PHONY: test clean diff --git a/test/postinstall/c_app/test_ldd.sh b/test/postinstall/c_app/test_ldd.sh new file mode 100755 index 00000000..9750db16 --- /dev/null +++ b/test/postinstall/c_app/test_ldd.sh @@ -0,0 +1,4 @@ +#!/bin/sh +. ../common.sh + +test_ldd c_app libproj diff --git a/test/postinstall/c_app/test_searchpath.sh b/test/postinstall/c_app/test_searchpath.sh new file mode 100755 index 00000000..0bd4feab --- /dev/null +++ b/test/postinstall/c_app/test_searchpath.sh @@ -0,0 +1,7 @@ +#!/bin/sh +. ../common.sh + +PROGRAM_SEARCHPATH="$(./c_app -s)" +EXPECTED_SEARCHPATH="$(pkg-config proj --variable=datadir)" + +test_searchpath "${PROGRAM_SEARCHPATH}" "${EXPECTED_SEARCHPATH}" diff --git a/test/postinstall/c_app/test_transform.sh b/test/postinstall/c_app/test_transform.sh new file mode 100755 index 00000000..cfcaa9c3 --- /dev/null +++ b/test/postinstall/c_app/test_transform.sh @@ -0,0 +1,6 @@ +#!/bin/sh +. ../common.sh + +PROGRAM_TRANSFORM="$(./c_app -t)" + +test_transform "${PROGRAM_TRANSFORM}" diff --git a/test/postinstall/c_app/test_version.sh b/test/postinstall/c_app/test_version.sh new file mode 100755 index 00000000..a1faacf5 --- /dev/null +++ b/test/postinstall/c_app/test_version.sh @@ -0,0 +1,7 @@ +#!/bin/sh +. ../common.sh + +PROGRAM_VERSION=$(./c_app -v) +EXPECTED_VERSION=$(pkg-config proj --modversion) + +test_version ${PROGRAM_VERSION} ${EXPECTED_VERSION} diff --git a/test/postinstall/common.cmake b/test/postinstall/common.cmake new file mode 100644 index 00000000..3a66444c --- /dev/null +++ b/test/postinstall/common.cmake @@ -0,0 +1,72 @@ +# Common CMake macros for post-install tests + +include(CTest) + +macro(add_test_ldd EXE) + set(EXEPATH ${CMAKE_BINARY_DIR}/${EXE}) + if(APPLE) + set(LDD_CL "otool -L") + set(EXPECTED_LDD_CL_OUT "@rpath/libproj") + elseif(UNIX) + set(LDD_CL "ldd") + set(EXPECTED_LDD_CL_OUT "${CMAKE_PREFIX_PATH}/lib/libproj") + elseif(CMAKE_GENERATOR STREQUAL "MSYS Makefiles") + set(LDD_CL "ldd") + # Convert to Unix-style path + execute_process( + COMMAND cygpath -u ${CMAKE_PREFIX_PATH}/bin/libproj + OUTPUT_VARIABLE EXPECTED_LDD_CL_OUT + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + if(LDD_CL) + add_test(NAME test_ldd + COMMAND sh -c "${LDD_CL} ${EXEPATH} | grep proj") + if($ENV{BUILD_MODE} STREQUAL "static") + set_tests_properties(test_ldd PROPERTIES + PASS_REGULAR_EXPRESSION "^$" + FAIL_REGULAR_EXPRESSION "${EXPECTED_LDD_CL_OUT};not found" + ) + else() + set_tests_properties(test_ldd PROPERTIES + PASS_REGULAR_EXPRESSION "${EXPECTED_LDD_CL_OUT}" + FAIL_REGULAR_EXPRESSION "not found" + ) + endif() + else() + add_test(NAME test_ldd COMMAND ${EXEPATH}) + set_tests_properties(test_ldd PROPERTIES SKIP_RETURN_CODE 1) + endif() +endmacro() + +macro(add_test_transform EXE) + set(EXEPATH ${CMAKE_BINARY_DIR}/${EXE}) + add_test(NAME test_transform COMMAND ${EXEPATH} -t) + set(EXPECTED +"easting: 691875.63, northing: 6098907.83, latitude: 55.00, longitude: 12.00") + set_tests_properties(test_transform PROPERTIES + PASS_REGULAR_EXPRESSION "${EXPECTED}" + ) +endmacro() + +macro(add_test_searchpath EXE) + set(EXEPATH ${CMAKE_BINARY_DIR}/${EXE}) + # data directory property not available, so recreate one + get_filename_component(EXPECTED_SEARCHPATH + "${${USE_PROJ_NAME}_DIR}/../../../share/proj" ABSOLUTE) + if(WIN32) + # Match each '/' with either '\' or '/' + string(REPLACE "/" "[\\/]" EXPECTED_SEARCHPATH "${EXPECTED_SEARCHPATH}") + endif() + add_test(NAME test_searchpath COMMAND ${EXEPATH} -s) + set_tests_properties(test_searchpath PROPERTIES + PASS_REGULAR_EXPRESSION "${EXPECTED_SEARCHPATH}" + ) +endmacro() + +macro(add_test_version EXE) + set(EXEPATH ${CMAKE_BINARY_DIR}/${EXE}) + add_test(NAME test_version COMMAND ${EXEPATH} -v) + set_tests_properties(test_version PROPERTIES + PASS_REGULAR_EXPRESSION "${${USE_PROJ_NAME}_VERSION}" + ) +endmacro() diff --git a/test/postinstall/common.sh b/test/postinstall/common.sh new file mode 100755 index 00000000..3bb5c080 --- /dev/null +++ b/test/postinstall/common.sh @@ -0,0 +1,135 @@ +#!/bin/sh + +# Common shell functions for post-install tests + +main_setup(){ + # usage: main_setup $1 $2 + export prefix=$1 + if [ -z "${prefix}" ]; then + echo "First positional argument to the the installed prefix is required" + exit 1 + fi + case $2 in + "" | shared) export BUILD_MODE=shared ;; + static) export BUILD_MODE=static ;; + *) + echo "Second argument must be either shared (default) or static" + exit 1 ;; + esac + + if [ ${BUILD_MODE} = shared ]; then + case $(uname) in + MINGW* | MSYS*) + prefix=$(cygpath -u ${prefix}) + export LD_LIBRARY_PATH=${prefix}/bin + ;; + Darwin*) + export DYLD_LIBRARY_PATH=${prefix}/lib + export LDFLAGS="${LDFLAGS} -Wl,-rpath,${prefix}/lib" + ;; + *) + export LD_LIBRARY_PATH=${prefix}/lib + ;; + esac + fi +} + +test_ldd(){ + # usage: test_ldd ${PROGRAM} ${LIBNAME} + # use optional 'BUILD_MODE=static' to to pass if LIBNAME is not found + if [ ! $(which ldd) ]; then + UNAME=$(uname) + case ${UNAME} in + Darwin*) alias ldd="otool -L" ;; + *) + echo "no ldd equivalent found for UNAME=${UNAME}" + return 77 ;; # skip + esac + fi + if [ -n "${LD_LIBRARY_PATH}" ]; then + EXPECTED_LDD_SUBSTR="${LD_LIBRARY_PATH}/$2" + elif [ -n "${DYLD_LIBRARY_PATH}" ]; then + EXPECTED_LDD_SUBSTR="${DYLD_LIBRARY_PATH}/$2" + else + EXPECTED_LDD_SUBSTR=$2 + fi + printf "Testing expected ldd output " + if [ "x${BUILD_MODE}" = xstatic ]; then + printf "not " + fi + printf "containing '${EXPECTED_LDD_SUBSTR}' ... " + LDD_OUTPUT=$(ldd ./$1 | grep "$3") + case "${LDD_OUTPUT}" in + *"not found"*) + echo "failed: ${LDD_OUTPUT}" + return 1 ;; + *${EXPECTED_LDD_SUBSTR}*) found=yes ;; + *) found=no ;; + esac + if [ "x${BUILD_MODE}" = xstatic ]; then + if [ "x${found}" = "xyes" ] ; then + echo "failed: ${LDD_OUTPUT}" + return 1 + fi + elif [ "x${found}" = "xno" ] ; then + echo "failed:" + ldd ./$1 + return 1 + fi + echo "passed" + return 0 +} + +test_transform(){ + # usage: test_transform ${PROGRAM_TRANSFORM} + printf "Testing transform ... " + EXPECTED="easting: 691875.63, northing: 6098907.83, latitude: 55.00, longitude: 12.00" + case "$1" in + "${EXPECTED}") + echo "passed" + return 0 ;; + *) + echo "failed, expected ${EXPECTED}, found $1" + return 1 ;; + esac +} + +test_searchpath(){ + # usage: test_searchpath ${PROGRAM_SEARCHPATH} ${EXPECTED_SEARCHPATH} + printf "Testing program searchpath '$1' ... " + PROGRAM_SEARCHPATH=$1 + UNAME=$(uname) + case ${UNAME} in + MINGW* | MSYS*) + PROGRAM_SEARCHPATH=$(echo "${PROGRAM_SEARCHPATH}" | tr '\\' '/') + esac + if [ -z $2 ]; then + echo "failed (empty expected)" + return 1 + fi + case ${PROGRAM_SEARCHPATH} in + *"$2"*) + echo "passed" + return 0 ;; + *) + echo "failed, expected '$2'" + return 1 ;; + esac +} + +test_version(){ + # usage: test_version ${PROGRAM_VERSION} ${EXPECTED_VERSION} + printf "Testing program version $1 ... " + if [ -z $2 ]; then + echo "failed (empty expected)" + return 1 + fi + case $1 in + $2*) + echo "passed" + return 0 ;; + *) + echo "failed, expected $2" + return 1 ;; + esac +} diff --git a/test/postinstall/cpp_app/CMakeLists.txt b/test/postinstall/cpp_app/CMakeLists.txt new file mode 100644 index 00000000..1f011082 --- /dev/null +++ b/test/postinstall/cpp_app/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.5) +project(CPP_APP LANGUAGES CXX) + +# Required for (e.g.) g++-4.8 +# can be refactored for CMake 3.22 +# https://github.com/OSGeo/PROJ/issues/1924 +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(USE_PROJ_NAME "PROJ" + CACHE STRING "Either PROJ (default) or PROJ4") + +find_package(${USE_PROJ_NAME} REQUIRED CONFIG) + +include(CMakePrintHelpers) +cmake_print_properties( + TARGETS ${USE_PROJ_NAME}::proj + PROPERTIES + LOCATION + INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_LINK_LIBRARIES + INTERFACE_COMPILE_FEATURES +) + +add_executable(cpp_app cpp_app.cpp) +target_link_libraries(cpp_app PRIVATE ${USE_PROJ_NAME}::proj) + +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/..) +include(common) +add_test_ldd(cpp_app) +add_test_transform(cpp_app) +add_test_searchpath(cpp_app) +add_test_version(cpp_app) diff --git a/test/postinstall/cpp_app/Makefile.am b/test/postinstall/cpp_app/Makefile.am new file mode 100644 index 00000000..5451403a --- /dev/null +++ b/test/postinstall/cpp_app/Makefile.am @@ -0,0 +1,9 @@ +bin_PROGRAMS = cpp_app +cpp_app_SOURCES = cpp_app.cpp +cpp_app_CXXFLAGS = $(PROJ_CFLAGS) +cpp_app_LDADD = $(PROJ_LIBS) +TESTS = \ + test_ldd.sh \ + test_transform.sh \ + test_searchpath.sh \ + test_version.sh diff --git a/test/postinstall/cpp_app/configure.ac b/test/postinstall/cpp_app/configure.ac new file mode 100644 index 00000000..7da902a8 --- /dev/null +++ b/test/postinstall/cpp_app/configure.ac @@ -0,0 +1,20 @@ +AC_INIT([cpp_app], [0.1]) +AM_INIT_AUTOMAKE +AC_PROG_CXX +dnl Required for (e.g.) g++-4.8 +AC_CONFIG_MACRO_DIR([../../../m4]) +AX_CXX_COMPILE_STDCXX_11([noext],[mandatory]) + +PKG_CHECK_MODULES([PROJ], [proj]) + +AC_ARG_ENABLE([static-proj], + AS_HELP_STRING([--enable-static-proj], + [Enable linking to static PROJ library])) + +# If enabled, force static linking for Linux +if test "x$enable_static_proj" = "xyes" -a "x$(uname)" = "xLinux"; then + PROJ_LIBS=$(echo "$PROJ_LIBS" | sed 's/-lproj/-Wl,-Bstatic -lproj -Wl,-Bdynamic/') +fi + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/test/postinstall/cpp_app/cpp_app.cpp b/test/postinstall/cpp_app/cpp_app.cpp new file mode 100644 index 00000000..9bcab2fb --- /dev/null +++ b/test/postinstall/cpp_app/cpp_app.cpp @@ -0,0 +1,45 @@ +#include <iostream> +#include <proj.h> + +int test_transform() { + PJ *P; + PJ_COORD a, b; + P = proj_create_crs_to_crs( + PJ_DEFAULT_CTX, + "EPSG:4326", + "+proj=utm +zone=32 +datum=WGS84", // or EPSG:32632 + NULL); + if (0 == P) { + std::cerr << "Oops" << std::endl; + return 1; + } + // Copenhagen: 55d N, 12d E + a = proj_coord(55, 12, 0, 0); + b = proj_trans(P, PJ_FWD, a); + std::cout.precision(2); + std::cout.setf( std::ios::fixed, std::ios::floatfield ); + std::cout << "easting: " << b.enu.e << ", northing: " << b.enu.n; + b = proj_trans(P, PJ_INV, b); + std::cout << ", latitude: " << b.lp.lam << ", longitude: " << b.lp.phi << std::endl; + proj_destroy(P); + return 0; +} + +int main(int argc, char *argv[]) { + PJ_INFO info; + info = proj_info(); + if(argc == 2 && argv[1][0] == '-') { + switch(argv[1][1]) { + case 't': + return(test_transform()); + case 's': + std::cout << info.searchpath << std::endl; + return(0); + case 'v': + std::cout << info.major << '.' << info.minor << '.' << info.patch << std::endl; + return(0); + } + } + std::cerr << "Use option -t, -s or -v" << std::endl; + return(1); +} diff --git a/test/postinstall/cpp_app/makefile.mak b/test/postinstall/cpp_app/makefile.mak new file mode 100644 index 00000000..8d84785f --- /dev/null +++ b/test/postinstall/cpp_app/makefile.mak @@ -0,0 +1,34 @@ +PROGRAM = cpp_app +OBJECTS = $(addsuffix .o,$(PROGRAM)) +TESTS = \ + test_ldd.sh \ + test_transform.sh \ + test_searchpath.sh \ + test_version.sh + +override CXXFLAGS += -std=c++11 -fvisibility=hidden -g -Wall -Werror $(shell pkg-config proj --cflags) + +ifeq ($(BUILD_MODE),static) + UNAME_S := $(shell uname -s) + _ldflags := $(shell pkg-config proj --libs --static) + ifeq ($(UNAME_S),Linux) + # force static linking to libproj + _ldflags := $(shell echo $(_ldflags) | sed 's/-lproj/-Wl,-Bstatic -lproj -Wl,-Bdynamic/') + endif + override LDFLAGS += $(_ldflags) +else # default is shared + override LDFLAGS += $(shell pkg-config proj --libs) +endif + +all: $(PROGRAM) + +$(PROGRAM): $(OBJECTS) + $(CXX) -o $@ $< $(LDFLAGS) + +test: $(PROGRAM) + set -e; for t in $(TESTS); do ./$$t; done + +clean: + $(RM) $(PROGRAM) $(OBJECTS) + +.PHONY: test clean diff --git a/test/postinstall/cpp_app/test_ldd.sh b/test/postinstall/cpp_app/test_ldd.sh new file mode 100755 index 00000000..2e8cd5ea --- /dev/null +++ b/test/postinstall/cpp_app/test_ldd.sh @@ -0,0 +1,4 @@ +#!/bin/sh +. ../common.sh + +test_ldd cpp_app libproj diff --git a/test/postinstall/cpp_app/test_searchpath.sh b/test/postinstall/cpp_app/test_searchpath.sh new file mode 100755 index 00000000..71ac1756 --- /dev/null +++ b/test/postinstall/cpp_app/test_searchpath.sh @@ -0,0 +1,7 @@ +#!/bin/sh +. ../common.sh + +PROGRAM_SEARCHPATH="$(./cpp_app -s)" +EXPECTED_SEARCHPATH="$(pkg-config proj --variable=datadir)" + +test_searchpath "${PROGRAM_SEARCHPATH}" "${EXPECTED_SEARCHPATH}" diff --git a/test/postinstall/cpp_app/test_transform.sh b/test/postinstall/cpp_app/test_transform.sh new file mode 100755 index 00000000..3f4e69ec --- /dev/null +++ b/test/postinstall/cpp_app/test_transform.sh @@ -0,0 +1,6 @@ +#!/bin/sh +. ../common.sh + +PROGRAM_TRANSFORM="$(./cpp_app -t)" + +test_transform "${PROGRAM_TRANSFORM}" diff --git a/test/postinstall/cpp_app/test_version.sh b/test/postinstall/cpp_app/test_version.sh new file mode 100755 index 00000000..d095aad8 --- /dev/null +++ b/test/postinstall/cpp_app/test_version.sh @@ -0,0 +1,7 @@ +#!/bin/sh +. ../common.sh + +PROGRAM_VERSION=$(./cpp_app -v) +EXPECTED_VERSION=$(pkg-config proj --modversion) + +test_version ${PROGRAM_VERSION} ${EXPECTED_VERSION} diff --git a/test/postinstall/test_autotools.sh b/test/postinstall/test_autotools.sh new file mode 100755 index 00000000..3e088fac --- /dev/null +++ b/test/postinstall/test_autotools.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# Post-install tests with autotools/pkg-config +# +# First required argument is the installed prefix, which +# is used to set PKG_CONFIG_PATH and +# LD_LIBRARY_PATH/DYLD_LIBRARY_PATH for shared builds +# Second argument is either shared (default) or static +cd $(dirname $0) +. ./common.sh +main_setup $1 $2 + +echo "Running post-install tests with autotools/pkg-config (${BUILD_MODE})" + +if [ ${BUILD_MODE} = shared ]; then + export PKG_CONFIG="pkg-config" + ENABLE_STATIC_PROJ=no +else + export PKG_CONFIG="pkg-config --static" + ENABLE_STATIC_PROJ=yes +fi +export PKG_CONFIG_PATH=${prefix}/lib/pkgconfig + +autogen_configure_check_clean(){ + set -e + aclocal + automake --add-missing --copy --foreign + autoconf + ./configure --enable-static-proj=${ENABLE_STATIC_PROJ} + make clean + make + set +e + make check + EXIT=$? + if [ ${EXIT} -ne 0 ]; then + cat test-suite.log + exit ${EXIT} + fi + make distclean +} + +echo "Testing C app" +cd c_app +autogen_configure_check_clean +cd .. + +echo "Testing C++ app" +cd cpp_app +autogen_configure_check_clean +cd .. + +echo "Finished running post-install tests with autotools/pkg-config (${BUILD_MODE})" diff --git a/test/postinstall/test_cmake.bat b/test/postinstall/test_cmake.bat index 8eba4e78..9576a4e9 100755 --- a/test/postinstall/test_cmake.bat +++ b/test/postinstall/test_cmake.bat @@ -3,42 +3,76 @@ :: :: First required argument is the installed prefix, which :: is used to set CMAKE_PREFIX_PATH +:: Second argument is either shared (default) or static +:: Additionally, several environment variable are required +:: - CMAKE_GENERATOR - (e.g.) Ninja +:: - VCPKG_ROOT - (e.g.) C:\Tools\vcpkg +:: - platform - x64 or x86 -echo Running post-install tests with CMake +If not defined CMAKE_GENERATOR ( + Echo CMAKE_GENERATOR must be set 1>&2 + Exit /B 1 +) +If not defined VCPKG_ROOT ( + Echo VCPKG_ROOT not defined for Vcpkg 1>&2 + Exit /B 1 +) +Set VCPKG_INSTALLED=%VCPKG_ROOT%\installed\%platform%-windows -set CMAKE_PREFIX_PATH=%1 -if not defined CMAKE_PREFIX_PATH ( - echo First positional argument CMAKE_PREFIX_PATH required - exit /B 1 +Set CMAKE_PREFIX_PATH=%1 +If not defined CMAKE_PREFIX_PATH ( + Echo First positional argument CMAKE_PREFIX_PATH required 1>&2 + Exit /B 1 +) +Set BUILD_MODE=%2 +If not defined BUILD_MODE ( + Set BUILD_MODE=shared +) +Set _ValidBuildMode=0 +If %BUILD_MODE% EQU shared ( + Set _ValidBuildMode=1 + Setlocal EnableDelayedExpansion + Set PATH=!CMAKE_PREFIX_PATH!\bin;!VCPKG_INSTALLED!\bin;!PATH! + Setlocal DisableDelayedExpansion +) +If %BUILD_MODE% EQU static Set _ValidBuildMode=1 +If %_ValidBuildMode% NEQ 1 ( + Echo Second argument must be either shared ^(default^) or static 1>&2 + Exit /B 1 ) -echo CMAKE_PREFIX_PATH=%CMAKE_PREFIX_PATH% +Echo Running post-install tests with CMake (%BUILD_MODE%) -cd %~dp0 +Set _InitDir=%~dp0 +Cd %_InitDir% -cd testappprojinfo -del /f /q build 2> nul +Echo Testing C app +Cd c_app +Call :cmake_build_ctest PROJ || (Cd %_InitDir% & Exit /B 1) +Call :cmake_build_ctest PROJ4 || (Cd %_InitDir% & Exit /B 1) +Cd .. -:: Check CMake project name PROJ -md build -cd build -cmake -GNinja -DCMAKE_BUILD_TYPE=Release ^ - -DCMAKE_PREFIX_PATH=%CMAKE_PREFIX_PATH% ^ - -DUSE_PROJ_NAME=PROJ .. || exit /B 2 -ninja -v || exit /B 3 -ctest -VV || exit /B 4 -cd .. -del /f /q build - -:: Check legacy CMake project name PROJ4 -md build -cd build -cmake -GNinja -DCMAKE_BUILD_TYPE=Release ^ +Echo Testing C++ app +Cd cpp_app +Call :cmake_build_ctest PROJ || (Cd %_InitDir% & Exit /B 1) +Call :cmake_build_ctest PROJ4 || (Cd %_InitDir% & Exit /B 1) +Cd .. + +Echo Finished running post-install tests CMake (%BUILD_MODE%) +Goto :EOF + +:cmake_build_ctest +If exist build Rd /s /q build || Exit /B 1 +Md build +Cd build + +cmake -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%\scripts\buildsystems\vcpkg.cmake ^ -DCMAKE_PREFIX_PATH=%CMAKE_PREFIX_PATH% ^ - -DUSE_PROJ_NAME=PROJ4 .. || exit /B 2 -ninja -v || exit /B 3 -ctest -VV || exit /B 4 -cd .. -del /f /q build + -DUSE_PROJ_NAME=%1 .. || Exit /B 1 + +cmake --build . --config Release || Exit /B 1 +ctest --output-on-failure -V -C Release || Exit /B 1 -cd .. +Cd .. +Rd /s /q build diff --git a/test/postinstall/test_cmake.sh b/test/postinstall/test_cmake.sh index e72af7c7..b95b0c02 100755 --- a/test/postinstall/test_cmake.sh +++ b/test/postinstall/test_cmake.sh @@ -1,43 +1,40 @@ -#!/bin/sh +#!/bin/sh -e # Post-install tests with CMake # # First required argument is the installed prefix, which -# is used to set CMAKE_PREFIX_PATH - -set -e - -echo "Running post-install tests with CMake" +# is used to set CMAKE_PREFIX_PATH and +# LD_LIBRARY_PATH/DYLD_LIBRARY_PATH for shared builds +# Second argument is either shared (default) or static +cd $(dirname $0) +. ./common.sh +main_setup $1 $2 -CMAKE_PREFIX_PATH=$1 -if [ -z "$CMAKE_PREFIX_PATH" ]; then - echo "First positional argument CMAKE_PREFIX_PATH required" - exit 1 -fi +echo "Running post-install tests with CMake (${BUILD_MODE})" -echo "CMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH" +cmake_make_ctest(){ + rm -rf build + mkdir build + cd build -cd $(dirname $0) + cmake -DCMAKE_PREFIX_PATH=${prefix} -DUSE_PROJ_NAME=$1 .. + VERBOSE=1 make + ctest --output-on-failure -V -cd testappprojinfo -rm -rf build + cd .. + rm -rf build +} -# Check CMake project name PROJ -mkdir build -cd build -cmake -DCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH -DUSE_PROJ_NAME=PROJ -DCMAKE_VERBOSE_MAKEFILE=ON .. -cmake --build . -ctest -VV . -cd .. -rm -rf build - -# Check legacy CMake project name PROJ4 -mkdir build -cd build -cmake -DCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH -DUSE_PROJ_NAME=PROJ4 -DCMAKE_VERBOSE_MAKEFILE=ON .. -cmake --build . -ctest -VV . +echo "Testing C app" +cd c_app +cmake_make_ctest PROJ +cmake_make_ctest PROJ4 cd .. -rm -rf build +echo "Testing C++ app" +cd cpp_app +cmake_make_ctest PROJ +cmake_make_ctest PROJ4 cd .. + +echo "Finished running post-install tests CMake (${BUILD_MODE})" diff --git a/test/postinstall/test_pkg-config.sh b/test/postinstall/test_pkg-config.sh index 619d66b0..c417f99d 100755 --- a/test/postinstall/test_pkg-config.sh +++ b/test/postinstall/test_pkg-config.sh @@ -1,95 +1,35 @@ #!/bin/sh -# Post-install tests with pkg-config +# Post-install tests with pkg-config and a Makefile # # First required argument is the installed prefix, which -# is used to set PKG_CONFIG_PATH and LD_LIBRARY_PATH - -set -e - -echo "Running post-install tests with pkg-config" - -prefix=$1 -if [ -z "$prefix" ]; then - echo "First positional argument to the installed prefix is required" - exit 1 -fi - -export LD_LIBRARY_PATH=$prefix/lib - -UNAME=$(uname) -case $UNAME in - Darwin*) - alias ldd="otool -L" ;; - Linux*) - ;; - MINGW* | MSYS*) - prefix=$(cygpath -u ${prefix}) - export LD_LIBRARY_PATH=$prefix/bin ;; - *) - echo "no ldd equivalent found for UNAME=$UNAME" - exit 1 ;; -esac - -export PKG_CONFIG_PATH=$prefix/lib/pkgconfig -echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" - -PKG_CONFIG_MODVERSION=$(pkg-config proj --modversion) -echo "pkg-config proj --modversion: $PKG_CONFIG_MODVERSION" -PKG_CONFIG_DATADIR=$(pkg-config proj --variable=datadir) -echo "pkg-config proj --variable=datadir: $PKG_CONFIG_DATADIR" - +# is used to set PKG_CONFIG_PATH and +# LD_LIBRARY_PATH/DYLD_LIBRARY_PATH for shared builds +# Second argument is either shared (default) or static cd $(dirname $0) +. ./common.sh +main_setup $1 $2 -PROGRAM=testappprojinfo -cd $PROGRAM -make - -# Run tests from shell, count any errors -ERRORS=0 +echo "Running post-install tests with pkg-config (${BUILD_MODE})" -LDD_OUTPUT=$(ldd ./$PROGRAM | grep proj) -LDD_SUBSTR=$LD_LIBRARY_PATH/libproj -LDD_RPATH_SUBSTR=@rpath/libproj -printf "Testing expected ldd output ... " -case "$LDD_OUTPUT" in - *$LDD_SUBSTR*) - echo "passed (using path)" ;; - *$LDD_RPATH_SUBSTR*) - echo "passed (using rpath)" ;; - *) - ERRORS=$(($ERRORS + 1)) - echo "failed: ldd output '$LDD_OUTPUT' does not contain '$LDD_SUBSTR'" ;; -esac +export PKG_CONFIG_PATH=${prefix}/lib/pkgconfig -SEARCHPATH_OUTPUT=$(./$PROGRAM -s) -case $UNAME in - MINGW* | MSYS*) - SEARCHPATH_OUTPUT=$(echo "$SEARCHPATH_OUTPUT" | tr '\\' '/') -esac -printf "Testing expected searchpath/datadir ... " -case "$SEARCHPATH_OUTPUT" in - *$PKG_CONFIG_DATADIR*) - echo "passed" ;; - *) - ERRORS=$(($ERRORS + 1)) - echo "failed: searchpath '$SEARCHPATH_OUTPUT' does not contain '$PKG_CONFIG_DATADIR'" ;; -esac - -VERSION_OUTPUT=$(./$PROGRAM -v) -printf "Testing expected version ... " -case "$VERSION_OUTPUT" in - $PKG_CONFIG_MODVERSION) - echo "passed" ;; - *) - ERRORS=$(($ERRORS + 1)) - echo "failed: '$VERSION_OUTPUT' != '$PKG_CONFIG_MODVERSION'" ;; -esac - -make clean +make_all_test_clean(){ + set -e + make -f makefile.mak clean + make -f makefile.mak all + make -f makefile.mak test + make -f makefile.mak clean +} +echo "Testing C app" +cd c_app +make_all_test_clean cd .. -(cd testcpp && make && make clean) +echo "Testing C++ app" +cd cpp_app +make_all_test_clean +cd .. -exit $ERRORS +echo "Finished running post-install tests with pkg-config (${BUILD_MODE})" diff --git a/test/postinstall/testappprojinfo/CMakeLists.txt b/test/postinstall/testappprojinfo/CMakeLists.txt deleted file mode 100644 index 2b3cf70e..00000000 --- a/test/postinstall/testappprojinfo/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(testappprojinfo LANGUAGES C) - -set(USE_PROJ_NAME "PROJ" - CACHE STRING "Either PROJ (default) or PROJ4") - -find_package(${USE_PROJ_NAME}) - -# Show some target properties -get_cmake_property(_variableNames VARIABLES) -list(SORT _variableNames) -foreach(_variableName ${_variableNames}) - string(REGEX MATCH "^${USE_PROJ_NAME}_" _matched ${_variableName}) - if(NOT ${_matched} STREQUAL "") - message(STATUS "${_variableName}=${${_variableName}}") - endif() -endforeach() - -add_executable(testappprojinfo testappprojinfo.c) -target_link_libraries(testappprojinfo PRIVATE ${${USE_PROJ_NAME}_LIBRARIES}) - -include(CTest) - -if(APPLE) - set(LDD_CL "otool -L") - set(EXPECTED_LDD_CL_OUT "@rpath/libproj") -elseif(UNIX) - set(LDD_CL "ldd") - set(EXPECTED_LDD_CL_OUT "${CMAKE_PREFIX_PATH}/lib/libproj") -elseif(CMAKE_GENERATOR STREQUAL "MSYS Makefiles") - set(LDD_CL "ldd") - # Convert to Unix-style path - execute_process( - COMMAND cygpath -u ${CMAKE_PREFIX_PATH}/bin/libproj - OUTPUT_VARIABLE EXPECTED_LDD_CL_OUT - OUTPUT_STRIP_TRAILING_WHITESPACE) -endif() - -if(LDD_CL) - add_test(NAME test_ldd - COMMAND sh -c "${LDD_CL} ${CMAKE_BINARY_DIR}/testappprojinfo | grep proj") - set_tests_properties(test_ldd PROPERTIES - PASS_REGULAR_EXPRESSION ${EXPECTED_LDD_CL_OUT} - ) -else() - add_test(NAME test_ldd COMMAND testappprojinfo) - set_tests_properties(test_ldd PROPERTIES SKIP_RETURN_CODE 1) -endif() - -# data directory property not available, so recreate one -get_filename_component(EXPECTED_DATADIR - "${${USE_PROJ_NAME}_DIR}/../../../share/proj" ABSOLUTE) -if(WIN32) - # Match each '/' with either '\' or '/' - string(REPLACE "/" "[\\/]" EXPECTED_DATADIR ${EXPECTED_DATADIR}) -endif() -add_test(NAME test_searchpath COMMAND testappprojinfo -s) -set_tests_properties(test_searchpath PROPERTIES - PASS_REGULAR_EXPRESSION "${EXPECTED_DATADIR}" -) - -add_test(NAME test_version COMMAND testappprojinfo -v) -set_tests_properties(test_version PROPERTIES - PASS_REGULAR_EXPRESSION "${${USE_PROJ_NAME}_VERSION}" -) diff --git a/test/postinstall/testappprojinfo/Makefile b/test/postinstall/testappprojinfo/Makefile deleted file mode 100644 index 98c47f28..00000000 --- a/test/postinstall/testappprojinfo/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -PROGRAM = testappprojinfo -OBJECTS = $(addsuffix .o,$(PROGRAM)) - -override CFLAGS += -g -Wall -Werror $(shell pkg-config proj --cflags) -override LDFLAGS += $(shell pkg-config proj --libs) - -all: $(PROGRAM) - -$(PROGRAM): $(OBJECTS) - $(CC) -o $@ $< $(LDFLAGS) - -clean: - $(RM) $(PROGRAM) $(OBJECTS) - -.PHONY: clean diff --git a/test/postinstall/testappprojinfo/testappprojinfo.c b/test/postinstall/testappprojinfo/testappprojinfo.c deleted file mode 100644 index 64b5d665..00000000 --- a/test/postinstall/testappprojinfo/testappprojinfo.c +++ /dev/null @@ -1,19 +0,0 @@ -#include <stdio.h> -#include <proj.h> - -int main(int argc, char *argv[]) { - PJ_INFO info; - info = proj_info(); - if(argc == 2 && argv[1][0] == '-') { - switch(argv[1][1]) { - case 's': - printf("%s\n", info.searchpath); - return(0); - case 'v': - printf("%d.%d.%d\n", info.major, info.minor, info.patch); - return(0); - } - } - printf("Use option -v or -s\n"); - return(1); -} diff --git a/test/postinstall/testcpp/Makefile b/test/postinstall/testcpp/Makefile deleted file mode 100644 index d6c47e65..00000000 --- a/test/postinstall/testcpp/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -PROGRAM = testcpp -OBJECTS = $(addsuffix .o,$(PROGRAM)) - -override CXXFLAGS += -std=c++11 -fvisibility=hidden -g -Wall -Werror $(shell pkg-config proj --cflags) -override LDFLAGS += $(shell pkg-config proj --libs) - -all: $(PROGRAM) - -$(PROGRAM): $(OBJECTS) - $(CXX) -o $@ $< $(LDFLAGS) - -clean: - $(RM) $(PROGRAM) $(OBJECTS) - -.PHONY: clean diff --git a/test/postinstall/testcpp/testcpp.cpp b/test/postinstall/testcpp/testcpp.cpp deleted file mode 100644 index a03ca0ee..00000000 --- a/test/postinstall/testcpp/testcpp.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include <proj/io.hpp> -#include <proj/crs.hpp> -#include <proj/coordinateoperation.hpp> -#include <proj/coordinatesystem.hpp> -#include <proj/datum.hpp> - -int main(int /*argc */, char** /* argv */) -{ - return 0; -} |
