I have cross compiled a software for an HummingBoard-Pro (arm processor).
The software just receives some data using the lcm protocol.
If I use the cross compiled software, the data received by the application are invalid, while if I use on-board compiled software everything works fine.
-The software is exactly the same!
-I cross compiled using cmake and a specific arm toolchain.
Output example of cross compiled sw:
first value 5.73599e+107
second value 5.73599e+107
third value 5.73599e+107
Output example of on board compiled sw:
first value 1
second value 2
third value 3
Note: It's my first cross compilation attempt so probably something goes wrong but I haven't really idea about what.
CMakelists file
cmake_minimum_required(VERSION 3.1)
set(main_project_dir ${CMAKE_CURRENT_SOURCE_DIR})
set(external_dir ${main_project_dir}/external)
set(external_lcm_dir ${external_dir}/lcm_dir)
set(external_lcm ${external_lcm_dir}/lcm)
set(external_lcm_build ${external_lcm}/build)
set(external_lcm_gen_exe /usr/local/bin/lcm-gen)
set(lcm_input_file ${main_project_dir}/lcm_format_files/lcm_input_files/indrive.sensors.vanet.lcm)
set(lcm_libraries ${main_project_dir}/external/lcm_dir/lcm/build/lcm)
set(lmc_libraries_header ${main_project_dir}/external/lcm_dir/lcm/)
set(lcm_autogenerated_dir ${main_project_dir}/build/lcm_autogenerated_classes)
add_custom_target(
generate-lcm
COMMAND ${external_lcm_gen_exe} -x ${lcm_input_file} --cpp-hpath ${lcm_autogenerated_dir}
COMMENT "=================== Generating lcm files..."
)
add_subdirectory(testSender)
add_subdirectory(testReceiver)
TOOLCHAIN FILE
SET (CMAKE_SYSTEM_NAME Linux)
SET (CMAKE_SYSTEM_VERSION 1)
SET (CMAKE_SYSTEM_PROCESSOR arm)
INCLUDE_DIRECTORIES(/usr/hummingboard/usr/include /usr/hummingboard/include /usr/hummingboard/usr/include/arm-linux-gnueabihf/)
LINK_DIRECTORIES(/usr/hummingboard/usr/lib /usr/hummingboard/lib /usr/hummingboard/lib/arm-linux-gnueabihf )
SET(CMAKE_PREFIX_PATH /usr/arm-linux-gnueabihf/lib/
/usr/hummingboard/
/usr/hummingboard/lib/arm-linux-gnueabihf/
/usr/hummingboard/usr
/usr/hummingboard/usr/lib/arm-linux-gnueabihf/
)
SET (CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabi-gcc)
SET (CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabi-g++)
SET (CMAKE_FIND_ROOT_PATH /usr/hummingboard/ /usr/hummingboard/usr)
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Turning my comments into an answer
Your toolchain file looks like a mixture of two GNU toolchains, which is not allowed and could explain strange behavior of your software.
I would e.g. expect there to be a /usr/hummingboard/bin directory. And shouldn't there be a arm-linux-gnueabihf-gcc to match with /usr/arm-linux-gnueabihf/lib/.
My guess would be that you are mixing hard-float (hf) with soft-float libraries and native- with cross-compilers.
It gets visible with the value 5.73599e+107 = 0x7f800000 which means infinite.
To find the root-cause I would recommend to check your floating point settings. Please compare the compiler command lines between both builds (working vs. non-working) using verbose makefiles.
References
Assign infinity to float
Using CMake with GNU Make: How can I see the exact commands?
Related
In the build process, I set directories where I gather the build output of different sub-projects. The directories are set as :
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_LIST_DIR}/../build/bin/debug" )
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_LIST_DIR}/../build/bin/release" )
Now, I'd like to copy some files (a directory of qt plugins) to that directory dependent on the configuration which it is built for.
I tried:
# copy qt plugins
add_custom_command( TARGET mytarget POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${QT_DIR}/../../../plugins"
"${$<UPPER_CASE:CMAKE_RUNTIME_OUTPUT_DIRECTORY_$<CONFIG> >}/plugins"
COMMAND_EXPAND_LISTS)
thus, I try to build a string that equals the variable name and then try to expand that as described here: CMake interpret string as variable. In other words: I would like to have a generator expression that evaluates to the content of CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG or CMAKE_RUNTIME_OUTPUT_DIRECTOR_RELEASE dependent on the current build configuration.
However running cmake with the statement above results in an error:
"CMakeLists.txt:112: error: Syntax error in cmake code at [..] when parsing string ${$<UPPER_CASE:CMAKE_RUNTIME_OUTPUT_DIRECTORY_$<CONFIG> >}/plugins Invalid character ('<') in a variable name: '$'
So my question is, how can I use a generator-expression to access the corresponding variable? (Bonus question: is there another/better way to achieve the same goal?)
So my question is, how can I use a generator-expression to access the corresponding variable?
You cannot. There is currently (CMake <=3.23) no way to expand a variable whose name is determined by the value of a generator expression.
Bonus question: is there another/better way to achieve the same goal?
Yes, and you are almost there! You can use $<TARGET_FILE_DIR:...>:
add_custom_command(
TARGET mytarget POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy_directory
"${QT_DIR}/../../../plugins"
"$<TARGET_FILE_DIR:mytarget>/plugins"
VERBATIM
)
This works because TARGET_FILE_DIR evaluates to the actual directory containing the executable or library file for mytarget, no matter the active configuration, property values, etc.
Docs: https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#genex:TARGET_FILE_DIR
CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG> is already relative to the binary directory so you should not try to compute the binary directory in its definition. Also, it supports generator expressions. Thus, the following will be much more robust:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin/$<LOWER_CASE:$<CONFIG>>"
CACHE STRING "Common output directory for runtime artifacts")
This has a bunch of concrete benefits:
No need to set CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG or CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE
This will work for MinSizeRel and RelWithDebInfo, plus any custom configurations one might add down the line.
Since it's defined as a cache variable, it can be overridden for debugging / working around name clashes, etc.
A bit more context for (3): most CMAKE_* variables are intended to be either read-only or user-configurable (i.e. at the command line, from the GUI, etc.). Overriding their defaults via set(CACHE) is a polite compromise. A notable exception to this rule is the collection of Qt codegen flags (CMAKE_AUTO{MOC,RCC,UIC}). These must typically be set for the build to produce usable binaries.
I want add_custom_command() to produce a different output depending on whether I'm building for Debug or Release (with a support for Visual Studio multi-configuration builds).
Essentially, I want to achieve something like:
add_custom_command(
OUTPUT $<IF:$<CONFIG:Debug>, file_to_generate_in_debug, file_to_generate_in_release>
COMMAND something.exe
...
)
Unfortunately, the generator expressions are not supported for the OUTPUT argument.
How should I do it using Modern CMake?
To make it more concrete, I'm trying to run windeployqt.exe to and my output should be either Qt5Core.dll or Qt5Cored.dll depending on the actual build configuration (which could either be known at Configure-time (e.g. for Ninja) or at Generate-time (e.g. for Visual Studio)).
Create as many add_custom_command as different OUTPUT you need to produce.
# A command which can be applied for Debug configuration(s)
add_custom_command(
OUTPUT file_to_generate_in_debug
COMMAND something.exe
...
)
# A command which can be applied for Release configuration(s)
add_custom_command(
OUTPUT file_to_generate_in_release
COMMAND something.exe
...
)
Only that instance will be active in a specific configuration which OUTPUT is used as DEPENDS in (other) add_custom_command/add_custom_target. Unlike to OUTPUT, DEPENDS clause supports generator expressions.
# This will chose a command suitable for configuration
add_custom_target(MY_GEN_LIB
DEPENDS $<IF:$<CONFIG:Debug>, file_to_generate_in_debug, file_to_generate_in_release>
)
If some other target needs your configuration-dependent output file, then you may adjust target-level dependencies:
# Depends from the target which produces required file
add_dependencies(other_target MY_GEN_LIB)
This will work even if the other target is an IMPORTED one.
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.
I hope the title clarifies what I want to ask because it is a bit tricky.
I have a SCONS SConscript for every subdir as follows (doing it in linux, if it matters):
src_dir
compiler
SConscript
yacc srcs
scripts
legacy_script
data
SConscript
data files for the yacc
I use a variant_dir without copy, for example:
SConscript('src_dir/compiler/SConscript', variant_dir = 'obj_dir', duplicate = 0)
The resulting obj_dir after building the yacc is:
obj_dir
compiler
compiler_compiler.exe
Now here is the deal.
I have another SConscript in the data dir that needs to do 2 things:
1. compile the data with the yacc compiled compiler
2. Take the output of the compiler and run it with the legacy_script I can't change
(the legacy_script, takes the output of the compiled data and build some h files for another software to depend on)
number 1 is acheived easily:
linux_env.Command('[output1, output2]', 'data/data_files','compiler_compiler.exe data_files output1 output2')
my problem is number 2: How do I make the script runner depend on outputs of another target
And just to clarify it, I need to make SCONS run (and only if compiler_output changes):
src_dir/script/legacy_script obj_dir/data/compiler_output obj_dir/some_dir/script_output
(the script is usage is: legacy_script input_file output_file)
I hope I made myself clear, feel free to ask some more questions...
I've had a similar problem recently when I needed to compile Cheetah Templates first, which were then used from another Builder to generate HTML files from different sources.
If you define the build output of the first builder as source for the second builder, SCons will run them in the correct order and only if intermediate files have changed.
Wolfgang
Does the objective-c compiler in Xcode know better, or is it faster if I use bit shift for multiplications and divisions by powers of 2?
NSInteger parentIndex = index >> 1; // integer division by 2
Isn't this a bit 1980's? Don't processors run these instructions in the same time these days? I remember back in my 68000 days when a div was 100+ cycles and a shift only 3 or 4... not sure this is the case any more as processors have moved on.
Why don't you get the compiler to generate the assembler file and have a look what it's generating and run some benchmarks.
I found this on the web which may help you... although it's for 'C' I think most of the options will be the same.
Q: How can I peek at the assembly code generated by GCC?
Q: How can I create a file where I can see the C code and its assembly
translation together?
A: Use the -S (note: capital S) switch to GCC, and it will emit the assembly code to a file with a .s extension. For example, the following command:
gcc -O2 -S -c foo.c
will leave the generated assembly code on the file foo.s.
If you want to see the C code together with the assembly it was converted to, use a command line like this:
gcc -c -g -Wa,-a,-ad [other GCC options] foo.c > foo.lst
which will output the combined C/assembly listing to the file foo.lst.
If you need to both get the assembly code and to compile/link the program, you can either give the -save-temps option to GCC (which will leave all the temporary files including the .s file in the current directory), or use the -Wa,aln=foo.s option which instructs the assembler to output the assembly translation of the C code (together with the hex machine code and some additional info) to the file named after the =.