TL;DR: In the following MsBuild output, what do the file names (sourceFile1.cpp ~ sourceFileX.cpp) that come after the cl command mean? (scroll down for a link to an actual log file)
ClCompile:
cl.exe <args> <includeDirs> <sourceFile1.cpp sourceFile2.cpp ... sourceFileN.cpp>
sourceFile1.cpp # what do these mean?
sourceFile2.cpp
...
sourceFileX.cpp
The N and X are deliberately different variables.
Long:
Context: I'm modifying CppMicroServices library's CMake configuration to be biicode compatible.
Building with the original configuration produces the above output, with N == X, i.e. all files passed to the cl command are also output on the subsequent lines. This compiles fine on Ubuntu 14.10, and Windows 8.1.
Building using the biicode-modified CMakeLists.txt produces a similar output, but N != X. N is the same for both the biicode output and the original, but X for biicode is a much smaller subset of the source files compared to X from the original.
A full log file of this is here: http://pastebin.com/hRi8WGwN
Lines 56 ~ 100: output that matches the original build target (43 source files passed to cl, 43 lines follow with the same source file names).
Lines 183 ~ 192: output for the bii-specific target (43 source files passed to cl, 8 lines of some source file names, followed by some errors which I assume will be fixed when this is solved).
The biicode specific target builds fine on Ubuntu.
The files in the list are the ones that the compiler is supposed to be compiling. It prints them out one by one as it compiles them. If it encounters any errors while compiling, the errors and a reference to the source file they were encountered in will be interspersed with the list of source files that are being compiled.
Related
Imagine a code generator which reads an input file (say a UML class diagram) and produces an arbitrary number of source files which I want to be handled in my project. (to draw a simple picture let's assume the code generator just produces .cpp files).
The problem is now the number of files generated depends on the input file and thus is not known when writing the CMakeLists.txt file or even in CMakes configure step. E.g.:
>>> code-gen uml.xml
generate class1.cpp..
generate class2.cpp..
generate class3.cpp..
What's the recommended way to handle generated files in such a case? You could use FILE(GLOB.. ) to collect the file names after running code-gen the first time but this is discouraged because CMake would not know any files on the first run and later it would not recognize when the number of files changes.
I could think of some approaches but I don't know if CMake covers them, e.g.:
(somehow) define a dependency from an input file (uml.xml in my example) to a variable (list with generated file names)
in case the code generator can be convinced to tell which files it generates the output of code-gen could be used to create a list of input file names. (would lead to similar problems but at least I would not have to use GLOB which might collect old files)
just define a custom target which runs the code generator and handles the output files without CMake (don't like this option)
Update: This question targets a similar problem but just asks how to glob generated files which does not address how to re-configure when the input file changes.
Together with Tsyvarev's answer and some more googling I came up with the following CMakeList.txt which does what I want:
project(generated)
cmake_minimum_required(VERSION 3.6)
set(IN_FILE "${CMAKE_SOURCE_DIR}/input.txt")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${IN_FILE}")
execute_process(
COMMAND python3 "${CMAKE_SOURCE_DIR}/code-gen" "${IN_FILE}"
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
INPUT_FILE "${IN_FILE}"
OUTPUT_VARIABLE GENERATED_FILES
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_executable(generated main.cpp ${GENERATED_FILES})
It turns an input file (input.txt) into output files using code-gen and compiles them.
execute_process is being executed in the configure step and the set_property() command makes sure CMake is being re-run when the input file changes.
Note: in this example the code-generator must print a CMake-friendly list on stdout which is nice if you can modify the code generator. FILE(GLOB..) would do the trick too but this would for sure lead to problems (e.g. old generated files being compiled, too, colleagues complaining about your code etc.)
PS: I don't like to answer my own questions - If you come up with a nicer or cleaner solution in the next couple of days I'll take yours!
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?
This question is subsequent to my previous one: How to integrate such kind of source generator into CMake build chain?
Currently, the C source file is generated from XS in this way:
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${file_src_by_xs} PROPERTIES GENERATED 1)
add_custom_target(${file_src_by_xs}
COMMAND ${XSUBPP_EXECUTABLE} ${XSUBPP_EXTRA_OPTIONS} ${lang_args} ${typemap_args} ${file_xs} >${CMAKE_CURRENT_BINARY_DIR}/${file_src_by_xs}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${file_xs} ${files_xsh} ${_XSUBPP_TYPEMAP_FILES}
COMMENT "generating source from XS file ${file_xs}"
)
The GENERATED property let cmake don't check the existence of this source file at configure time, and add_custom_target let the xsubpp always re-run at each compile. The reason for always rerun is because xsubpp will generate an incomplete source file even if it fails, so there are possibility that the whole compiling continues with an incomplete source file.
I found it is time consuming to always re-run source generator and recompile it. So I want to have it re-run only when dependent XS files are modified. However, if I do so, the incomplete generated source file must be deleted.
So my question is: is there any way to remove the generated file, only when the program exit abnormally at compile time?
Or more generic: is there any way to run a command depending on another command's exit status at compile time?
You can always write a wrapper script in your favorite language, e.g. Perl or Ruby, that runs xsubpp and deletes the output file if the command failed. That way you can be sure that if it exists, it is correct.
In addition, I would suggest that you use the OUTPUT keyword of add_custom_command to tell CMake that the file is a result of executing the command. (And, if you do that, you don't have to set the GENERATED property manually.)
Inspired by #Lindydancer's answer, I achieved the purpose by multiple COMMANDs in one target, and it don't need to write an external wrapper script.
set(source_file_ok ${source_file}.ok)
add_custom_command(
OUTPUT ${source_file} ${source_file_ok}
DEPENDS ${xs_file} ${xsh_files}
COMMAND rm -f ${source_file_ok}
COMMAND xsubpp ...... >${source_file}
COMMAND touch ${source_file_ok}
)
add_library(${xs_lib} ${source_file})
add_dependencies(${xs_lib} ${source_file} ${source_file_ok})
The custom target has 3 commands. The OK file only exists when xsubpp is success, and this file is added as a dependency of the library. When xsubpp is not success, the dependency on the OK file will force the custom command to be run again.
The only flaw is cross-platform: not all OS have touch and rm, so the name of these two commands should be decided according to OS type.
I have put these two lines in my Findglm.cmake file to point to the headers for this header library.
find_path(glm_INCLUDE_DIR NAMES glm.hpp matrix_transform.hpp type_ptr.hpp PATHS
${CMAKE_SOURCE_DIR}/libs/glm-0.9.3.2/glm ${CMAKE_SOURCE_DIR}/libs/glm-0.9.3.2/glm/gtc
${CMAKE_SOURCE_DIR}/libs/glm-0.9.3.2/glm/gtx ${CMAKE_SOURCE_DIR}/libs/glm-0.9.3.2glm/core)
set(glm_INCLUDE_DIRS ${glm_INCLUDE_DIR})
However when I generate my Xcode project it says that it cannot locate matrix_transform.hpp and type_ptr.hpp
I have played around with this some more it appears to only find the first argument I am wondering if I am using find path wrong ?
I am using cmake 2.8.8 darwinports.
The find_path() command returns single directory. In your case, it's the first dir, which contains the first file.
If this glm will be always located in your source dir, it would be sufficient to do
include_directories(${CMAKE_SOURCE_DIR}/libs/glm-0.9.3.2/glm
${CMAKE_SOURCE_DIR}/libs/glm-0.9.3.2/glm/gtc
${CMAKE_SOURCE_DIR}/libs/glm-0.9.3.2/glm/gtx
${CMAKE_SOURCE_DIR}/libs/glm-0.9.3.2/glm/core)
The find_path() is used to determine dir somewhere outside of your project.
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