I wonder if there is a better solution to my problem. I am working on a platform independent software project and want to add python-based unittests to cmake. The issue that I encountered now is that when configuring the ctest tests and setting up the correct PYTHONPATH environment variable for running my test, I end up with a lot of boilerplate code for each test:
add_test(my_awesome_test ${PYTHON_EXECUTABLE} my_awesome_test.py)
if("${CMAKE_HOST_SYSTEM}" MATCHES ".*Windows.*")
set_tests_properties(my_awesome_test PROPERTIES ENVIRONMENT "PYTHONPATH=somepath\;anotherpath")
else() # e.g. Linux
set_tests_properties(my_awesome_test PROPERTIES ENVIRONMENT "PYTHONPATH=somepath:anotherpath")
endif()
# more tests like this after this...
The problem here is the branching, that is required only because of the platform dependent list separators.
Is there some neater way to accomplish this?
Is there a constant which specifies the platform separator or a function that allows me to construct these lists?
If there is no "proper" answer, I also wanted to share my obvious, but not-so-nice solution:
if("${CMAKE_HOST_SYSTEM}" MATCHES ".*Windows.*")
set(SEP "\\;")
else() # e.g. Linux
set(SEP ":")
endif()
add_test(my_awesome_test ${PYTHON_EXECUTABLE} my_awesome_test.py)
set_tests_properties(my_awesome_test PROPERTIES ENVIRONMENT "PYTHONPATH=somepath${SEP}anotherpath")
# more tests like this after this...
On Windows the ";" must be double escaped because otherwise it it is substituted later in the add_test line as a single ";" again, which is then in turn interpreted as the cmake-list separator leading to wrong results. However, having cmake report which character should be used as list separator would still be nicer...
Unfortunately file(TO_NATIVE_PATH ...
does not convert ;
to :
on Unix platforms. I think the easiest way is therefore something like this:
set(PATH "/usr/bin" "/bin")
if (UNIX)
string(REPLACE ";" ":" PATH "${PATH}")
endif()
This works because CMake lists are really ;
-separated strings, so on Windows you can use them for path lists as-is. It won't work for paths containing ;
or :
but that will trip up 99% of Unix software anyway so I wouldn't worry about it.
You can use the file function as follow:
file(TO_CMAKE_PATH "<path>" <variable>)
file(TO_NATIVE_PATH "<path>" <variable>)
https://cmake.org/cmake/help/v3.9/command/file.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With