mirror of
https://github.com/reactos/CMake.git
synced 2025-02-21 20:40:44 +00:00
target_compile_options: Add syntax to specify shell strings
Options specified via `COMPILE_OPTIONS` and `INTERFACE_COMPILE_OPTIONS` are deduplicated, but individual options can legitimately be duplicated when grouped with other options, e.g. -D A -D B After deduplication that becomes `-D A B`. Therefore we need a way to treat groups of options as units during deduplication. A simple approach is to specify each group as one option, e.g. "-D A" "-D B" However, that conflicts with options that legitimately have spaces. To break this ambiguity, add a `SHELL:` prefix syntax to specify that an option should be parsed like shell command line arguments after deduplication, e.g. "SHELL:-D A" "SHELL:-D B" These will survive deduplication intact, and then be parsed to produce `-D A -D B` on the final command line. Fixes: #15826
This commit is contained in:
parent
b340cacde8
commit
ce0b983216
9
Help/command/COMPILE_OPTIONS_SHELL.txt
Normal file
9
Help/command/COMPILE_OPTIONS_SHELL.txt
Normal file
@ -0,0 +1,9 @@
|
||||
The final set of compile options used for a target is constructed by
|
||||
accumulating options from the current target and the usage requirements of
|
||||
it dependencies. The set of options is de-duplicated to avoid repetition.
|
||||
While beneficial for individual options, the de-duplication step can break
|
||||
up option groups. For example, ``-D A -D B`` becomes ``-D A B``. One may
|
||||
specify a group of options using shell-like quoting along with a ``SHELL:``
|
||||
prefix. The ``SHELL:`` prefix is dropped and the rest of the option string
|
||||
is parsed using the :command:`separate_arguments` ``UNIX_COMMAND`` mode.
|
||||
For example, ``"SHELL:-D A" "SHELL:-D B"`` becomes ``-D A -D B``.
|
@ -21,3 +21,5 @@ Arguments to ``add_compile_options`` may use "generator expressions" with
|
||||
the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
|
||||
manual for available expressions. See the :manual:`cmake-buildsystem(7)`
|
||||
manual for more on defining buildsystem properties.
|
||||
|
||||
.. include:: COMPILE_OPTIONS_SHELL.txt
|
||||
|
@ -38,3 +38,5 @@ Arguments to ``target_compile_options`` may use "generator expressions"
|
||||
with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
|
||||
manual for available expressions. See the :manual:`cmake-buildsystem(7)`
|
||||
manual for more on defining buildsystem properties.
|
||||
|
||||
.. include:: COMPILE_OPTIONS_SHELL.txt
|
||||
|
6
Help/release/dev/compile-options-shell.rst
Normal file
6
Help/release/dev/compile-options-shell.rst
Normal file
@ -0,0 +1,6 @@
|
||||
compile-options-shell
|
||||
---------------------
|
||||
|
||||
* :command:`target_compile_options` and :command:`add_compile_options`
|
||||
commands gained a ``SHELL:`` prefix to specify a group of related
|
||||
options using shell-like quoting.
|
@ -2622,13 +2622,20 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
|
||||
return includes;
|
||||
}
|
||||
|
||||
enum class OptionsParse
|
||||
{
|
||||
None,
|
||||
Shell
|
||||
};
|
||||
|
||||
static void processCompileOptionsInternal(
|
||||
cmGeneratorTarget const* tgt,
|
||||
const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
|
||||
std::vector<std::string>& options,
|
||||
std::unordered_set<std::string>& uniqueOptions,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
|
||||
bool debugOptions, const char* logName, std::string const& language)
|
||||
bool debugOptions, const char* logName, std::string const& language,
|
||||
OptionsParse parse)
|
||||
{
|
||||
for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
|
||||
std::vector<std::string> entryOptions;
|
||||
@ -2639,7 +2646,12 @@ static void processCompileOptionsInternal(
|
||||
std::string usedOptions;
|
||||
for (std::string const& opt : entryOptions) {
|
||||
if (uniqueOptions.insert(opt).second) {
|
||||
options.push_back(opt);
|
||||
if (parse == OptionsParse::Shell &&
|
||||
cmHasLiteralPrefix(opt, "SHELL:")) {
|
||||
cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, options);
|
||||
} else {
|
||||
options.push_back(opt);
|
||||
}
|
||||
if (debugOptions) {
|
||||
usedOptions += " * " + opt + "\n";
|
||||
}
|
||||
@ -2664,7 +2676,7 @@ static void processCompileOptions(
|
||||
{
|
||||
processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
|
||||
dagChecker, config, debugOptions, "options",
|
||||
language);
|
||||
language, OptionsParse::Shell);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
|
||||
@ -2718,7 +2730,7 @@ static void processCompileFeatures(
|
||||
{
|
||||
processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
|
||||
dagChecker, config, debugOptions, "features",
|
||||
std::string());
|
||||
std::string(), OptionsParse::None);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result,
|
||||
@ -2768,7 +2780,7 @@ static void processCompileDefinitions(
|
||||
{
|
||||
processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
|
||||
dagChecker, config, debugOptions,
|
||||
"definitions", language);
|
||||
"definitions", language, OptionsParse::None);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetCompileDefinitions(
|
||||
|
@ -18,9 +18,21 @@ set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS
|
||||
"-DTEST_DEFINE"
|
||||
"-DNEEDS_ESCAPE=\"E$CAPE\""
|
||||
"$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE_GNU>"
|
||||
"SHELL:" # produces no options
|
||||
${c_tests}
|
||||
${cxx_tests}
|
||||
)
|
||||
if(BORLAND OR WATCOM)
|
||||
# these compilers do not support separate -D flags
|
||||
target_compile_definitions(CompileOptions PRIVATE NO_DEF_TESTS)
|
||||
else()
|
||||
set_property(TARGET CompileOptions APPEND PROPERTY COMPILE_OPTIONS
|
||||
"SHELL:-D DEF_A"
|
||||
"$<1:SHELL:-D DEF_B>"
|
||||
"SHELL:-D 'DEF_C' -D \"DEF_D\""
|
||||
[[SHELL:-D "DEF_STR=\"string with spaces\""]]
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|Borland|Embarcadero")
|
||||
set_property(TARGET CompileOptions APPEND PROPERTY COMPILE_OPTIONS
|
||||
|
@ -12,6 +12,28 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NO_DEF_TESTS
|
||||
#ifndef DEF_A
|
||||
#error Expected definition DEF_A
|
||||
#endif
|
||||
|
||||
#ifndef DEF_B
|
||||
#error Expected definition DEF_B
|
||||
#endif
|
||||
|
||||
#ifndef DEF_C
|
||||
#error Expected definition DEF_C
|
||||
#endif
|
||||
|
||||
#ifndef DEF_D
|
||||
#error Expected definition DEF_D
|
||||
#endif
|
||||
|
||||
#ifndef DEF_STR
|
||||
#error Expected definition DEF_STR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
@ -19,6 +41,9 @@ int main()
|
||||
return (strcmp(NEEDS_ESCAPE, "E$CAPE") == 0
|
||||
#ifdef TEST_OCTOTHORPE
|
||||
&& strcmp(TEST_OCTOTHORPE, "#") == 0
|
||||
#endif
|
||||
#ifndef NO_DEF_TESTS
|
||||
&& strcmp(DEF_STR, "string with spaces") == 0
|
||||
#endif
|
||||
&&
|
||||
strcmp(EXPECTED_C_COMPILER_VERSION, TEST_C_COMPILER_VERSION) == 0 &&
|
||||
|
Loading…
x
Reference in New Issue
Block a user