Commit 008df693cf5a71b8f1db87731a7b5af87400e5dd

Silvio Traversaro 2020-11-26T11:16:05

Merge pull request #85 from rhabacker/cmake-wine-support Add support to use wine to run cross compiled tests for cmake

diff --git a/.travis.yml b/.travis.yml
index 3205fa9..4df8ce7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,8 +9,11 @@ addons:
     packages:
       - gcc-mingw-w64
       - wine
+      - cmake
+
+env:
+  - ci_buildsys=cmake
+  - ci_buildsys=Makefile
 
 script:
-  - ./configure --enable-shared --enable-static --enable-wine --cross-prefix=${CC%-*}-
-  - make
-  - make test
+  - ci_target=${CC%-*} ./tools/ci-build.sh
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 17d3fc4..2202c93 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,11 +6,41 @@ endif ()
 
 project (dlfcn-win32 C)
 
+list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")
+include(Macros)
+
 option(BUILD_SHARED_LIBS "shared/static libs" ON) 
 option(BUILD_TESTS "tests?" OFF)
 
+if(WIN32 AND NOT CMAKE_HOST_WIN32 AND CMAKE_CROSSCOMPILING AND BUILD_TESTS)
+    add_auto_option(ENABLE_WINE "Enable running tests with wine" AUTO)
+    find_program(WINE_EXECUTABLE wine)
+    check_auto_option(ENABLE_WINE "wine support" WINE_EXECUTABLE "wine executable")
+    if(ENABLE_WINE AND WINE_EXECUTABLE)
+        set(WRAPPER ${WINE_EXECUTABLE})
+        set(RUN_TESTS 1)
+        message(STATUS "Support to run cross compiled tests - enabled")
+    endif()
+elseif(BUILD_TESTS)
+    set(RUN_TESTS 1)
+endif()
+
+if(RUN_TESTS)
+    enable_testing()
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+if (MSVC)
+    add_compile_options(/W4)
+else()
+    add_compile_options(-Wall)
+endif()
+
 add_subdirectory(src)
 
 if (BUILD_TESTS)
-  add_subdirectory(tests)
+    add_subdirectory(tests)
 endif()
diff --git a/cmake/modules/Macros.cmake b/cmake/modules/Macros.cmake
new file mode 100644
index 0000000..fa0f1fc
--- /dev/null
+++ b/cmake/modules/Macros.cmake
@@ -0,0 +1,32 @@
+#
+# provide option with three states AUTO, ON, OFF
+#
+macro(add_auto_option _name _text _default)
+    if(NOT DEFINED ${_name})
+        set(${_name} ${_default} CACHE STRING "${_text}" FORCE)
+    else()
+        set(${_name} ${_default} CACHE STRING "${_text}")
+    endif()
+    set_property(CACHE ${_name} PROPERTY STRINGS AUTO ON OFF)
+endmacro()
+
+#
+# Ensure that if a tristate ON/OFF/AUTO feature is set to ON,
+# its requirements have been met. Fail with a fatal error if not.
+#
+# _name: name of a variable ENABLE_FOO representing a tristate ON/OFF/AUTO feature
+# _text: human-readable description of the feature enabled by _name, for the
+#        error message
+# _var: name of a variable representing a system property we checked for,
+#       such as an executable that must exist for the feature enabled by _name to work
+# _vartext: what we checked for, for the error message
+#
+macro(check_auto_option _name _text _var _vartext)
+    set(_nameval ${${_name}})
+    set(_varval ${${_var}})
+    #message("debug: _name ${_name} ${_nameval}  _var ${_var} ${_varval}")
+    if(_nameval AND NOT _nameval STREQUAL "AUTO" AND NOT _varval)
+        message(FATAL_ERROR "${_text} requested but ${_vartext} not found")
+    endif()
+endmacro()
+
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 64f85f7..5fc6c44 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,12 +1,17 @@
-enable_testing()
 include_directories(../src)
+
 add_library(testdll SHARED testdll.c)
 set_target_properties(testdll PROPERTIES PREFIX "")
+
 add_library(testdll2 SHARED testdll2.c)
 set_target_properties(testdll2 PROPERTIES PREFIX "")
 target_link_libraries(testdll2 dl)
+
 add_library(testdll3 SHARED testdll3.c)
 set_target_properties(testdll3 PROPERTIES PREFIX "")
+
 add_executable(t_dlfcn test.c)
 target_link_libraries(t_dlfcn dl)
-add_test (NAME t_dlfcn COMMAND t_dlfcn)
+if(RUN_TESTS)
+    add_test(NAME t_dlfcn COMMAND ${WRAPPER} $<TARGET_FILE:t_dlfcn> WORKING_DIRECTORY $<TARGET_FILE_DIR:t_dlfcn>)
+endif()
diff --git a/tools/ci-build.sh b/tools/ci-build.sh
new file mode 100755
index 0000000..a7d79b1
--- /dev/null
+++ b/tools/ci-build.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+set -euo pipefail
+set -x
+
+# ci_buildsys:
+# Build system under test: Makefile or cmake
+: "${ci_buildsys:=cmake}"
+
+# ci_target:
+# target to build for
+: "${ci_target:=${CROSS_COMPILE%-}}"
+
+install_prefix=$(${ci_target}-gcc --print-sysroot)/${ci_target}
+
+case "$ci_buildsys" in
+    (Makefile)
+        ./configure --enable-shared --enable-static --enable-wine --cross-prefix=${ci_target}-
+        make
+        make test
+        ;;
+
+    (cmake)
+        cmake --version
+        rm -rf build
+        mkdir build
+        cd build
+        cmake \
+            --no-warn-unused-cli                         \
+            -DCMAKE_FIND_ROOT_PATH=$install_prefix       \
+            -DCMAKE_BUILD_TYPE=RelWithDebInfo            \
+            -DCMAKE_C_COMPILER=$(which ${ci_target}-gcc) \
+            -DCMAKE_SYSTEM_PROCESSOR=${ci_target%-*-*}   \
+            -DCMAKE_CROSSCOMPILING=TRUE                  \
+            -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER    \
+            -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY     \
+            -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY     \
+            -DCMAKE_SYSTEM_NAME=Windows                  \
+            -DBUILD_TESTS=1                              \
+            -DENABLE_WINE=ON                             \
+            -DWINE_EXECUTABLE=/usr/bin/wine              \
+            ..
+        make
+        ctest --output-on-failure
+        make install DESTDIR=$(pwd)/DESTDIR
+        ;;
+esac
+
+# vim:set sw=4 sts=4 et: