question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[feature] CMake generator: custom target

See original GitHub issue

Hi!

After the feature https://github.com/conan-io/conan/pull/5598, which helped a lot with cmake_find_package, now we have another cmake situation which can be solved with a new feature.

I’ll try to illustrate using a real case, Protobuf. This package was divided in two, the library (libprotobuf, libprotoc, libprotobuf-lite) and the compiler (.proto parser). The parser can be invoked from Cmake, using macros to generate both headers and sources:

cmake_minimum_required(VERSION 2.8.12)
project(test_package CXX)

find_package(protoc)   # protoc/3.9.1@
find_package(Protobuf) # protobuf/3.9.1@

PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS addressbook.proto)
add_executable(${CMAKE_PROJECT_NAME} "${PROTO_SRCS}" example.cpp)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC protobuf::protobuf)

Using cmake_find_package, Conan will provide Findprotoc.cmake, which has the CMake target protoc::protoc, and for cmake generator we will have CONAN_PKG::protoc from conanbuildinfo.cmake.

However, those macros are looking for the original target, protobuf::protoc. We could patch those cmake files, but this problem also could be avoided using a custom target:

def cpp_info(self):
    self.cpp_info.target = "protobuf::protoc"

Now the cmake_find_package can use this new custom target name and all cmake files imported from protobuf will work straightforward.

The current PR #5408 is adding new feature to self.cpp_info. Similar to this feature request.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:17 (15 by maintainers)

github_iconTop GitHub Comments

3reactions
KerstinKellercommented, Nov 19, 2019

As for the special case of Protobuf and cross compiling:

I think for many people, it would be a nogo / step backward to do the proto file compilation before entering cmake.

If you are cross-compiling, usually you would install the package for both build and target architecture. You would then pass a -DProtobuf_PROTOC_EXECUTABLE=/path/to/my/build/system/protoc. Then the find_package(Protobuf REQUIRED) command would locate your cross build Protobuf libraries, but the cmake scripts will use your build system protoc compiler to do the *.proto file compilations. Things might just work fine, too, if the build protoc compiler is in the system path.

During the CMake execution it is also asserted that protoc and protobuf library versions match, otherwise CMake will error out.

At least this works with the FindProtobuf.cmake that is distributed with CMake, I don’t know about their config mode.

For our own packages that come with a “compiler” such as protoc, we create a pattern such as this

INCLUDE("@PACKAGE_xxx_INSTALL_CMAKE_DIR@/xxxTargets.cmake")
IF (CMAKE_CROSSCOMPILING)
  IF (NOT XXX_COMPILER)
    FIND_PROGRAM(XXX_COMPILER xxxc HINTS ${XXX_COMPILER_PATH_HINT})
  ENDIF () 
  IF (XXX_COMPILER)
    ADD_EXECUTABLE(xxx::xxxc IMPORTED)
    SET_TARGET_PROPERTIES(xxx::xxxc PROPERTIES
      IMPORTED_LOCATION "${XXX_COMPILER}"
    )  
  ELSE ()
    MESSAGE(ERROR "You are cross-compiling but xxx needs to locate the xxxc program on your host system. Make sure it is installed and set the XXX_COMPILER_PATH_HINT variable.")
  ENDIF ()  
ELSE ()
  INCLUDE("@PACKAGE_xxx_INSTALL_CMAKE_DIR@/xxxcTargets.cmake")
ENDIF ()

What this means is, when you do a find_package, the targets are always included. The targets for the compiler are only included when not cross compiling. When cross compiling an imported target is created instead.

1reaction
uilianriescommented, Jul 29, 2020

@danimtb No, we are good to go.

Read more comments on GitHub >

github_iconTop Results From Across the Web

add_custom_target — CMake 3.25.1 Documentation
Adds a target with the given name that executes the given commands. The target has no output file and is always considered out...
Read more >
generator expression in add_custom_target - Stack Overflow
I'm trying to create a cmake (3.22) function that creates a target called cppclean for the target that I provide in the arguments...
Read more >
CMake Generator-Expressions | Jeremi Mucha
Both alternatives have their nuisances – generating a file requires us to get to the contents of the file and using a custom...
Read more >
CMake customization points, how to configure your project?
We will now dive deeper and look into more advanced features so that you can customize your project. This is an important part...
Read more >
Feature Request: add_custom_command(TARGET) for ...
Note that at this point in my cmake code, the target does not yet ... the use of target specific properties generator expressions...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found