I am working on a project that uses ExternalProject, with BUILD_IN_SOURCE=TRUE, and the entire project (all of the sources and targets) are rebuilt every time, as though make is unable to see that the files already exist. My implementation looks like this:
# Need to explicitly enable ExternalProject functionality
include(ExternalProject)
# Download or update library as an external project
ExternalProject_Add(project_bdsg
GIT_REPOSITORY https://github.com/vgteam/libbdsg-easy.git
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/external/
CONFIGURE_COMMAND ""
UPDATE_DISCONNECTED True
BUILD_ALWAYS False
BUILD_IN_SOURCE True
INSTALL_DIR ${CMAKE_SOURCE_DIR}/external/bdsg/
INSTALL_COMMAND make INSTALL_PREFIX=${CMAKE_SOURCE_DIR}/external/bdsg/ install
)
# Define INSTALL_DIR as the install directory for external library
ExternalProject_Get_Property(project_bdsg INSTALL_DIR)
# Create new library for external project (so it can be linked with main library)
add_library(bdsg STATIC IMPORTED)
set_property(TARGET bdsg
PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libbdsg.a)
add_library(divsufsort STATIC IMPORTED)
set_property(TARGET divsufsort
PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libdivsufsort64.a)
add_library(libhandlegraph STATIC IMPORTED)
set_property(TARGET libhandlegraph
PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libhandlegraph.a)
add_library(libsdsl STATIC IMPORTED)
set_property(TARGET libsdsl
PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libsdsl.a)
# Define library as dependent on the downloaded project
add_dependencies(bdsg
project_bdsg
libsdsl
libhandlegraph
divsufsort)
# Define main library as dependent on the downloaded project (transitively)
add_dependencies(Bluntifier bdsg)
# Ensure that main library has access to primary dependencies' and secondary dependencies' headers
include_directories(external/bdsg/include/)
and I have targets defined like this:
add_executable(${FILENAME_PREFIX} src/test/${FILENAME_PREFIX}.cpp)
set_property(TARGET ${FILENAME_PREFIX} PROPERTY INSTALL_RPATH "$ORIGIN")
target_link_libraries(${FILENAME_PREFIX}
Bluntifier
Threads::Threads
bdsg
divsufsort
libhandlegraph
libsdsl)
Running make with some debugging output gives me messages like this:
Updating goal targets....
Considering target file 'CMakeFiles/Bluntifier.dir/build'.
File 'CMakeFiles/Bluntifier.dir/build' does not exist.
Considering target file 'Bluntifier.a'.
Considering target file 'CMakeFiles/Bluntifier.dir/link.txt'.
Finished prerequisites of target file 'CMakeFiles/Bluntifier.dir/link.txt'.
No need to remake target 'CMakeFiles/Bluntifier.dir/link.txt'.
Considering target file 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o'.
File 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o' does not exist.
Considering target file '../src/adjacency_components.cpp'.
Finished prerequisites of target file '../src/adjacency_components.cpp'.
No need to remake target '../src/adjacency_components.cpp'.
Considering target file '../external/bdsg/include/bdsg/internal/packed_structs.hpp'.
Finished prerequisites of target file '../external/bdsg/include/bdsg/internal/packed_structs.hpp'.
No need to remake target '../external/bdsg/include/bdsg/internal/packed_structs.hpp'.
Considering target file '../external/bdsg/include/handlegraph/expanding_overlay_graph.hpp'.
Finished prerequisites of target file '../external/bdsg/include/handlegraph/expanding_overlay_graph.hpp'.
No need to remake target '../external/bdsg/include/handlegraph/expanding_overlay_graph.hpp'.
Considering target file '../external/bdsg/include/handlegraph/handle_graph.hpp'.
Finished prerequisites of target file '../external/bdsg/include/handlegraph/handle_graph.hpp'.
No need to remake target '../external/bdsg/include/handlegraph/handle_graph.hpp'.
Considering target file '../external/bdsg/include/handlegraph/iteratee.hpp'.
Finished prerequisites of target file '../external/bdsg/include/handlegraph/iteratee.hpp'.
No need to remake target '../external/bdsg/include/handlegraph/iteratee.hpp'.
Considering target file '../external/bdsg/include/handlegraph/types.hpp'.
Finished prerequisites of target file '../external/bdsg/include/handlegraph/types.hpp'.
No need to remake target '../external/bdsg/include/handlegraph/types.hpp'.
Considering target file '../external/bdsg/include/handlegraph/util.hpp'.
Finished prerequisites of target file '../external/bdsg/include/handlegraph/util.hpp'.
No need to remake target '../external/bdsg/include/handlegraph/util.hpp'.
Considering target file '../external/bdsg/include/sdsl/bits.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/bits.hpp'.
No need to remake target '../external/bdsg/include/sdsl/bits.hpp'.
Considering target file '../external/bdsg/include/sdsl/config.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/config.hpp'.
No need to remake target '../external/bdsg/include/sdsl/config.hpp'.
Considering target file '../external/bdsg/include/sdsl/int_vector.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/int_vector.hpp'.
No need to remake target '../external/bdsg/include/sdsl/int_vector.hpp'.
Considering target file '../external/bdsg/include/sdsl/int_vector_buffer.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/int_vector_buffer.hpp'.
No need to remake target '../external/bdsg/include/sdsl/int_vector_buffer.hpp'.
Considering target file '../external/bdsg/include/sdsl/io.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/io.hpp'.
No need to remake target '../external/bdsg/include/sdsl/io.hpp'.
Considering target file '../external/bdsg/include/sdsl/iterators.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/iterators.hpp'.
No need to remake target '../external/bdsg/include/sdsl/iterators.hpp'.
Considering target file '../external/bdsg/include/sdsl/memory_management.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/memory_management.hpp'.
No need to remake target '../external/bdsg/include/sdsl/memory_management.hpp'.
Considering target file '../external/bdsg/include/sdsl/ram_filebuf.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/ram_filebuf.hpp'.
No need to remake target '../external/bdsg/include/sdsl/ram_filebuf.hpp'.
Considering target file '../external/bdsg/include/sdsl/ram_fs.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/ram_fs.hpp'.
No need to remake target '../external/bdsg/include/sdsl/ram_fs.hpp'.
Considering target file '../external/bdsg/include/sdsl/sdsl_concepts.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/sdsl_concepts.hpp'.
No need to remake target '../external/bdsg/include/sdsl/sdsl_concepts.hpp'.
Considering target file '../external/bdsg/include/sdsl/sfstream.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/sfstream.hpp'.
No need to remake target '../external/bdsg/include/sdsl/sfstream.hpp'.
Considering target file '../external/bdsg/include/sdsl/structure_tree.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/structure_tree.hpp'.
No need to remake target '../external/bdsg/include/sdsl/structure_tree.hpp'.
Considering target file '../external/bdsg/include/sdsl/uintx_t.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/uintx_t.hpp'.
No need to remake target '../external/bdsg/include/sdsl/uintx_t.hpp'.
Considering target file '../external/bdsg/include/sdsl/util.hpp'.
Finished prerequisites of target file '../external/bdsg/include/sdsl/util.hpp'.
No need to remake target '../external/bdsg/include/sdsl/util.hpp'.
Considering target file '../inc/adjacency_components.hpp'.
Finished prerequisites of target file '../inc/adjacency_components.hpp'.
No need to remake target '../inc/adjacency_components.hpp'.
Considering target file '../inc/subtractive_graph.hpp'.
Finished prerequisites of target file '../inc/subtractive_graph.hpp'.
No need to remake target '../inc/subtractive_graph.hpp'.
Considering target file '../inc/utility.hpp'.
Finished prerequisites of target file '../inc/utility.hpp'.
No need to remake target '../inc/utility.hpp'.
Pruning file '../src/adjacency_components.cpp'.
Pruning file 'CMakeFiles/Bluntifier.dir/flags.make'.
Finished prerequisites of target file 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o'.
Must remake target 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o'.
[ 38%] Building CXX object CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o
Successfully remade target file 'CMakeFiles/Bluntifier.dir/src/adjacency_components.cpp.o'.
where adjacency_components.cpp is one of several source files that are rebuilt every time I run make. Why does make conclude that it needs to rebuild these targets?
After looking further up in my debug output, it became apparent that cmake was tracking file timestamps from the downloaded content of the ExternalProject. Since it was redownloading every time I recompiled, there was always a fresh timestamp that cause all dependees to appear out of date in relative terms, which then triggered recompiling everything. To stop this temporarily, while developing, it is sufficient to add the following lines:
DOWNLOAD_COMMAND ""
UPDATE_COMMAND ""
to the ExternalProject arguments. Ideally this would be tied to a flag that the developer could invoke so that this is not the default behavior.
Related
I'm new to Cmake and I have a main output named TARGET. I'm trying to add custom target named _COPY_ASSETS_TARGET as a dependency to main TARGET. I want TARGET to rebuild _COPY_ASSETS_TARGET automatically if there's any change in _COPY_ASSETS_TARGET. _COPY_ASSETS_TARGET should depend on change in folders.
Here's the code I tried to implement:
if (NOT TARGET ${_COPY_ASSETS_TARGET})
add_custom_target(${_COPY_ASSETS_TARGET})
add_dependencies(${_ARGS_PROJECT_TARGET} ${_COPY_ASSETS_TARGET})
set_property(TARGET ${_COPY_ASSETS_TARGET} PROPERTY FOLDER "Targets")
endif()
add_custom_command(TARGET ${_COPY_ASSETS_TARGET}
${_COMMANDS}
VERBATIM
)
I'm trying visual studio to debug and if I rebuild _COPY_ASSETS_TARGET then only I can see the updated output. I would like to know how I can link my folders to _COPY_ASSETS_TARGET so that TARGET automatically builds new code
add_custom_command(OUTPUT ${OUTPUT_DIRECTORY} ${_COMMANDS}
DEPENDS ${DEPENDENT_DIRECTORY}
VERBATIM
)
add_custom_target(${_COPY_ASSETS_TARGET} ALL
DEPENDS ${OUTPUT_DIRECTORY}
)
add_dependencies(${_ARGS_PROJECT_TARGET} ${_COPY_ASSETS_TARGET})
set_property(TARGET ${_COPY_ASSETS_TARGET} PROPERTY FOLDER "Targets")
I found this to be working for my project
I have a custom build rule for a file type, which I setup according to this blog post. The build rule is working fine and my file is compiled.
But if I add a new file of this type to the project and I select the targets, the file is currently added to the "Copy Bundle Resources" phase. Instead, I'd like to have it added to the "Compile Sources" phase automatically (if I don't do this, the build rule won't kick in).
Is there a flag or something I can set so Xcode recognizes my files as "source files"?
As we known, we can set target membership for a certain file/bundle in right navigator of xcode.
But now I want to set target membership in a certain configuration. So how can I set target for a file/bundle in xcconfig file?
Many Thanks!
You could attach a build phase that:
runs before you copy bundles phase.
It would detect whether the config is Debug vs Release using ${CONFIGURATION}
and then copy the file into a location/name where it would then get picked up by the copy files phase.
I have a big C++ project and I need to do many steps in the building phase because I am building an application that is compatible with both 64 and 32, I have three projects:
proj1,Porj2,Proj3
and I need to do the following:
Exclude a cpp File from proj1 (32bit version)
Include a cpp file to proj1 (64bit version)
build proj1
build proj2
Execute output of proj2
Exclude a cpp File from proj3 (32bit version)
Include a cpp file to proj3 (64bit version)
Build proj3
Rename the exe that was built from proj3
Exclude a cpp File from proj1 (64bit version)
Include a cpp file to proj1 (32bit version)
still there are some other steps ... I was doing that manually and its frustrating, I found the I need to use MSBUILD but is it used for building native code ? and how can I perfrom these tasks ?
-Excluding and Including cpp files into projects
-Building proj
In Visual Studio 2010 and later, C++ projects use MSBuild.
Rather than excluding or including files based on the configuration, it would be simpler to use a preprocessor directive to conditionally compile the contents of the file. E.g., wrap the entire contents of the file in:
#ifdef MY_32BIT_BUILD_MACRO
// Source file contents here
#endif
And likewise with a macro for 64-bit builds. When using Visual C++, you can use the _M_IX86 and _M_X64 predefined macros to detect whether you are compiling for x86 or x64, respectively.
Alternatively, you could add a Condition property to the ClCompile item for the particular source file in the project file, and have it only included in the build when certain properties are set. I think that conditional compilation within the source file is a better option, though, unless you have complex rules that you need to use to determine whether to include a file or not.
In your solution, you can set project dependencies to ensure that one project is built before another. Right-click the solution, select Properties, and browse to Common Properties -> Project Dependencies. Dependencies can also be specified in a project file.
You can execute the output of a build by using a post-build task. Right-click the project, select Properties, and browse to Configuration Properties -> Build Events. The Post-Build event can be used to execute a command when the build has completed.
Rather than renaming an executable after build, it's easier to just have the build produce an executable with the right name. In the Project properties, under Configuration Properties -> General, the Target Name property can be used to set the name of the primary build output.
I am going to port the C project that was for unix into windows. So far, I could make it compile but not build . The problem I am getting is , some of the functions which are declared in the header files are defined in the yacc files.so I am getting the following errors:
error LNK2001: unresolved external symbol function_name
I am adding .y and .l files in the source directory of the project.I think I could not port yacc files into windows version or am I doing something stupid.I search it on web but could not get proper tutorial for it.Could you please let me know
How could I add .y or .l files in the project.
How would I make those file compatible to the windows?
How can I link them with other object files.
EDIT
I tried with changing the the .l files into the .yy.c files using the flex.exe.Following is the command for it
c:\> flex.exe name.l
Supposing that both the flex.exe and name.l are in C;>.And I loaded those all those files .l .y(previously present for parsing in unix system) .yy.c(corrsonding yacc file for windows) in the solution of previously exisiting project. Once I compile,I get the following
Can't read the header file parserheaderfile.h
This is the header file which needs to be generated by the bison in the unix
system. So I think I am not able to make the bison compatible for windows .So please him me how can I solve this problem?
Thanks in advance.
You need to add custom build rules for your .y and .l files. To do this, you need to
create one dummy .c file for the .l file and the .y file
add the .l, .y and both .c files to the project
right click on the .l file and select properties
Configuration->All Configurations
General->Item Type->Custom Build Tool
Apply
Custom Build Tool->General->Command Line->flex -olexer.c lexer.l
Custom Build Tool->General->Outputs->lexer.c
Custom Build Tool->General->Additional Dependencies->parser.y parser.c
Apply
select the .y file in the solution explorer
Configuration->All Configurations
General->Item Type->Custom Build Tool
Apply
Custom Build Tool->General->Command Line->bison -oparser.c parser.y
Custom Build Tool->General->Outputs->parser.c parser.h
Also you need to have flex.exe, bison.exe and m4.exe in the system search path. Another drawback is that VS does not get the dependencies right, so when you change something in the parser or lexer files, you need to manually rebuild the project.