简体   繁体   中英

How do I migrate from COMPILE_FLAGS to target_compile_options in CMake?

I have the following code in my CMakeLists.txt to set some compiler and linker flags for my emscripten project:

Old, working code

set_target_properties(prolog_bfs PROPERTIES COMPILE_FLAGS "-s USE_BOOST_HEADERS=1 -s DISABLE_EXCEPTION_CATCHING=0")
set_target_properties(prolog_bfs PROPERTIES LINK_FLAGS "--bind --emrun -s USE_BOOST_HEADERS=1 -s DISABLE_EXCEPTION_CATCHING=0")

This works perfectly fine and my compiler gets called with the options as it should (I still wonder where the spaces after em++ are coming from though, but this is not an issue):

em++    -s USE_BOOST_HEADERS=1 -s DISABLE_EXCEPTION_CATCHING=0 -std=gnu++17 -o xy.o -c xy.cpp

However, COMPILE_FLAGS and LINK_FLAGS are deprecated , so I want to migrate to the new/recommended approach of using target_compile_options() and target_link_options() instead.

Thus, I have changed my CMakeLists.txt like so:

New approach

target_compile_options(prolog_bfs PUBLIC -s USE_BOOST_HEADERS=1;-s DISABLE_EXCEPTION_CATCHING=0)
target_link_options(prolog_bfs PUBLIC --bind;--emrun;-s USE_BOOST_HEADERS=1;-s DISABLE_EXCEPTION_CATCHING=0)

I understand that the target_*_options function requires to separate flags with a semicolon, which I did. Apart from that, I don't see any other major differences.

The problem

Building my project with these changes will get the compiler called like this:

em++    -s USE_BOOST_HEADERS=1 DISABLE_EXCEPTION_CATCHING=0 -std=gnu++17 -o xy.o -c xy.cpp

Note that that the -s before the second flag is missing. I don't understand why it disappears. Interestingly, the first one stays there.

Question

How do I transform my initial CMakeLists.txt code into the modern approach without losing the -s ?

By default, CMake de-duplicates compile and link options. This is explicitly stated in the documentation for target_compile_options command. Also, the documentation suggests to use SHELL: prefix for avoid breaking groups because of that:

The final set of compile or link options used for a target is constructed by accumulating options from the current target and the usage requirements of its 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, -DA -DB becomes -DAB . 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 separate_arguments() UNIX_COMMAND mode. For example, "SHELL:-DA" "SHELL:-DB" becomes -DA -DB .

That is, in your case you may specify

target_compile_options(prolog_bfs PUBLIC "SHELL:-s USE_BOOST_HEADERS=1" "SHELL:-s DISABLE_EXCEPTION_CATCHING=0")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM