[cmake-developers] escape double quote in generated file

Craig Scott craig.scott at crascit.com
Fri Aug 30 20:20:43 EDT 2019


On Sat, Aug 31, 2019 at 12:36 AM Eugene Karpov <karpov.en at gmail.com> wrote:

> Hello all,
>
> I'm working on a cross platform project. On Ubuntu I would like to save
> all the compiler options, definitions and other complier related stuff to a
> generated file to use it later for precompiled header generation.
> My issue is that I have to specify a macro that contain double quotes for
> g++ compiler visibility attribute. When I generate a file with double
> quotes they are not escaped. I also tried to use `string(replace "\""
> "\\\""...)` without effect.
> I've made simple two files project of a shared library to show the issue.
> It has only target compile definitions for simplicity.
>
> ------------- CMakeLists.txt ------------------
> cmake_minimum_required(VERSION 3.14)
> set(target test)
> project(${target})
> if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
>     set(API_IMPORT_MACRO "__attribute__((visibility(\"default\")))")
>     set(API_EXPORT_MACRO "__attribute__((visibility(\"default\")))")
> else()
>     set(API_IMPORT_MACRO "__declspec(dllimport)")
>     set(API_EXPORT_MACRO "__declspec(dllexport)")
> endif()
> function(export_all_flags _target _filename)
>   set(_compile_definitions
> "$<TARGET_PROPERTY:${_target},COMPILE_DEFINITIONS>")
>   set(_compile_definitions
> "$<$<BOOL:${_compile_definitions}>:-D$<JOIN:${_compile_definitions},\n-D>\n>")
>   file(GENERATE OUTPUT "${_filename}" CONTENT "${_compile_definitions}")
> endfunction()
> add_library(${target} SHARED test.cpp)
> target_compile_definitions(${target}
>     PRIVATE API=${API_EXPORT_MACRO}
>     INTERFACE API=${API_IMPORT_MACRO})
> export_all_flags(${target} ${CMAKE_BINARY_DIR}/flags.txt)
> ------------- CMakeLists.txt ------------------
> ------------- test.cpp ------------------
> void API test() {}
> ------------- test.cpp ------------------
>
> The result file "flags.txt" is following:
> -DAPI=__attribute__((visibility("default")))
>
> I would like any solution to make the result as:
> -DAPI=__attribute__((visibility(\"default\")))
>

Are you free to modify the headers where the API_IMPORT/API_EXPORT symbols
are used? If so, then it is far easier to delegate the definition of such a
symbol to a separate header file rather than try to define it directly on
the compiler command line. The GenerateExportHeader
<https://cmake.org/cmake/help/latest/module/GenerateExportHeader.html>
module provides a convenient way to create such a header and also set the
relevant details in your CMake target to do the right thing when building
and when consuming the library. I'd expect it to be suitable for a
precompiled header scenario too.

And shameless plug, if you're interested in this area (symbol visibility),
part of my upcoming CppCon talk <https://sched.co/SfnH> in a few weeks will
cover exactly this topic. ;)

-- 
Craig Scott
Melbourne, Australia
https://crascit.com

Get the hand-book for every CMake user: Professional CMake: A Practical
Guide <https://crascit.com/professional-cmake/>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake-developers/attachments/20190831/e0f83764/attachment.html>


More information about the cmake-developers mailing list