Conan: [question] How to deploy conan libraries with my application using cmake install()

Created on 22 Jul 2020  路  8Comments  路  Source: conan-io/conan

I ported my cross-platform, modern CMake-based application to use Conan library packages with transparent integration (conan_paths.cmake). Build and tests are good.

When I run the installer (cmake --install | build INSTALL project), everything is installed into the correct location. Now I need to include the new Conan libraries.

Since imported targets cannot be directly installed via cmake install(), I use workarounds such as:

install(
  PROGRAMS $<TARGET_FILE:sometarget>
  DESTINATION ${CMAKE_INSTALL_BINDIR}
)

However, since the Conan library targets are imported as INTERFACE, those generator expressions don't work with _libname::libname_ targets defined in the generated Find_libname_ scripts. Using "$

I read the following:

Short of using a python script to convert the json deployment file into a cmake include with install(), I don't see any direct/easy way to deploy the Conan libraries.

What is the most efficient way to install Conan libaries along side my application for deployment?

triaging

Most helpful comment

I'll hijack this thread as i've recently stumbled upon this issue myself

I think the question is about easy global installation of conanfile targets (libs/bins) that are required for runtime to a designated prefix

  • /usr/local/{bin/lib}
  • /usr/local/xxx/{bin/lib}

In cmake current best way to achieve that is to add custom install step that executes
conan imports ${CMAKE_SOURCE_DIR}/conanfile.txt -imf ${CMAKE_INSTALL_PREFIX}

@memsharded would this be the best recommended way ?

All 8 comments

Hi @glennaycock

I think we need to understand the case a bit better, not fully sure I understood it. Let me summarize:

  • You are creating an application, but it is not a Conan package, just an application that would be using maybe a conanfile.txt to install dependencies.
  • You are using the cmake_paths generator, but at some point you are talking about the generated Find_libname scripts. Conan has the generator cmake_find_package and cmake_find_package_multi that generate these scripts on the fly, for every package, even if the origin package does not use CMake at all. Are you talking about these files, the Conan cmake_find_package generated files, or the files generated by CMake inside the packages?
  • Also, it seems that you are talking about the targets generated by Conan, so I would say you are not using the cmake_paths, but the cmake_find_package generator?
  • Then, you are able to build, link and run your app, locally? And your problem is to extract the information after that to distribute outside of Conan?

If that is the case, maybe you want to have a look to the imports functionality ([imports] in conanfile.txt,imports()in conanfile.py). With that you can define which files are imported from the cache to the local folder, with which patterns (*.dll), and how. This copy will be done automatically when you executeconan install``. Have a look to https://docs.conan.io/en/latest/using_packages/conanfile_txt.html#imports.

@memsharded,

Thanks for the quick response. I am responding to your summary points below:

  • You are creating an application, but it is not a Conan package, just an application that would be using maybe a conanfile.txt to install dependencies. YES - I am using conanfile.py
  • You are using the cmake_paths generator, but at some point you are talking about the generated Find_libname scripts. Conan has the generator cmake_find_package and cmake_find_package_multi that generate these scripts on the fly, for every package, even if the origin package does not use CMake at all. I am using a hybrid because I have some libraries that aren't in Conan yet. Are you talking about these files, the Conan cmake_find_package generated files, or the files generated by CMake inside the packages? I am referring to the find_package scripts _generated_ by conan.
  • Also, it seems that you are talking about the targets generated by Conan, so I would say you are not using the cmake_paths, but the cmake_find_package generator? I am using both -- see above.
  • Then, you are able to build, link and run your app, locally? And your problem is to extract the information after that to distribute outside of Conan? We are currently using a lot of shared libraries. I was continuing on this path, limiting the number of changes at once. However, it occurs to me that I could eliminate this problem entirely by statically linking. In fact, as I was working on a solution using the deploy generator, I realized most of the libraries Conan pulled in (on Windows) are static.

Hi @glennaycock

Ok, then. I think now I understand it better:

Let me know if that works ok. Thanks!

This led me down a path I didn't intend to take. I had to complete the conan build of my application, which I never intended to use, in order for imports() to work. In the course of doing so, I got side tracked trying to fix my other conan package.

I don't think static linking is going to work in the short term.

Hi @glennaycock

Sorry I didn't fully understand. I got that static linking is not going to work.

But I didn't get:

I had to complete the conan build of my application, which I never intended to use, in order for imports() to work.

Could you please clarify? Can you tell why imports() will not copy the DLLs or shared libraries from the packages to your local folder?

I'll hijack this thread as i've recently stumbled upon this issue myself

I think the question is about easy global installation of conanfile targets (libs/bins) that are required for runtime to a designated prefix

  • /usr/local/{bin/lib}
  • /usr/local/xxx/{bin/lib}

In cmake current best way to achieve that is to add custom install step that executes
conan imports ${CMAKE_SOURCE_DIR}/conanfile.txt -imf ${CMAKE_INSTALL_PREFIX}

@memsharded would this be the best recommended way ?

I have the same problem.

Project 1 Use Conan management to generate a .dll file and header file for use in other projects.
Project 2 only uses the product of Project 1, a .dll file and some header files.

If I define the imports function in the conanfile.py of project 2, I can copy the dynamic library of project 1 to the CMake cache directory.
But when I execute cmake install, it cannot install the files imported into the cache to the CMAKE_INSTALL_PREFIX folder that I specified when I initialized CMake.

@nmgwddj
I'm doing it via custom target

add_custom_target( conan-install COMMAND conan imports ${CMAKE_SOURCE_DIR}/conanfile.py -imf ${CMAKE_INSTALL_PREFIX} )

Was this page helpful?
0 / 5 - 0 ratings