Is it possible to add an external project in CMake but to exclude it from the all build target?
I've looked at the EXCLUDE_FROM_ALL option which is used with ADD_EXECUTABLE but I don't think this works with an external project.
Alternatively I'd be happy if I could change the default target for CMake, but I I think that's hard-coded to all.
For the project that I'm working on I am generating Unix Makefiles with CMake and right now I'm using CMake version 2.8.10.2.
Even if the option EXCLUDE_FROM_ALL is not used upon adding the target by the ExternalProject_add command, the option can be activated retroactively by setting the EXCLUDE_FROM_ALL property of the external project target, i.e.:
ExternalProject_add(MyExternal
URL ... )
set_target_properties(MyExternal PROPERTIES EXCLUDE_FROM_ALL TRUE)
Related
My project consists of multiple targets. I want to specify compile options for all of them with
command "target_compile_options"
I get a list of targets using macros from CMake - remove a compile flag for a single translation unit:
macro(apply_global_cxx_flags_to_all_targets)
separate_arguments(_global_cxx_flags_list UNIX_COMMAND ${CMAKE_CXX_FLAGS})
get_property(_targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
foreach(_target ${_targets})
target_compile_options(${_target} PUBLIC ${_global_cxx_flags_list})
endforeach()
unset(CMAKE_CXX_FLAGS)
set(_flag_sync_required TRUE)
endmacro()
But I receive errors:
target_compile_options called with non-compilable target type
as some of targets doesn't require compiling. Is there a way to check if project is compilable? I want to use "target_compile_options as I need to remove some options for one subproject (as in mentioned thread)
Is there a way to check if project is compilable?
Yes, get the type of the target and check if it's an executable or a library and if it's not an INTERFACE library.
I want to specify compile options for all of them
Consider using add_compile_options at root folder instead.
I have a cmake project that uses an external project using CMake's ExternalProject_Add feature. Is there a way to set policy and property on the external project?
I would like following policy and property that is set in my project to be forwarded also to external project so that static multi-threaded windows runtime libraries are used instead of dynamic ones.
cmake_policy(SET CMP0091 NEW)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
You can simply add those settings to the CMAKE_ARGS variable of the ExternalProject_Add command, e.g.
ExternalProject_Add(<you_name_it>
...
CMAKE_ARGS
-DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW
-DCMAKE_MSVC_RUNTIME_LIBRARY:STRING=MultiThreaded$<$<CONFIG:Debug>:Debug>
...
)
I don't need ALL_BUILD subproject, can I avoid generating it? Thanx.
CMake Issue #16979: "ALL_BUILD target being generated":
The ALL_BUILD target corresponds to CMake's notion of the "all" target, equivalent to make all with makefile generators. This is different from "Build Solution" behavior due to idiosyncrasies in how the VS IDE deals with inter-vcxproj dependencies.
There is no way to suppress the ALL_BUILD target. It must exist for commands like cmake --build. to be able to build the "all" target by default.
So you can't avoid it - as with #arrowd answer - but there are some things in CMake that can influence the usage/appearance (on IDE generators like Visual Studio) of it:
When you activate global USE_FOLDERS property
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
the generic targets ALL_BUILD, ZERO_CHECK, INSTALL, PACKAGE and RUN_TESTS will be grouped into the CMakePredefinedTargets folder (or whichever name is given in global PREDEFINED_TARGETS_FOLDER property).
The global variables CMAKE_SKIP_INSTALL_ALL_DEPENDENCY and CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY do suppress otherwise automatically generated dependencies for INSTALL or PACKAGE to the ALL_BUILD target.
The global VS_STARTUP_PROJECT property can be used to change the default startup project name to something other than the ALL_BUILD or "first project not in sub-folder" targets.
References
What are ALL_BUILD and ZERO_CHECK and do I need them?
How to skip dependency on all for package target?
No CMakePredefinedTargets when using solution folders
It corresponds to the all make target, so, no, you can't avoid generating it. You can delete it from the solution manually, though.
I've got a cmake project that builds multiple executables and shared
libraries. There are option() settings that determine which of these
executables are built. What I'd like to be able to do is prevent the
building and installation of shared libraries that are not required. So
what I did is as follows:
set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY TRUE) on the top level
CMakeLists file
add_library(${SHARED_LIBRARY} SHARED EXCLUDE_FROM_ALL ...)
install(TARGETS ${SHARED_LIBRARY} DESTINATION ${DESTINATION} OPTIONAL)
These three settings result in the desired behaviour. However, cmake
generates the following warning:
WARNING: Target "xxxx" has EXCLUDE_FROM_ALL set and will not be built by
default but an install rule has been provided for it. CMake does not
define behavior for this case.
Is this warning still valid in this specific scenario?
If so is there another/more correct way to achieve what I want?
If what I'm doing is acceptable, is there a way to suppress this
warning?
Thank you
My Mercurial repository repo1 has a custom target named foo; never mind what it does. I also have another repository repo2, which which I want to use as a subrepo of repo1. repo2 is developed in a similar fashion to repo1, and also has a custom target named foo, doing about the same thing (but just for the repo2 directory of course).
If I try to run CMake for repo1 with add_subdirectory(relative/path/to/repo2) in the CMakeLists.txt, I get:
CMake Error at CMakeLists.txt:123 (add_custom_target):
add_custom_target cannot create target "foo" because another target with
the same name already exists. The existing target is a custom target
created in source directory
I suppose I could just prefix the custom target names with the repository names, but that seems like a crude solution to this problem; and I kind of like the fact that make foo does the same thing, conceptually, both in repo1 and in repo2. So is there anything smarter I can do here?
Approach depends on what you expect from
make foo
Building target only for current project. That is, being run from directory of project1, make foo should build target for this project. Same for project2.
In that case, use ExternalProject_Add instead of add_subdirectory for bind projects together.
Building targets for both projects.
Usually such targets are "project-wide actions", like make uninstall or make test.
In that case, before adding the target into the project, you need to check whether target exists and take appropriate actions:
if(NOT TARGET foo)
<create target foo>
endif()
<append-new-actions-to-foo>
Steps "create" and "append" depend on target type.
E.g., classic uninstall target automatically process all subprojects via reading install_manifest.txt file:
if(NOT TARGET uninstall)
add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
For general case, you may create per-project targets and attach them via add_dependencies to the "shared" target:
if(NOT TARGET foo)
add_custom_target(foo)
endif()
add_custom_target(foo_${CMAKE_PROJECT_NAME} <do-something>)
add_dependencies(foo foo_${CMAKE_PROJECT_NAME})