Handling of generator expressions

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Handling of generator expressions

Roberto Di Remigio
Hello,
I am trying to compile the following code snippet:

int main(int argc, char ** argv) {
  int stack_array[100];
  stack_array[1] = 0;
  return stack_array[argc + 100]; // BOOM
}

The followin CMakeLists.txt works fine, but you can notice that target_compile_options takes a list, while target_link_libraries takes a string. Always using the string will result in a compilation error, because the compiler flags are passed quoted to the compiler. Always using the list doesn't work either, because the generator expression is evaluated as $<1:-fsanitize=address -fno-omit-frame-pointer> and then passed as-is to the linker, which doesn't know what to do with it.
Is this supposed to be like this? If yes, what's the rationale?
Thanks in advance!
  Roberto

cmake_minimum_required(VERSION 3.3 FATAL_ERROR)

project(recipe-09 CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

list(APPEND CXX_BASIC_FLAGS "-g3" "-O1")

include(CheckCXXCompilerFlag)

set(ASAN_FLAGS "-fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_REQUIRED_FLAGS ${ASAN_FLAGS})
check_cxx_compiler_flag(${ASAN_FLAGS} asan_works)
unset(CMAKE_REQUIRED_FLAGS)

add_executable(asan-example asan-example.cpp)
string(REPLACE " " ";" _asan_flags ${ASAN_FLAGS})
target_compile_options(asan-example
  PUBLIC
    ${CXX_BASIC_FLAGS}
    $<$<BOOL:${asan_works}>:${_asan_flags}>
  )
target_link_libraries(asan-example
  PUBLIC
    $<$<BOOL:${asan_works}>:${ASAN_FLAGS}>
  )

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Handling of generator expressions

Robert Maynard
Hi Roberto,

Can you please report this as an issue (
https://gitlab.kitware.com/cmake/cmake ) as this looks like a bug in
the way we are parsing generator expressions in target_link_libraries.
The target_link_libraries fully supports taking a list of linker flags
when it isn't part of a generator expression.

On Sun, Nov 19, 2017 at 1:16 PM, Roberto Di Remigio
<[hidden email]> wrote:

> Hello,
> I am trying to compile the following code snippet:
>
> int main(int argc, char ** argv) {
>   int stack_array[100];
>   stack_array[1] = 0;
>   return stack_array[argc + 100]; // BOOM
> }
>
> The followin CMakeLists.txt works fine, but you can notice that
> target_compile_options takes a list, while target_link_libraries takes a
> string. Always using the string will result in a compilation error, because
> the compiler flags are passed quoted to the compiler. Always using the list
> doesn't work either, because the generator expression is evaluated as
> $<1:-fsanitize=address -fno-omit-frame-pointer> and then passed as-is to the
> linker, which doesn't know what to do with it.
> Is this supposed to be like this? If yes, what's the rationale?
> Thanks in advance!
>   Roberto
>
> cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
>
> project(recipe-09 CXX)
>
> set(CMAKE_CXX_STANDARD 11)
> set(CMAKE_CXX_EXTENSIONS OFF)
> set(CMAKE_CXX_STANDARD_REQUIRED ON)
>
> list(APPEND CXX_BASIC_FLAGS "-g3" "-O1")
>
> include(CheckCXXCompilerFlag)
>
> set(ASAN_FLAGS "-fsanitize=address -fno-omit-frame-pointer")
> set(CMAKE_REQUIRED_FLAGS ${ASAN_FLAGS})
> check_cxx_compiler_flag(${ASAN_FLAGS} asan_works)
> unset(CMAKE_REQUIRED_FLAGS)
>
> add_executable(asan-example asan-example.cpp)
> string(REPLACE " " ";" _asan_flags ${ASAN_FLAGS})
> target_compile_options(asan-example
>   PUBLIC
>     ${CXX_BASIC_FLAGS}
>     $<$<BOOL:${asan_works}>:${_asan_flags}>
>   )
> target_link_libraries(asan-example
>   PUBLIC
>     $<$<BOOL:${asan_works}>:${ASAN_FLAGS}>
>   )
>
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more
> information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://public.kitware.com/mailman/listinfo/cmake
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Handling of generator expressions

Oleksii Vilchanskyi
In reply to this post by Roberto Di Remigio
UPD. forgot to CC the mailing list

Hi,

I am also confused by this and decided to test it. I found a long thread
from 2012
<https://cmake.org/pipermail/cmake-developers/2012-August/thread.html#16509>
that discusses list expansion issues. It doesn't tell though whether the
patch was mainlined.

tldr; if you quote the whole genexpr, the list will expand properly.
Below is the working code.

----------------------------------------------------------------------
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)

project(recipe-09 CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

list(APPEND CXX_BASIC_FLAGS "-g3" "-O1")

include(CheckCXXCompilerFlag)

set(ASAN_FLAGS "-fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_REQUIRED_FLAGS ${ASAN_FLAGS})
check_cxx_compiler_flag(${ASAN_FLAGS} asan_works)
unset(CMAKE_REQUIRED_FLAGS)

add_executable(asan-example asan-example.cpp)
string(REPLACE " " ";" _asan_flags ${ASAN_FLAGS})
target_compile_options(asan-example
  PUBLIC
    ${CXX_BASIC_FLAGS}
    $<$<BOOL:${asan_works}>:${_asan_flags}>
  )
target_link_libraries(asan-example
  PUBLIC
    "$<$<BOOL:${asan_works}>:${_asan_flags}>" # <-- NOTE THIS
  )
----------------------------------------------------------------------

On 19.11.2017 19:16, Roberto Di Remigio wrote:

> Hello,
> I am trying to compile the following code snippet:
>
> int main(int argc, char ** argv) {
>   int stack_array[100];
>   stack_array[1] = 0;
>   return stack_array[argc + 100]; // BOOM
> }
>
> The followin CMakeLists.txt works fine, but you can notice that
> target_compile_options takes a list, while target_link_libraries takes a
> string. Always using the string will result in a compilation error,
> because the compiler flags are passed quoted to the compiler. Always
> using the list doesn't work either, because the generator expression is
> evaluated as $<1:-fsanitize=address -fno-omit-frame-pointer> and then
> passed as-is to the linker, which doesn't know what to do with it.
> Is this supposed to be like this? If yes, what's the rationale?
> Thanks in advance!
>   Roberto
>
> cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
>
> project(recipe-09 CXX)
>
> set(CMAKE_CXX_STANDARD 11)
> set(CMAKE_CXX_EXTENSIONS OFF)
> set(CMAKE_CXX_STANDARD_REQUIRED ON)
>
> list(APPEND CXX_BASIC_FLAGS "-g3" "-O1")
>
> include(CheckCXXCompilerFlag)
>
> set(ASAN_FLAGS "-fsanitize=address -fno-omit-frame-pointer")
> set(CMAKE_REQUIRED_FLAGS ${ASAN_FLAGS})
> check_cxx_compiler_flag(${ASAN_FLAGS} asan_works)
> unset(CMAKE_REQUIRED_FLAGS)
>
> add_executable(asan-example asan-example.cpp)
> string(REPLACE " " ";" _asan_flags ${ASAN_FLAGS})
> target_compile_options(asan-example
>   PUBLIC
>     ${CXX_BASIC_FLAGS}
>     $<$<BOOL:${asan_works}>:${_asan_flags}>
>   )
> target_link_libraries(asan-example
>   PUBLIC
>     $<$<BOOL:${asan_works}>:${ASAN_FLAGS}>
>   )
>
>
--
Regards,
Oleksii Vilchanskyi
PGP:0x8D3A0E046BDE941F2A53867CE3FD952D48C0B338


--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Handling of generator expressions

Roberto Di Remigio
Dear Oleksii,
indeed it works! Thank you! I have opened an issue on the CMake repository: https://gitlab.kitware.com/cmake/cmake/issues/17501
I think it could still be a bug, since target_compile_definitions and target_link_libraries seem to evaluate the expression differently.
  All the best,
   Roberto 

On Wed, Nov 22, 2017 at 11:40 AM, Oleksii Vilchanskyi <[hidden email]> wrote:
UPD. forgot to CC the mailing list

Hi,

I am also confused by this and decided to test it. I found a long thread
from 2012
<https://cmake.org/pipermail/cmake-developers/2012-August/thread.html#16509>
that discusses list expansion issues. It doesn't tell though whether the
patch was mainlined.

tldr; if you quote the whole genexpr, the list will expand properly.
Below is the working code.

----------------------------------------------------------------------
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)

project(recipe-09 CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

list(APPEND CXX_BASIC_FLAGS "-g3" "-O1")

include(CheckCXXCompilerFlag)

set(ASAN_FLAGS "-fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_REQUIRED_FLAGS ${ASAN_FLAGS})
check_cxx_compiler_flag(${ASAN_FLAGS} asan_works)
unset(CMAKE_REQUIRED_FLAGS)

add_executable(asan-example asan-example.cpp)
string(REPLACE " " ";" _asan_flags ${ASAN_FLAGS})
target_compile_options(asan-example
  PUBLIC
    ${CXX_BASIC_FLAGS}
    $<$<BOOL:${asan_works}>:${_asan_flags}>
  )
target_link_libraries(asan-example
  PUBLIC
    "$<$<BOOL:${asan_works}>:${_asan_flags}>" # <-- NOTE THIS
  )
----------------------------------------------------------------------

On 19.11.2017 19:16, Roberto Di Remigio wrote:
> Hello,
> I am trying to compile the following code snippet:
>
> int main(int argc, char ** argv) {
>   int stack_array[100];
>   stack_array[1] = 0;
>   return stack_array[argc + 100]; // BOOM
> }
>
> The followin CMakeLists.txt works fine, but you can notice that
> target_compile_options takes a list, while target_link_libraries takes a
> string. Always using the string will result in a compilation error,
> because the compiler flags are passed quoted to the compiler. Always
> using the list doesn't work either, because the generator expression is
> evaluated as $<1:-fsanitize=address -fno-omit-frame-pointer> and then
> passed as-is to the linker, which doesn't know what to do with it.
> Is this supposed to be like this? If yes, what's the rationale?
> Thanks in advance!
>   Roberto
>
> cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
>
> project(recipe-09 CXX)
>
> set(CMAKE_CXX_STANDARD 11)
> set(CMAKE_CXX_EXTENSIONS OFF)
> set(CMAKE_CXX_STANDARD_REQUIRED ON)
>
> list(APPEND CXX_BASIC_FLAGS "-g3" "-O1")
>
> include(CheckCXXCompilerFlag)
>
> set(ASAN_FLAGS "-fsanitize=address -fno-omit-frame-pointer")
> set(CMAKE_REQUIRED_FLAGS ${ASAN_FLAGS})
> check_cxx_compiler_flag(${ASAN_FLAGS} asan_works)
> unset(CMAKE_REQUIRED_FLAGS)
>
> add_executable(asan-example asan-example.cpp)
> string(REPLACE " " ";" _asan_flags ${ASAN_FLAGS})
> target_compile_options(asan-example
>   PUBLIC
>     ${CXX_BASIC_FLAGS}
>     $<$<BOOL:${asan_works}>:${_asan_flags}>
>   )
> target_link_libraries(asan-example
>   PUBLIC
>     $<$<BOOL:${asan_works}>:${ASAN_FLAGS}>
>   )
>
>

--
Regards,
Oleksii Vilchanskyi
PGP:0x8D3A0E046BDE941F2A53867CE3FD952D48C0B338




--
Roberto Di Remigio

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake