Merge remote-tracking branch 'public/pr/1470' into mbedtls-2.7
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2018d35..587cfe2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,6 +56,30 @@
     CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
     FORCE)
 
+# Create a symbolic link from ${base_name} in the binary directory
+# to the corresponding path in the source directory.
+function(link_to_source base_name)
+    # Get OS dependent path to use in `execute_process`
+    file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${base_name}" link)
+    file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${base_name}" target)
+
+    if (NOT EXISTS ${link})
+        if (CMAKE_HOST_UNIX)
+            set(command ln -s ${target} ${link})
+        else()
+            set(command cmd.exe /c mklink /j ${link} ${target})
+        endif()
+
+        execute_process(COMMAND ${command}
+            RESULT_VARIABLE result
+            ERROR_VARIABLE output)
+
+        if (NOT ${result} EQUAL 0)
+            message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
+        endif()
+    endif()
+endfunction(link_to_source)
+
 string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
 
 if(CMAKE_COMPILER_IS_GNUCC)
@@ -164,3 +188,12 @@
         )
     endif(UNIX)
 endif()
+
+# Make scripts needed for testing available in an out-of-source build.
+if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
+    link_to_source(scripts)
+    # Copy (don't link) DartConfiguration.tcl, needed for memcheck, to
+    # keep things simple with the sed commands in the memcheck target.
+    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DartConfiguration.tcl
+                   ${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
+endif()
diff --git a/ChangeLog b/ChangeLog
index 124bd67..29c90f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,9 @@
    * Fix redundant declaration of mbedtls_ssl_list_ciphersuites. Raised by
      TrinityTonic. #1359.
 
+Changes
+   * Support TLS testing in out-of-source builds using cmake. Fixes #1193.
+
 = mbed TLS 2.7.3 branch released 2018-04-30
 
 Security
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 985a353..1b581a5 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -9,3 +9,8 @@
         PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
 
 endif(INSTALL_MBEDTLS_HEADERS)
+
+# Make config.h available in an out-of-source build. ssl-opt.sh requires it.
+if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
+    link_to_source(mbedtls)
+endif()
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 16e19a9..9fd4916 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -105,26 +105,11 @@
 add_test_suite(x509parse)
 add_test_suite(x509write)
 
-# Make data_files available in an out-of-source build
+# Make scripts and data files needed for testing available in an
+# out-of-source build.
 if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
-    # Get OS dependent path to use in `execute_process`
-    file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/data_files" link)
-    file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/data_files" target)
-
-    if (NOT EXISTS ${link})
-        if (CMAKE_HOST_UNIX)
-            set(command ln -s ${target} ${link})
-        else()
-            set(command cmd.exe /c mklink /j ${link} ${target})
-        endif()
-
-        execute_process(COMMAND ${command}
-                        RESULT_VARIABLE result
-                        ERROR_VARIABLE output)
-
-        if (NOT ${result} EQUAL 0)
-            message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
-        endif()
-    endif()
+    link_to_source(compat.sh)
+    link_to_source(data_files)
+    link_to_source(scripts)
+    link_to_source(ssl-opt.sh)
 endif()
-
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index c64c9c0..aa466e8 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -150,9 +150,19 @@
 # remove built files as well as the cmake cache/config
 cleanup()
 {
+    if [ -n "${MBEDTLS_ROOT_DIR+set}" ]; then
+        cd "$MBEDTLS_ROOT_DIR"
+    fi
+
     command make clean
 
-    find . -name yotta -prune -o -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} \+
+    # Remove CMake artefacts
+    find . -name .git -prune -o -name yotta -prune -o \
+           -iname CMakeFiles -exec rm -rf {} \+ -o \
+           \( -iname cmake_install.cmake -o \
+              -iname CTestTestfile.cmake -o \
+              -iname CMakeCache.txt \) -exec rm {} \+
+    # Recover files overwritten by in-tree CMake builds
     rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile
     git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile
     git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile
@@ -831,8 +841,20 @@
 
 msg "test: cmake 'out-of-source' build"
 make test
+# Test an SSL option that requires an auxiliary script in test/scripts/.
+# Also ensure that there are no error messages such as
+# "No such file or directory", which would indicate that some required
+# file is missing (ssl-opt.sh tolerates the absence of some files so
+# may exit with status 0 but emit errors).
+if_build_succeeded ./tests/ssl-opt.sh -f 'Fallback SCSV: beginning of list' 2>ssl-opt.err
+if [ -s ssl-opt.err ]; then
+  cat ssl-opt.err >&2
+  record_status [ ! -s ssl-opt.err ]
+  rm ssl-opt.err
+fi
 cd "$MBEDTLS_ROOT_DIR"
 rm -rf "$OUT_OF_SOURCE_DIR"
+unset MBEDTLS_ROOT_DIR