Skip to content

Instantly share code, notes, and snippets.

@scivision
Last active Oct 25, 2021
Embed
What would you like to do?
append to PATH env var on Windows for CTest
# works for Unix, Windows, etc.
cmake_minimum_required(VERSION 3.20)
project(WindowsPath LANGUAGES C)
find_library(ZLIB REQUIRED)
include(dll_path.cmake)
add_executable(hello hello.c)
target_link_libraries(hello PRIVATE ZLIB::ZLIB)
add_test(NAME unit_hello COMMAND $<TARGET_FILE:hello>)
if(test_dll_path)
set_tests_properties(unit_hello PROPERTIES ENVIRONMENT "PATH=${test_dll_path}")
endif()
# special handling since both Windows PATH and CMake lists are delimited by semicolon
if(NOT WIN32)
# Unix uses LD_LIBRARY_PATH or similar instead
return()
endif()
set(test_dll_path)
# we use ZLib as an example, and assume you've already `find_package(ZLIB)` before this
find_path(ZLIB_DLL NAMES zlib.dll
NO_DEFAULT_PATH
HINTS ${ZLIB_INCLUDE_DIR}/.. ${ZLIB_ROOT} ENV ZLIB_ROOT
PATH_SUFFIXES bin
DOC "path to DLL")
if(ZLIB_DLL)
list(APPEND test_dll_path ${ZLIB_DLL})
endif()
cmake_path(APPEND_STRING test_dll_path ";$ENV{PATH}")
cmake_path(CONVERT "${test_dll_path}" TO_NATIVE_PATH_LIST test_dll_path NORMALIZE)
# this is the vital line, without it CMake set_tests_properties mangles the ENVIRONMENT
string(REPLACE ";" "\\;" test_dll_path "${test_dll_path}")
message(DEBUG "test_dll_path: ${test_dll_path}")
#include "zlib.h"
int main(void) { return 0; }
@scivision
Copy link
Author

scivision commented Oct 25, 2021

Should instead set:

set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/lib)
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)

and then copy DLLs for Windows with

add_custom_command(TARGET test_minimal POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:test_minimal> $<TARGET_FILE_DIR:test_minimal>
COMMAND_EXPAND_LISTS
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment