How to put regex string as compiler option

I want to write a simple function in CMake:

function(add_my_compiler_options target_name regexes)
  if(NOT "${regexes}" STREQUAL "")
    target_compile_options(${target_name}
      PRIVATE
         "-fprofile-filter-files=${regexes}"
    )
  endif()
endfunction()

And I want to call it like this:

set(regexes [=[^.*first\.(h|cpp)$;^.*second\.(h|cpp)$]=])
add_my_compiler_options(${regexes})

How to fix this function to get this compiler command line?:

compiler -fprofile-filter-files="^.*first\.(h|cpp)$;^.*second\.(h|cpp)$"

The regexes variable contains a semicolon (;), so CMake interprets it as a list.

When calling add_my_compiler_options, regexes will be expanded as 2 arguments. To prevent that, you need to quote it:

add_my_compiler_options(${target_name} "${regexes}")

Then, target_compile_options will also treat any argument that contains semicolons as a list of compiler options. So you need to escape semicolons in regexes before using it:

  if(NOT "${regexes}" STREQUAL "")
    string(REPLACE ";" "\;" regexes "${regexes}")
    target_compile_options(${target_name}
      PRIVATE
         "-fprofile-filter-files=${regexes}"
    )
  endif()

I hope this helps!

Thank you for answer!
Problem with backslash still exist… CMake converts symbols \. to .. How to fix this?
Second problem with $.

There is full example:

cmake_minimum_required(VERSION 3.16)

set(CMAKE_CXX_STANDARD 17)

project(Test)

add_executable(test_exe test_exe.cpp)

function(add_my_compiler_options target_name regexes)
  message(STATUS "ARGV:${ARGV}")
  message(STATUS "regexes1:${regexes}")
  if(NOT "${regexes}" STREQUAL "")
    string(REPLACE ";" "\;" regexes "${regexes}")
    message(STATUS "regexes2:${regexes}")
    target_compile_options(${target_name}
      PRIVATE
         "-###"
         "--coverage"
         "-fprofile-filter-files=${regexes}"
    )
  endif()
endfunction()

set(regexes
    [=[^.*first\.(h|cpp)$]=]
    [=[^.*second\.(h|cpp)$]=]
)
add_my_compiler_options(test_exe "${regexes}")

Generation command:

cmake -G"Visual Studio 16 2019" -A x64 -T"LLVM" ..

There are properties in VS:

There is test output (VS 2017):

1>------ Build started: Project: ZERO_CHECK, Configuration: Debug x64 ------
1>Checking Build System
1>CMake is re-running because D:/libs/test/test_regexs/build/CMakeFiles/generate.stamp is out-of-date.
1>  the file 'D:/libs/test/test_regexs/CMakeLists.txt'
1>  is newer than 'D:/libs/test/test_regexs/build/CMakeFiles/generate.stamp.depend'
1>  result='-1'
1>-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.18363.
1>-- ARGV:test_exe;^.*first\.(h|cpp)$;^.*second\.(h|cpp)$
1>-- regexes1:^.*first\.(h|cpp)$;^.*second\.(h|cpp)$
1>-- regexes2:^.*first\.(h|cpp)$\;^.*second\.(h|cpp)$
1>-- Configuring done
1>-- Generating done
1>-- Build files have been written to: D:/libs/test/test_regexs/build
2>------ Build started: Project: test_exe, Configuration: Debug x64 ------
2>clang version 9.0.0 (https://github.com/llvm/llvm-project.git 150ad3120e346ed8dff2bdda458a72e734b1879a)
2>Target: x86_64-pc-windows-msvc
2>Thread model: posix
2>InstalledDir: C:\Program Files\LLVM\bin
2> "C:\\Program Files\\LLVM\\bin\\clang-cl.exe" "-cc1" "-triple" "x86_64-pc-windows-msvc19.16.27035" "-emit-obj" "-mrelax-all" "-mincremental-linker-compatible" "-disable-free" "-disable-llvm-verifier" "-discard-value-names" "-main-file-name" "test_exe.cpp" "-mrelocation-model" "pic" "-pic-level" "2" "-mthread-model" "posix" "-relaxed-aliasing" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-mllvm" "-x86-asm-syntax=intel" "-D_DEBUG" "-D_MT" "-D_DLL" "--dependent-lib=msvcrtd" "--dependent-lib=oldnames" "-stack-protector" "2" "-fcxx-exceptions" "-fexceptions" "-fexternc-nounwind" "-fms-volatile" "-fdefault-calling-conv=cdecl" "-fdiagnostics-format" "msvc" "-gcodeview" "-debug-info-kind=limited" "-femit-coverage-notes" "-femit-coverage-data" "-fprofile-filter-files=^.*first\\.(h|cpp)\$;^.*second\\.(h|cpp)\$" "-coverage-notes-file" "D:\\libs\\test\\test_regexs\\build\\test_exe.gcno" "-coverage-data-file" "D:\\libs\\test\\test_regexs\\build\\test_exe.gcda" "-resource-dir" "C:\\Program Files\\LLVM\\lib\\clang\\9.0.0" "-D" "WIN32" "-D" "_WINDOWS" "-D" "CMAKE_INTDIR=\"Debug\"" "-D" "_MBCS" "-internal-isystem" "C:\\Program Files\\LLVM\\lib\\clang\\9.0.0\\include" "-internal-isystem" "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\VC\\Tools\\MSVC\\14.16.27023\\include" "-internal-isystem" "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\VC\\Tools\\MSVC\\14.16.27023\\atlmfc\\include" "-internal-isystem" "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\VC\\Auxiliary\\VS\\include" "-internal-isystem" "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt" "-internal-isystem" "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\VC\\Auxiliary\\VS\\UnitTest\\include" "-internal-isystem" "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\um" "-internal-isystem" "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\shared" "-internal-isystem" "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\winrt" "-internal-isystem" "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\cppwinrt" "-internal-isystem" "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.6.1\\Include\\um" "-internal-isystem" "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.6.1\\Include\\um" "-O0" "-Wall" "-Wno-error" "-fdeprecated-macro" "-fdebug-compilation-dir" "D:\\libs\\test\\test_regexs\\build" "-ferror-limit" "19" "-fmessage-length" "0" "-fno-use-cxa-atexit" "-fms-extensions" "-fms-compatibility" "-fms-compatibility-version=19.16.27035" "-std=c++17" "-fdelayed-template-parsing" "-fno-inline" "-fobjc-runtime=gcc" "-fno-caret-diagnostics" "-fdiagnostics-show-option" "-fno-show-column" "-faddrsig" "-o" "test_exe.dir\\Debug\\test_exe.obj" "-x" "c++" "D:\\libs\\test\\test_regexs\\test_exe.cpp"
2>lld-link : error : could not open 'test_exe.dir\Debug\test_exe.obj': no such file or directory
2>Done building project "test_exe.vcxproj" -- FAILED.
3>------ Skipped Build: Project: ALL_BUILD, Configuration: Debug x64 ------
3>Project not selected to build for this solution configuration 
========== Build: 1 succeeded, 1 failed, 0 up-to-date, 1 skipped ==========

clang-cl.command.1.tlog:

^D:\LIBS\TEST\TEST_REGEXS\TEST_EXE.CPP
/c /Z7 /nologo /W1 /WX- /diagnostics:classic /Od /Ob0 /D WIN32 /D _WINDOWS /D "CMAKE_INTDIR=\"Debug\"" /D _MBCS /EHsc /MDd /GS /fp:precise /GR /std:c++17 /Fo"TEST_EXE.DIR\DEBUG\\" /Gd /TP -m64   "-###" --coverage "-fprofile-filter-files=^.*first\.(h|cpp)"$"";"^.*second\.(h|cpp)"$"" D:\LIBS\TEST\TEST_REGEXS\TEST_EXE.CPP

You’ll probably need some more escaping to happen here. I would also guess that " needs escaping too.