I'm using Conan as a dependency manager for C++ and I want to create a package which requires a compiled file from another, already created, Conan-package. I'm currently trying to create a package for the OpenStreetMap-Library OSM-binary (https://github.com/scrosby/OSM-binary.git).
The Makefile for this project (which can be found at ./OSM-binary/src/Makefile) requires a file called protoc from the protobuf-project (https://github.com/google/protobuf). This protoc-file can be found after compiling the protobuf-project in ./protobuf/src.
Without this file compiling the OSM-sources will fail with an error: make: ../protoc: Command not found
The Problem
As conan's documentation suggests to copy my needed files to folders in my package, e.g header-files to ./include, libs to ./lib, etc. According to this, after building the protobuf-project via make, I'm copying the mentioned file via
def package(self):
self.copy("*.so", dst="lib", keep_path=False)
self.copy("protoc", dst="scripts", src="./protobuf/src")
to an folder called "scripts".
But at this point the black magic starts. My first question is, how can I access any of these packed files (e. g. the *.so files or any other files (here the protoc-file) which are present in an package) from another package? For me, even after reading conan's documentation, it's not clear how conan stores it's packed files and how to access these or any other files packed in the previous step.
Now back at the OSM-Project my approach would be setting the correct path manually in the Makefile via the tools.replace
command.
First I declared the protobuf-packaged as an requirement
requires = "protobuf/2.5.0@test/testing"
and replaced the corresponding lines (in version 1.3.3, line 7) in the osm-Makefile with the correct path to the protoc-file.
tools.replace_in_file("OSM-binary/src/Makefile",
"PROTOC ?= protoc",
"PROTOC ?= <path-to-file>/protoc")
Now this leads us to my actual question: How do I get the path to the protoc-file which can be found in the protobuf-package in a folder called scripts, or is there any other way to do it?
Thanks, Chris
There are different ways to access files from your dependencies:
If you want to directly run some file from your dependencies, you could use the self.run(...., run_environment=True)
, that will automatically set the PATH, LD_LIBRARY_PATH, etc so the binaries are found in the place where the package is installed. Find more information here
You can directly import
the files you want from your dependencies, doing a copy (which is done before the build()
method) of such files into the build folder, so they can be directly used there. The path you can use in your script is the current one, or self.build_folder
. The imported files will be automatically removed after build, so they are not accidentally repackaged. Check imports docs
You can obtain information from your dependencies from the self.deps_cpp_info
attribute. Check the reference here. That means you can get the paths to your protobuf
dependency with something like
def build(self): # Get the directory where protobuf package is installed protoc_root = self.deps_cpp_info["protobuf"].rootpath # Note this is a list protoc_bin_paths = self.deps_cpp_info["protobuf"].bin_paths