cmake rejects certain cflags - cmake

I have here a project - though I believe it's independent of the package used - that, when configured with
cmake -DCMAKE_C_FLAGS_RELEASE="-O2 -msse"
uses those exact flags. However, as soon as I use
cmake -DCMAKE_C_FLAGS_RELEASE="-O2 -msse -fmessage-length=0"
cmake goes to stubborn state and ignores my desired flags, instead defaulting to the project's defaults. This is even reflected in CMakeCache.txt, though I do not know what to make of it.
CMakeCache.txt:CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMakeCache.txt:CMAKE_C_FLAGS_RELEASE=-O2 -msse -fmessage-length:UNINITIALIZED=0
The question on the table is — how do I get my flags used?

This is a known bug in the command line parsing in CMake. It's getting confused with the extra = sign and thinks the variable name is CMAKE_C_FLAGS_RELEASE=-O2 -msse -fmessage-length with the value 0!
One way to get the option in the cache in the correct format is to use the cache editor. After running cmake initially, run make edit_cache then press t to toggle advanced options, Ctrl-n down to the CMAKE_C_FLAGS_RELEASE option, hit Enter to edit it and type in the value you want. After that type c then g to configure and generate the Makefiles.
Alternatively, just edit the cache with your $EDITOR and enter the correct line:
CMAKE_C_FLAGS_RELEASE:STRING=-O2 -msse -fmessage-length=0
This isn't very elegant, but it should get you motoring.

BTW, the type declaration also works from the command line, e.g.:
cmake -DCMAKE_C_FLAGS_RELEASE:STRING="-O2 -msse -fmessage-length=0"
should work. Still kind of awkward though.

Related

Can NOT find defined MACRO in cmake-3.16 [duplicate]

I'm building a large library using CMake, and I would like users to be able to selectively enable/disable certain parts of my build process.
How can I add command-line options to my CMake build, e.g. so that users may type something like cmake --build-partone --nobuild-parttwo --dothis=true --dothat=false ..?
Apparently the OPTION keyword will create variables that can be set from the CMake GUI, but I can't figure out how to do this from the command line.
Yeah, you should use the option command. You can set options from the command line this way:
//CMakeLists.txt
option(MyOption "MyOption" OFF)
//Command line
cmake -DMyOption=ON MyProjectFolder
Note that -DMyOption must come before the path.
Just a little correction:
If you have other variables to pass, it is recommended to indicate the type of these:
//CMakeLists.txt
option(MyOption "MyOption" OFF)
//Command line
cmake -DMyOption:BOOL=ON -D... MyProjectFolder

How do i set up instruction & data memory address when using "riscv32-unknown-elf-gcc"?

I designed RISCV32IM processor, and I used "riscv32-unknown-elf-gcc" to generate code for testing.
However, the PC(instruction memory address) value and data memory address of the generated code had arbitrary values. I used this command:
riscv32-unknown-elf-gcc -march=rv32im -mabi=ilp32 -nostartfiles test.c
Can I know if I can set the instruction and data memory address I want?
Thanks.
Thank you for answer.
I designed only HW, and this is my first time using the SW tool chain.
Even if my question is rudimentary, please understand.
The figure is the result of the "-v" option.
enter image description here
I can't modify the script file because I use riscv tool chain in DOCKER environment.
So, I tried to copy the script file (elf32lriscv.x), modify it.
I modified it to 0x10000 ==> 0x00000.
The file name of the copied script is "test5.x".
And it was executed as follows.
What am I doing wrong?
enter image description here
The riscv compiler is using the default linker script to place text and date section... .
If you add -v option to your command line riscv32-unknown-elf-gcc -v -march=rv32im -mabi=ilp32 -nostartfiles test.c, you will see the linker script used by collect 2 ( normally it will be -melf32lriscv . you can find the linker script in ${path_to_toolchain}/riscv32-unknown-elf/lib/ldscripts/ (the default one is .x).
You can also use riscv32-unknown-elf-ld --verbose like explained by #Frant. However , you need to be careful if the toolchain was compiled with enable multilib and you compile for rv64 but the default is rv32 or vice versa. It is not the case probably, but to be sure you can specify the arch with -A elf32riscv for an rv32.
To Set the addresses you can create your own linker script or copy and modify the default one. You can only modify the executable start like explained by #Frant or make more modification and place whatever you want where you want.
Once your own linker script ready you can pass it to the linker with -Wl,-T,${own_linker_script }. you command will be riscv32-unknown-elf-gcc -march=rv32im -mabi=ilp32 -nostartfiles test.c -Wl,-T,${own_linker_script }

How can a CMake variable be hidden?

I have a CMake project which lets a globally set variable (set with -DARDUINO_SDK_PATH=/a/b/c on command line) disappear i.e. suddenly the given value is gone which leads to a fatal error.
I know there are different ways to "hide" a variable (e.g. inside functions or external projects)
In my case:
the variable is not being set explicitly anywhere in the code (e.g. via set() or find_path())
the access which leads to the error is on top level (i.e. not inside a function)
there are instructions (i.e. same file/line) where in one case the variable has the value it's been given and the next time it's gone
Tracing the variable with variable_watch(ARDUINO_SDK_PATH) I can see that everything works fine before the compiler is being checked:
cmake -DARDUINO_SDK_PATH=/a/b/c <path>
...
... everything fine, ${DARDUINO_SDK_PATH} == '/a/b/c' everywhere
...
-- Check for working C compiler: /usr/bin/avr-gcc
...
... here the variable is empty and not being traced any more
...
Here is my suggestion:
Does the compiler check (indicated by check for working C compiler .. on the terminal) have it's own variable space and does not know variables provided on command line?
Note: This question is a generalization of this question, which has become way too specialized but might offer some useful background information.
That any modification to variable is not traced after the variable_watch() command seems like a bug somewhere in CMake to me.
Generally speaking a "cached CMake variable" can be hidden by a "normal CMake variable" with the same name. But e.g. find_path() won't run again or modify a variable if already set.
Here is an example:
cmake_minimum_required(VERSION 2.4)
project(VariableWatchTest NONE)
variable_watch(MY_TEST_VAR)
set(MY_TEST_VAR "something" CACHE INTERNAL "")
message("${MY_TEST_VAR}")
set(MY_TEST_VAR "hiding something")
message("${MY_TEST_VAR}")
unset(MY_TEST_VAR)
message("${MY_TEST_VAR}")
find_path(MY_TEST_VAR NAMES "CMakeLists.txt" HINTS "${CMAKE_CURRENT_LIST_DIR}")
message("${MY_TEST_VAR}")
Would give (without the variable_watch() messages:
-- something
-- hiding something
-- something
-- something
References
What's the CMake syntax to set and use variables?
I'm not sure whether this is a bug or a feature but (at least some) CMake variables are not available in certain steps of the CMake configuration procedure.
You can check this by adding something like this to your toolchain file:
MESSAGE("FOO: ${FOO}")
and run CMake like this
cd build-dir
cmake -DFOO=TEST ..
You will likely see FOO printed with value TEST once in the beginning of the configuration process and later printed again but being empty.
Just don't access variables from the global space inside a toolchain file (doesn't belong there anyway).

Getting CMake CHECK_CXX_COMPILER_FLAG to work

Note: This is my first time using CMake. I don't know much about it, so I'm just posting a bunch of information to see if anyone can see my problem.
I would like the ability to automatically determine which c++11 flag is appropriate, given my compiler. There are many examples of this line. Here is my CMakeLists.txt following such an example:
cmake_minimum_required (VERSION 2.8)
#Add the c++11 flag, whatever it is
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG(-std=c++0x COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
project(AnalyzeGames)
set(AnalyzeGames_SRCS AnalyzeGames.cpp)
add_executable(AnalyzeGames ${AnalyzeGames_SRCS})
Here is my cmake output when trying to use this file: http://pastebin.com/3AUwqffD
Here is CMakeError.log: http://pastebin.com/EbNKvGt8
Here is CMakeOutput.log: http://pastebin.com/kVJ0enJC
echo $CC: /usr/bin/gcc
echo $CXX: /usr/bin/g++
I can compile a simple test executable with g++ using either flag manually.
cmake --version: cmake version 2.8.12.2
For some reason CMake is not recognizing that my compiler does support both of those flags.
The cmake output tells you that it does not recognize the '.cxx' extension because it doesn't know that your project is a C++ project. To fix this, you should enable C++ in the project command. Try to change the following line:
project(AnalyzeGames)
to:
project(AnalyzeGames CXX)
and then move it to the 2nd line of the CMakeLists.txt, right under cmake_minimum_required. The configuration should work as expected after this.
TLDR
Compiler checks are only performed in the variable passed is not previously defined, which includes in the cache from previous failed attempts. Use unset(my_var CACHE) to force checking to always occur, or just be aware of this behaviour and clear the cache manually when needed.
Detail
I too had this problem (with cmake 2.8.12.2) and I had to turn on trace output, and step through the code to get a similar toy build to work I had make sure the variables I used (COMPILER_SUPPORTS_CXX11_*) in these calls:
CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG(-std=c++0x COMPILER_SUPPORTS_CXX0X)
Were set such that they named themselves:
set(COMPILER_SUPPORTS_CXX11 "COMPILER_SUPPORTS_CXX11")
The other posters solution didn't work for me, it mainly just seemed to limit the detecting of compilers to just CXX and ignored the C compiler.
The issue appears to be with this line of code in the cmake module:
if("${VAR}" MATCHES "^${VAR}$")
Which in the trace output is:
/usr/share/cmake/Modules/CheckCXXSourceCompiles.cmake(30): if(COMPILER_SUPPORTS_CXX0X MATCHES ^COMPILER_SUPPORTS_CXX0X$ )
It looks as if the expression on the left of the MATCHES is replaced with the variables value, but the expression on the right is assumed to be plain text.
If the MATCH fails then the main part of the macro is skipped and according the to the log the check fails.
Looking at later versions of this macro online it looks as if this line has changed to only perform the compile check if the variable is undefined.
It as at this point that I realise that this is the intent / hack of the original code; if the X is undefined then "X" MATCHES "^X$" will be true, but then the compile check can be performed, fail for some other reason and then never be performed again.
So the solution is either force unset of variable in cache before calling the macro using:
unset(COMPILER_SUPPORTS_CXX0X CACHE)
Or clear the cache manually and be prepared for this behaviour.

Proper way to call a found executable in a custom command?

I have a program on my computer, let's say C:/Tools/generate_v23_debug.exe
I have a FindGenerate.cmake file which allows CMake to find that exact path to the executable.
So in my CMake code, I do:
find_program(Generate)
if (NOT Generate_FOUND)
message(FATAL_ERROR "Generator not found!")
So CMake has found the executable. Now I want to call this program in a custom command statement. Should I use COMMAND Generator or COMMAND ${GENERATOR_EXECUTABLE}? Will both of these do the same thing? Is one preferred over the other? Is name_EXECUTABLE a variable that CMake will define (it's not in the FindGenerate.cmake file), or is it something specific to someone else's example code I'm looking at? Will COMMAND Generator be expanded to the correct path?
add_custom_command(
OUTPUT blahblah.txt
COMMAND Generator inputfile1.log
DEPENDS Generator
)
find_program stores its result into the variable given as a first argument. You can verify this by inserting some debug output:
find_program(GENERATOR Generate)
message(${GENERATOR})
Note that find_program does not set any additional variables beyond that. In particular, you mentioned Generate_FOUND and GENERATOR_EXECUTABLE in your question and neither of those gets introduced implicitly by the find_program call.
The second mistake in your program is the use of the DEPENDS option on the add_custom_command. DEPENDS is used to model inter-target dependencies at build time and not to manipulate control flow in the CMakeLists. For example, additional custom command can DEPEND on the output of your command (blahblah.txt), but a custom command cannot DEPEND on the result of a previous find operation.
A working example might look something like this:
find_program(GENERATOR Generate)
if(NOT GENERATOR)
message(FATAL_ERROR "Generator not found!")
endif()
add_custom_command(
OUTPUT blahblah.txt
COMMAND ${GENERATOR} inputfile1.log
)
P.S.: You asked why the code examples were not properly formatted in your question. You indented everything correctly, but you need an additional newline between normal text and code paragraphs. I edited your question accordingly.