How to use Set directory properties [duplicate] - cmake

This question already has answers here:
How do I add a linker or compile flag in a CMake file?
(7 answers)
Closed last year.
I used Set_directory_properties(PROPERTIES COMPILE_DEFINITIONS "--saferc=none") to mask misra check in directory, but I got Warning:
Ccv850:Warning:option "-D--saferc=none" ignored due to invalid argument. Expected name or name=string.

You should basically never use directory properties, ever.
For whichever targets cannot compile without the flag, you can add it like so:
target_compile_options(
my_target
PRIVATE
"$<$<CXX_COMPILER_ID:GHS>:--saferc=none>"
"$<$<C_COMPILER_ID:GHS>:--saferc=none>"
)
My understanding is that --saferc=none is a Green Hills flag, hence the check for $<CXX_COMPILER_ID:GHS>. If you are only using one of C or C++, you can delete the flag for the other language.

Related

Cmake commands as macro arguments [duplicate]

This question already has answers here:
How to call a function in CMake whose name is stored in a variable
(5 answers)
Closed 11 months ago.
I want to use a CMake macro as a text replacement tool to call a command. This is something I am familiar with in C, but I am not sure if this is allowed in CMake.
what I want to be able to do:
MY_MACRO(
MY_COMMAND(ARGS)
)
I have tried a few different variations on this general idea on how to implement this, but I am not sure it is possible.
MACRO(MY_MACRO)
# do stuff
${ARGN} # Call MY_COMMAND
# do stuff
)
I figured this out based on this thread:
https://gitlab.kitware.com/cmake/cmake/-/issues/20800#note_951424
I haven't tested very thoroughly, but this is the gist at least:
MACRO(MY_MACRO)
#stuff
CMAKE_LANGUAGE(EVAL CODE ${ARGN})
#stuff
ENDMACRO(MY_MACRO)

CMake: how to normalize paths? [duplicate]

This question already has answers here:
cmake generate error on windows as it uses \ as escape seq
(3 answers)
Closed 5 years ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
Is there a robust way to normalize paths in CMake?
Example:
# Let's assume that an environment variable MY_ROOT_DIR is set
# that points to some directory.
set(MYFILE "$ENV{MY_ROOT_DIR}/somefile.txt")
message(${MYFILE})
# This will result for example in
# Win: C:\path\to\my\root\dir/somefile.txt
# Unix based: /path/to/my/root/dir/somefile.txt
In this example, it would be required to normalize MY_ROOT_DIR (that is to replace backslashes with slashes) prior to using it as path component. How would you do this in CMake?
CMake (or the tools further down the toolchain) may handle paths with mixed separators (/ or \), or may not. CMake uses / as the standard separator. A typical warning generated by CMake for paths with the wrong path separator \ may look similar to this:
CMake Warning (dev) at cmake_install.cmake:5 (set):
Syntax error in cmake code at
C:/path/to/my/root/build/cmake_install.cmake:5
when parsing string
C:\path\to\my\root/somefile.txt
Invalid escape sequence \p
Policy CMP0010 is not set: Bad variable reference syntax is an error. Run
"cmake --help-policy CMP0010" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
Thanks for any hints on this!
You can use the file(TO_CMAKE_PATH) command for this.
The TO_CMAKE_PATH mode converts a native <path> into a cmake-style path with forward-slashes (/). The input can be a single path or a system search path like $ENV{PATH}. A search path will be converted to a cmake-style list separated by ; characters.
Here is an example:
file(TO_CMAKE_PATH "$ENV{MY_DIR_VAR}" ENV_MY_DIR_VAR)

cmake replace string in custom target [duplicate]

This question already has an answer here:
How to call a CMake function from add_custom_target/command?
(1 answer)
Closed 5 years ago.
I want to have a cmake target that updates a specific file.
I tried following but it seems that I cannot put all what I want into a custom target.
ADD_CUSTOM_TARGET(update
file(READ "file.h" myFile)
string(REPLACE "originalString" "newString" myFile"${myFile}"))
)
I'm quite new to cmake so I may be missing something basic. How could I update the file on request ?
What I personally use for this type of problem is use configure_file. Essentially, you can make what you consider a template file and wrap variable names in the files.
Example.h.template
Here is my #VAR#
Then if you have VAR defined in your CMake project, it will replace VAR in your destination.
configure_file(<input> <output> NEWLINE_STYLE WIN32)
If input (your template) is modified, CMake will be re-run to keep your file up to date. So in your cmake you can
set(VAR "program")
configure_file("Path/To/Example.h.template" "Path/To/File.h" NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF])
The result should be:
File.h
Here is my program

How to put several paths in CMAKE_PREFIX_PATH? [duplicate]

This question already has an answer here:
Multiple Cmake_Prefix_Paths
(1 answer)
Closed 6 years ago.
How can I have several paths for cmake to look for needed libraries. I installed zlib and libpng under /usr/local/zlib and /usr/local/libpng however, what I'm currently doing is first cmake -DCMAKE_PREFIX_PATH=/usr/local/zlib, then issuing a second command `cmake -DCMAKE_PREFIX_PATH=/usr/local/libpng" in order for cmake to recognize both.
Is there a way to have both paths in the same variable?
I tried -DCMAKE_PREFIX_PATH=/usr/local/zlib:/usr/local/libpng but it didn't work.
You need to use ; character instead of : to define lists.

How to create a C #define for a certain target using CMake?

I feel a little stupid right now. After recently converting a few smaller projects to use CMake, I decided to also get rid of a few "Platform_Config.h" files. These files contain a few preprocessing directives like #define USE_NEW_CACHE and control compilation.
How would I 'convert' these defines to be controlled with CMake? Ideally by using these "cache" variables the user can easily edit.
There are two options. You can use the add_definitions method to pass defines as compiler flags: E.g. somewhere in your projects cmakelists.txt:
add_definitions( -DUSE_NEW_CACHE )
CMake will make sure the -D prefix is converted to the right flag for your compiler (/D for msvc and -D for gcc).
Alternatively, check out configure_file. It is more complex, but may be better suited to your original approach with a Platform_Config file.
You can create an input-file, similar to your original Platform_Config.h and add "#cmakedefine" lines to it.
Let's call in Platform_Config.h.in:
// In Platform_Config.h.in
#cmakedefine USE_NEW_CACHE
// end of Platform_Config.h.in
When then running
configure_file( ${CMAKE_SOURCE_DIR}/Platform_Config.h.in ${CMAKE_BINARY_DIR}/common/Platform_Config.h )
it will generate a new Platform_Config file in your build-dir. Those variables in cmake which are also a cmakedefine will be present in the generated file, the other ones will be commented out or undefed.
Of course, you should make sure the actual, generated file is then correctly found when including it in your source files.
option command might provide what you are looking for.
use it with the COMPILE DEFINITIONS property on the target and i think you are done.
To set the property on the target, use the command set target properties
option(DEBUGPRINTS "Prints a lot of debug prints")
target(myProgram ...)
if(DEBUGPRINTS)
set_target_properties(myProgram PROPERTIES COMPILE_DEFINITIONS "DEBUGPRINTS=1")
endif()
edit:
The option i wrote in the example shows up as a checkbox in the CMake GUI.
In case you want to set defines per target: Since 2.8.11 you can use target_compile_definitions.
In earlier versions you probably don't want to use set_target_properties as is, since it overwrites any defines you set previously. Call get_target_property first instead, then merge with previous values. See add_target_definitions here.
Use target_compile_options. Do not quote your define or it not be detected as a define. CMake parses off the /define and adds the actual define to the DefineConstants section of the csproj, if there are quotes it will put the entire quoted string in the AdditionalOptions section of the csproj.
An example from one of my projects that uses generator expressions:
target_compile_options( ${LIBRARY_NAME} PRIVATE
$<${IS_ART_ITERATION_BUILD}:/define:ART_ITERATION_BUILD>
)
An example without generator expressions:
target_compile_options( ${LIBRARY_NAME} PRIVATE
/define:GRAPHICS_VULKAN
)