-
Notifications
You must be signed in to change notification settings - Fork 991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix handling of tools.build:defines
for multiconfig CMake (#15921)
#15924
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a failing test first could help, would you like our help to provide one?
I'm not sure what exactly I should do for this, but let me clarify the problem a bit more. If I have a profile containing two defines for a multiconfig CMake generator like MSVC: [settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=20
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.version=192
os=windows
[conf]
tools.build:defines=['_WIN32_WINNT=0x0A00', 'NTDDI_VERSION=0x0A000006'] ... and then do a conan install with the add_compile_definitions($<$<CONFIG:Release>:" _WIN32_WINNT=0x0A00"" NTDDI_VERSION=0x0A000006">) After a CMake configure, this produces the following ...
<ClCompile>
<PreprocessorDefinitions>...;" _WIN32_WINNT=0x0A00"" NTDDI_VERSION=0x0A000006";...</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>...;\" _WIN32_WINNT=0x0A00\"\" NTDDI_VERSION=0x0A000006\";...</PreprocessorDefinitions>
</ResourceCompile>
... which MSVC does not interpret as intended. With the new solution, it will output: add_compile_definitions("$<$<CONFIG:Release>:_WIN32_WINNT=0x0A00>" "$<$<CONFIG:Release>:NTDDI_VERSION=0x0A000006>") which generates ...
<ClCompile>
<PreprocessorDefinitions>...;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000006;...</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>...;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000006;...</PreprocessorDefinitions>
</ResourceCompile>
... |
Thanks for the feedback. I have added some checks in The overlook in that test was adding only 1 |
Uhmmm, there might be something there still not right.
and the test now passes with 2 values. We would need a failing test first, to make sure we are covering and correctly fixing it. |
I identified one issue with the test: the validation of the output was not fully correct. I was checking |
@memsharded Thanks for adding the tests. I think the change introduces an issue, though. The value should be quoted: add_compile_definitions("$<$<CONFIG:Release>:ABC=123>""$<$<CONFIG:Release>:DEF=456>") should have been add_compile_definitions("$<$<CONFIG:Release>:ABC=123>" "$<$<CONFIG:Release>:DEF=456>") which does work. |
Makes sense, thanks for the investigation and feedback. I have pushed a fix for the broken test, quoting the defines, I think it should be ok now, please check. |
@memsharded This does not seem to work. For example: add_compile_definitions($<$<CONFIG:Debug>:"ABC=123">)
add_compile_definitions($<$<CONFIG:Debug>:"DEF=456">) generates: Compare to: add_compile_definitions("$<$<CONFIG:Debug>:ABC=123>")
add_compile_definitions("$<$<CONFIG:Debug>:DEF=456>") which properly generates: |
Omg, we have just released 2.2.2 with this fix... :( Still, the thing is that the test passes. We would need to add some tests that cover the case and fail. The current tests are working. |
@memsharded I'm not sure what we're doing differently, but if I test with the first pair of
|
If you could introduce something like |
I'll have a look.
Doesn't seem like it:
|
@memsharded I don't really understand what's going on. I tried the C code from the test separately with the relevant
Which is in line with the I'll check if I'm missing something by actually using Conan with |
Yes this outputs the same, as expected. Maybe it's not broken for MSVC for a weird reason? I'm not on my Windows pc to test atm. |
Apparently, this is how it comes out for Visual Studio: <ClCompile>
...
<PreprocessorDefinitions>%(PreprocessorDefinitions);"_WIN32_WINNT=0x0A00";"NTDDI_VERSION=0x0A000006";CMAKE_INTDIR="Release"</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;\"_WIN32_WINNT=0x0A00\";\"NTDDI_VERSION=0x0A000006\";CMAKE_INTDIR=\"Release\"</PreprocessorDefinitions>
</ResourceCompile> This does seem to work on my pc (the macros are actually defined), although I thought the CI did have problems with it, not sure. In any case, it does not work well with Ninja Multi-Config, as stated above. |
@memsharded, I can confirm that the current state fails with The correct fix is to just add quotes around the generator-expression instead of putting them inside it. Therefore, as @stevenwdv already mentioned here the code in question should look like this: --- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -724,7 +724,7 @@ class ExtraFlagsBlock(Block):
{% if defines %}
{% if config %}
{% for define in defines %}
- add_compile_definitions($<$<CONFIG:{{config}}>:"{{ define }}">)
+ add_compile_definitions("$<$<CONFIG:{{config}}>:{{ define }}>")
{% endfor %}
{% else %}
add_compile_definitions({% for define in defines %} "{{ define }}"{% endfor %})
edit: Forget the former not. As CMake's documentation for
However, the sentence in parentheses still leaves some possibility for problems. |
|
Changelog: Bugfix: Fix handling of
tools.build:defines
for multiconfig CMake.Docs: Omit
Closes #15921
The fix is not as simple as fixing the quote spacing. The problem is CMake generator expressions, which are a pain to work with. We can't just pass multiple strings to one generator expression, since the expression needs to be in one string argument to
add_compile_definitions
.This PR fixes it similarly to how it is done in:
conan/conan/tools/cmake/toolchain/toolchain.py
Lines 122 to 132 in 19b7cf6
But it uses quoted strings instead of variables.
Note that this still is not perfect, since we should really escape characters in the generator expression, such as
>
as$<ANGLE-R>
, which would otherwise close the generator expression, and$
as$<1:$>
, but also;
as\;
to prevent variables containing it to be split as a list. But this issue is also present with the variable-based approach intoolchain.py
.I'll create a separate issue for thisSee #15926.develop
branch, documenting this one.