cmake-basis / legacy

Legacy CMake BASIS project for versions 3.2 and older. For newer versions, go to
https://github.com/cmake-basis/BASIS
Other
13 stars 11 forks source link

Add HAVE_<PKG> definitions for found dependencies #503

Closed schuhschuh closed 8 years ago

schuhschuh commented 8 years ago

For optional dependencies, it is useful to have a compile definition for conditional code paths. Alternative name, HAS_<PKG>.

ahundt commented 8 years ago

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.

schuhschuh commented 8 years ago

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 .

schuhschuh commented 8 years ago

A HAVE_<PKG> compile definition is added for each found dependency (incl. required dependencies).

schuhschuh commented 8 years ago
schuhschuh commented 8 years ago

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...

schuhschuh commented 8 years ago

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.

ahundt commented 8 years ago

how would that work? perhaps there is a link to that functionality?

schuhschuh commented 8 years ago

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;
}
ahundt commented 8 years ago

looks good!