add submodule (built with cmake) in qbs project - cmake

I'm using cmake to build my project now and I want to migrate to qbs in the future. I have some opensource sub-modules from github, which are currently built with cmake, and are included in my project using cmake's add_subdirectory.
I've tried to research but found no alternatives of add_subdirectory in qbs.
I don't think migrating all sub-modules build system from cmake to qbs is a good idea because that means I have to migrate sub of sub-modules or sub of sub of sub-modules as well :)
Any help? Thanks!

To pull in projects built with a different tool, you'll need some sort of wrapper. For instance, assuming your cmake sub-project is a library, you could write this (untested):
Product {
type: ["dynamiclibrary"]
Group {
files: ["subdir/CMakeLists.txt"]
fileTags: ["cmake_project"]
}
Group {
files: ["subdir/*"]
excludedFiles: ["subdir/CMakeLists.txt"]
fileTags: ["cmake_sources"]
}
Rule {
inputs: ["cmake_project"]
auxiliaryInputs: ["cmake_sources"]
Artifact {
filePath: ... // Whatever cmake produces
fileTags: ["dynamiclibrary"]
}
prepare: {
var cmd = new Command("cmake", [/*cmake arguments*/]);
cmd.description = "building cmake project xyz";
cmd.workingDirectory = product.sourceDirectory + "/subdir";
return [cmd];
}
}
}
You should probably tweak the cmake call so that the generated binaries end up in qbs's build directory.
There might be convenience functionality for this sort of thing in the future, if it turns out that there's a sensible abstraction level.

Related

How can I specify library path when using Meson?

I'm trying to build a c++ project with Meson.
The thing is, I have some libraries under /opt/conda
but can't figure out how to link the project when running meson build.
It seems to be only searching through /usr/lib directory.
As far as I understood, meson uses cmake and pkg-config to look for libraries.
Then would setting something like CMAKE_PREFIX_PATH be a feasible solution? and if so, how can I do that?
Thanks in advance.
I see two possible approaches to solve your problem.
the first solution uses LIBRARY_PATH, which is different from LD_LIBRARY_PATH as explained later.
the second solution uses a modified meson file to directly pass options to the linker. Optionally, it also uses rpath that eliminates the need to modify LD_LIBRARY_PATH afterward.
First solution
When building your project the linker use LIBRARY_PATH (and not LD_LIBRARY_PATH)
LIBRARY_PATH is used by gcc before compilation to search directories
containing static and shared libraries that need to be linked to your
program.
LD_LIBRARY_PATH is used by your program to search directories
containing shared libraries after it has been successfully compiled
and linked.
further details: LD_LIBRARY_PATH vs LIBRARY_PATH
Maybe you can try
export LIBRARY_PATH=/opt/conda/:$LIBRARY_PATH
before running meson to build your project.
Second solution
Modifying your meson file and use rpath (optional)
An alternative to the previous first solution is to directly modify your Meson file to pass some options to the linker.
Here is something I used in the past you can easily adapt to your problem:
#
# blaspp
#
blaspp_lib = 'blaspp'
blaspp_lib_dir = '/opt/slate/lib'
blaspp_header_dir = '/opt/slate/include'
blaspp_dep = declare_dependency(
link_args : ['-L' + blaspp_lib_dir, '-l' + blaspp_lib],
include_directories : include_directories(blaspp_header_dir))
executable('test_blaspp',
'test_blaspp.cpp',
build_rpath : blaspp_lib_dir,
install_rpath : blaspp_lib_dir,
dependencies : [blaspp_dep])
declare_dependency(...) defines options to pass to the linker (this replaces the need to define LIBRARY_PATH in the first solution)
executable(...) defines rpath. This is an optional step that embeds the extra library path information directly into the executable. If you use this, you will not have to modify the LD_LIBRARY_PATH when running your executable.
Further details: https://amir.rachum.com/blog/2016/09/17/shared-libraries/ (have a look at the "rpath and runpath" section) and see wikipedia: https://en.wikipedia.org/wiki/Rpath
If I understand the documentation correctly, you could use different / others build system as subproject, and it doesn't seem basing on cmake.
You should be able to define CMAKE_PREFIX_PATH in a CMakeList.txt of a cmake project, and access the generated library within meson context:
in your cmake subproject:
add_library(cm_lib SHARED ${SOURCES})
in your meson:
cmake = import('cmake')
# Configure the CMake project
sub_proj = cmake.subproject('libsimple_cmake')
# Fetch the dependency object
cm_lib = sub_proj.dependency('cm_lib')
executable(exe1, ['sources'], dependencies: [cm_lib])
if you only want to propagate any specific library to meson, than it looks like you'll need to bundle those third party library, or using built-in options.
But first of all: Have you check, either /opt/conda is in your LD_LIBRARY_PATH ?
Surprised no one mentioned it but this is how it is done from within meson.
CXX = meson.get_compiler('cpp')
libs_you_need_to_link = ['lib_a', 'lib_b', 'lib_c']
deps = []
foreach lib_name : libs_you_need_to_link
deps += CXX.find_library(lib_name, dirs : ['/opt/conda', '/other/path'])
endforeach

Does Conan support non-compiled packages?

I have a group of class files which are shared by several of our projects. We would like to start refactoring these classes, so I am starting by building a Conan package to allow us to version them. The sticky part is that they do not build on their own; there is coupling both ways between the shared classes and the consuming classes.
As such, I've been trying to build a Conan package which simply includes the .h & .cpp files but does not attempt to build them. My conanfile.py looks like this:
from conans import ConanFile, CMake
import os
class SharedcodeConan(ConanFile):
name = "SharedCode"
version = "1.0"
author = "me myemail"
description = ""
generators = "cmake", "visual_studio"
exports_sources = "*"
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
self.copy("*.h", dst="include")
self.copy("*.cpp", dst="src")
self.copy("*.rc", dst="src")
def package_info(self):
self.cpp_info.includedirs = ['include']
This all works well. I can create the package (specifying --test-folder=None). When I pull it down from Artifactory, the include & src folders contain the files I expect.
What I cannot figure is how to bring the .cpp files into my Visual Studio project. The Conan VS extension conveniently adds Visual Studio macros for the includes, linker, etc., but not for the source files. As such, my project finds the header files, but linking fails. In looking through the docs & the Conan source, I haven't seen an indication that this is currently possible.
Is there a way to dynamically reference the src folder?
Update: In light of the comments below stating this isn't supported currently, any workaround ideas are also welcome.

Meson: how to make find_library() works with an unusual path?

For my Meson project I have a dependency that is in an "unusual" place:
/opt/MyDependence/lib/libmyLib.so
/opt/MyDependence/include/myLib.hpp
My meson file is:
project('Test', ['cpp'])
cpp = meson.get_compiler('cpp')
myLib_dep = cpp.find_library('myLib', required: true)
Obviously Meson cannot find the library
Meson.build:5:0: ERROR: C++ library 'myLib' not found
The problem is that I do not know the "canonical" way to add extra search paths so that Meson can found my lib. Any idea?
update: please note that even if I use:
meson --libdir=/opt/MyDepedence/lib build
I get this error message:
meson.build:1:0: ERROR: The value of the 'libdir' option is '/opt/MyDepedence/lib' which must be a subdir of the prefix '/usr/local'.
Note that if you pass a relative path, it is assumed to be a subdir of prefix.
find_library now has an optional argument dirs (since 0.53.0) that indicates an extra list of absolute paths where to look for program names.
cpp = meson.get_compiler('cpp')
myLib_dep = cpp.find_library('myLib', dirs: '/opt/MyDepedence/lib', required: true)
I finally got a solution, one must use LIBRARY_PATH
export LIBRARY_PATH=/opt/MyDepedence/lib
meson build
Note: attention this is not LD_LIBRARY_PATH, see there for the difference
Also read this Meson/issues/217 . For Windows, the LIBRARY_PATH equivalent seems to be LIBPATH (but I was not able to check as I only run under Linux).
An alternative is to "manually" define a new dependence. In your Meson project:
project('Test, ['cpp'])
myLib_dep = declare_dependency(link_args : ['-L/opt/MyDependence/lib', '-lmyLib'],
include_directories : ['/opt/MyDependence/include'])
exe1 = executable('main', ['main.cpp'], dependencies : [myLib_dep])
A refinement that could be done is to store this "manual" setting into meson_options.txt.
Note: I finally answered my question, but I am still open to better solutions.
Standard way to solve this is to use pkg-config. In short, library installation procedure should include stage where special "mylib.pc" file is generated (from scratch, or typically from template "mylib.pc.in" - search in the internet, there are lots of examples). Then these small key-value files which has info on include/library dirs, dependencies, etc are installed to some known location, typically /usr/lib/pkgconfig/. Meson naturally runs pkg-config under the hood and finds your library when you have something like this
mylib_dep = dependency('mylib', required: true)
in your meson.build.
Update
Regarding libdir meson option error, you can try add option prefix as well:
meson --prefix=/opt/MyDepedence --libdir=lib build
Note also that with this command line you actually call implicitly setup command (there is no command build, since you will build with ninja) and build is a build directory that will be created using your options. Check this. That is why it is more visible to write:
meson setup build_dir --prefix=/opt/MyDepedence --libdir=lib

Is there is any way to build the Conan without cmake

I just started to explore both conan and cmake for building and packaging C++ files. Here is a sample conanfile.py
from conans import ConanFile, CMake
class PocoTimerConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
requires = "Poco/1.7.8p3#pocoproject/stable"
generators = "cmake", "gcc", "txt"
default_options = {"Poco:shared": True, "OpenSSL:shared": True}
def imports(self):
self.copy("*.dll", dst="bin", src="bin") # From bin to bin
self.copy("*.dylib*", dst="bin", src="lib") # From lib to bin
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
Is there any option to build the same without the use of cmake. Thanks in advance.
Yes, Conan is Cross platform, build system agnostic
There is a list with all integrations available, which includes MS Build, QMake and Autotools.
If you don't want to use integration tools, you can run directly the build commands, including running the compiler commands:
def build(self):
self.run("gcc ...")
No, Conan uses whatever build system the library is using, wrapping it. In this case, Poco is using the CMake build system, so CMake is necessary to build it. It is not possible to replace a given build system by another one automatically, that level of automation does not exist.
That doesn't mean that Conan needs CMake to operate. Conan can work with any build system, including proprietary ones. For example:
Creating and using packages with Visual Studio
Create and reuse packages with Makefiles
How to create integrations for new and custom build systems
Also, take into account that the build system used to create the package can be different to the one to consume that package. Conan "generators" can generate files for the consuming build system on the fly.
Maybe you are interested in the concept of "build-requires". You can use Conan to automatically install the cmake version that you want as a Conan package, and use it, injecting it automatically to packages to be build. Check the documentation of "build-requires" here

Integrating application Yocto arm bitbake

I'm trying to have my recipe be compiled and linked against the arm libraries. I'm using cmake. I can't seem to figure out the right work flow, after having read trough multiple documents on the yocto site and reference materials. My approach right now is:
Set the source
Build my target minal image, without the layer that I want to use
Try to build my specific recipe: bitbake Test
I have downloaded the arm toolchain from the Yocto site, and prepared it in my sources/poky. Here I can see the systroots and all the libraries that I would need. My recipe bb file is the following:
# This file was derived from the 'Hello World!' example recipe in the
# Yocto Project Development Manual.
#
SUMMARY = "Project"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://."
S = "${WORKDIR}/project/src"
inherit pkgconfig cmake externalsrc
And my CMake file contains, among more:
link_directories(/media/traffic/Yocto/QorIQ-SDK-V2.0-20160527-yocto/sources/poky/sysroots/aarch64-poky-linux/usr/lib)
I'm able to compile a hello world project fine, but as soon as external libraries take a role, it goes wrong.
cannot find /usr/lib/libpthread_nonshared.a
/media/traffic/Yocto/QorIQ-SDK-V2.0-20160527-yocto/build_ls2084abluebox/tmp/sysroots/x86_64-linux/usr/bin/aarch64-fsl-linux/../../libexec/aarch64-fsl-linux/gcc/aarch64-fsl-linux/4.9.3/ld: cannot find /usr/lib/libpthread_nonshared.a
It seems to look in the wrong folder. Are the steps that I'm taking correctly? Or am i missing something?
Elmar
Which poky version are you using? I got exactly the same issue recently with another package. There are 2 issues here:
It cannot find the pThread library. I added a FindThreads.cmake in the tree and imported it. But then the linker could not make it. I went to the conclusion, cmake itself had an issue with this library and ended changing the poky commit to have a different version of CMake. Note that you can also keep the new poky versions and have the custom CMake in your layer.
CMake 3.7 and 3.8.2 were not working properly but the 3.7.1 was for me (hash c9a512b6408d4cc11c1b36f7bc1b9b1c31056ce1). To find out which commit, you can execute
git log --pretty=oneline | grep cmake: