Closed schuhschuh closed 8 years ago
Good idea! I vote for HAVE
Good, I was also going to use it. It's just that the software I work on now used to to use HAS ... but I'd rather change the code to use HAVE.
On Sun, 27 Dec 2015 6:22 am Andrew Hundt notifications@github.com wrote:
Good idea! I vote for HAVE that is used by many large and widely used libraries, such as OpenCV for example. Haven't seen HAS nearly as often.
— Reply to this email directly or view it on GitHub https://github.com/schuhschuh/cmake-basis/issues/503#issuecomment-167388645 .
A HAVE_<PKG>
compile definition is added for each found dependency (incl. required dependencies).
Instead of adding only a single HAVE_<PKG>
definition for a package, it would also be good to have individual definitions for each component/module that was found. For example, HAVE_<PKG>_ComponentA
, HAVE_<PKG>_ComponentB
...
It may actually be better if (imported) targets (i.e., libraries build as part of a project module that were exported) would define HAVE_<PKG>_<TARGET>
as part of their INTERFACE_COMPILE_DEFINITIONS
.
This means CMake BASIS would need to require version 2.8.12 or later (or only use these target properties when available). I am happy to drop support for older CMake versions.
how would that work? perhaps there is a link to that functionality?
Using the target_compile_definitions and generator expressions. Not sure how this can be "supported" by BASIS. It may more or less be in the responsible of the project developers themselves.
Provider:
add_library(foo src/foo.cxx include/foo.h src/utils.h)
target_include_directories(foo PUBLIC include PRIVATE src)
target_compile_definitions(foo INTERFACE HAVE_FooProject_foo)
export(TARGETS foo NAMESPACE FooProject:: FILE FooExports.cmake)
Client:
find_package(FooProject COMPONENTS foo) # not REQUIRED
add_executable(bar bar.cxx)
if (TARGET FooProject::foo)
target_link_libraries(bar FooProject::foo)
# the following I believe is implicitly done by target_link_libraries already and should be skipped
target_compile_definitions(bar PRIVATE $<TARGET_PROPERTY:FooProject::foo,INTERFACE_COMPILE_DEFINITIONS>)
endif ()
Then, in the source code bar.cxx
, one can use the compile definition:
#include <iostream>
int main()
{
#ifdef HAVE_FooProject_foo
std::cout << "Enable features which depend on foo library" << std::endl;
#endif
return 0;
}
looks good!
For optional dependencies, it is useful to have a compile definition for conditional code paths. Alternative name,
HAS_<PKG>
.