What to resolve the dependencies between jemalloc and pthread in cmake? - pthreads

I have a project that depends on jemalloc as an external library. jemalloc depends on pthread in turn. In cmake, how can I specify the dependency between these two libraries?
So far I tried:
target_link_libraries(jemalloc pthread) which doesn't work because jemalloc is an external library
target_link_libraries(current_library jemalloc pthread) which works, but it's inconvenient to specify pthread after jemalloc in all libraries where jemalloc is used. I also need to add jemalloc pthread for every executable and test.

You can set the imported library's IMPORTED_LINK_DEPENDENT_LIBRARIES and/or IMPORTED_LINK_INTERFACE_LIBRARIES properties to specify the dependency.

I don't think there's a way to "properly" specify a dependency between two external libraries like this.
The best you can probably do is something like find_library for each, and with the results (assuming they're both found correctly) set a single variable representing both libraries.
So, something like:
find_library(JemallocLib jemalloc)
find_library(PthreadLib pthread)
set(JemallocLibs ${JemallocLib} ${PthreadLib})
Then you can just do e.g.
target_link_libraries(MyLib ${JemallocLibs})
target_link_libraries(MyExe MyLib) # automatically links jemalloc and pthread too

Related

bazel: link to library that lacks 'lib' prefix

I have an external library ace.so.
cc_library(
name='ace',
hdrs=glob(['path/to/ace/**']),
srcs=['path/to/ace.so'],
)
How do I go about linking to that library with bazel? I know a colon can be used when invoking gcc/g++ directly, but I'm not sure how to get the same behavior from bazel.
I tried adding -l:ace.so (also -Wl,-l:ace.so) to copts but it seems bazel doesn't pass that to gcc or add it to the # file used for linker args.
I tried nocopts='-lace.so' in combination with linkopts=['-l:ace.so']. No luck.
I also tried cc_import instead of cc_library, but that didn't work either.
I've read the Importing precompiled C++ libraries doc, but I didn't see anything about using libs with an arbitrary prefix - or with no prefix.
As a temporary fix, I've added a symlink libace.so pointing to ace.so and changed the srcs line to match. While this works, I'd much rather convince bazel to use the lib as is.
Looking around how information about libraries is being collected and passed around, I am afraid this (assumption that "plain" dynamic libraries are prefixed with lib and libfoo.so can be given as -lfoo is fairly hard coded at the moment. The same would not be true of it was considered a "versioned" (matches a pattern "^.+\\.so(\\.\\d+)+$") dynamic library, which would be passed as -l:foo.so.1. But unfortunately that does not really help you, because you'd still need to employ a similar workaround and create a fiction of versioning to boot. That said, as long as your solib filenames are given, the symlink sounds like a reasonably sane workaround.

Using open source while writing a library in Swift

I'm trying to find more information / explanation for the following scenario:
I'm writing a library in Swift and would like to use some open source library in it.
If I just integrate them into my library, is there a chance of namespace collision?
What would happen if the host app will use:
The exact same open source library
The same library but different version
Does using CocoaPods changes something here?
Consider a scenario where I import AFNetworking for example (via CocoaPods) in my library, and the host app will use it too.
Using the same library, you won't have any issues. Using different version will likely cause problems, but that is going to be dependent on the changes made in the different versions.
Namespace collisions in Swift are rare. As #mattt stated, each module acts as a namespace, so naming conflicts with classes or functions from another module won't exist as they do in Objective-C. If you have a naming conflict, the compiler will tell you. In that case, you can just prefix the conflicting signature with the module name.
I would highly recommend you use Cocoapods for dependency management. It handles version control and will make your life much easier.

Which malloc will be called?

I want to adopt jemalloc in my project. In order to call the malloc() function in jemalloc, I included jemalloc/jemalloc.h in the .cpp files. However, inevitably I should also call some function provided in cstdlib.h. So both jemalloc/jemalloc.h and cstdlib.h are included. I am wondering in this case, which malloc() will be called? And how can I guarantee the malloc() from jemalloc will be called? Thanks in advance!
You need to link your application against the jemalloc library (add -L/path/to/jemalloc/lib -ljemalloc to the link command), which will cause the dynamic loader to resolve all calls to malloc(), free() etc. to the jemalloc versions. An easy way to tell if jemalloc is actually being used is to define MALLOC_CONF=stats_print:true in the environment, which will cause jemalloc to dump statistics to stderr just before program exit.
You have to tell the linker to use jemalloc, which you can do by setting an environment variable before running your program:
LD_PRELOAD=/path/to/lib/libjemalloc.so.1 your_program

Include libraries in iOS library project

I am writing an iOS library which depends on some other open-source libraries. Apparently it is not possible to have two classes with the same name, so it is possible that the library compiles, and a project that potentially could use it compiles as well, but they do not work well together (at the linking phase).
The library is targeted at a large audience, so I can not make any assumptions on whether these developers will be importing the same libraries or not, or if they might be using a different, incompatible version of the same libraries.
I have been looking around but couldn't find any clear solution to my problem (maybe there isn't). So far I am thinking of these options:
Inform the users that X libraries are already included in the project, so they do not include them as well. This means they can not use a different version of X libraries.
As a refined version of the first one, use CocoaPods, so dependencies are resolved automatically. Still has the disadvantage that two versions of the library can not coexist.
Import and rename all classes my library depends on, prefixing them, so the names don't conflict with the original ones. This is tedious work, but more importantly, has the disadvantage that I would not be able to pull/push code from/to the original library, as the code would change too much. Still seems to me the best option from the user perspective.
Can you think of a better idea? I'm pretty new to library projects, so maybe there is something obvious I am missing.
We're still not decided whether to distribute in binary or source code form. If there is a reason to choose one or another I would also like to hear your opinion.
When I was faced with this problem I choose your third option and prefixed the dependent classes within my library. The reason you might want to consider doing this rather than relying on the user to import the others would be that you can guarantee compatibility and you don't have to worry about versions of who you depend on.
First point -
Inform the users that X libraries are already included in the project,
so they do not include them as well
so you have a static library Foolib.a, it has a 3rd party dependency Barlib.a, in order for Foolib to build, Foolib's HEADER_SEARCH_PATHS must be set to the path of Barlib's public headers. No more.
If you are distributing your source code you can use CocoaPods (this is a good way to go), or you can add Barlib's repository as a git submodule (or whatever for your choice of VCS) of your repository and hard code the HEADER_SEARCH_PATHS to that path, or you can require that your user grabs their own Barlib and manually edits HEADER_SEARCH_PATHS to the correct path (if you go the CocoaPods or submodule route the user can easily do this as well, so has more options).
Nothing from Barlib is 'in' your project.
On the other hand, if you are distributing a binary for your user to link into their app you must specify in your instructions that Foolib requires Barlib to be linked into the app. Instructions for how to get hold of Barlib would be nice.
Nothing from Barlib is 'in' your project or compiled into your library.
Second Point -
use CocoaPods, so dependencies are resolved automatically. Still has
the disadvantage that two versions of the library can not coexist
Two versions of the same library in one App is impossible, but the situation where the end user already requires Barlib 3.0, wants to use your Foolib, but Foolib requires Barlib 4.0 doesn't have to ever arise - It is up to you the developer. You can be generous and support multiple versions of Barlib (i.e. all Foolib needs to work is a Barlib1.0, Barlib2.0, Barlib3.0 OR Barlib4.0 linked into the app - similar to writing an app that supports iOS5 and iOS6) or, you can be opinionated and require a specific version, and if the user is already requiring a different version of Barlib, tough luck, they will have to change their code if they want to use your library.
Third point -
Import and rename all classes my library depends on, prefixing them,
so the names don't conflict with the original one
This is just too terrible for me to consider at the moment. Sorry.
Nothing from Barlib is ever 'in' your project or compiled into your library. You don't distribute any copy of Barlib - either linked into your binary or as source code.

How to include the boost library in a C++ application?

I'm very inexperienced with Linux and the terminal, but I'm trying to learn. I've also never included an external library before. Now I need to include the Boost.Asio library in a program being developed in Ubuntu with G++.
Could someone very kindly and very carefully explain how to go about this, from the beginning?
EDIT:
Expanding on the original question: if I need to send this code to someone else for them to run it on a completely separate machine but in the same environment, how do I take that into account? If this whole process involves literally placing library files into the same folder as the code, do I just send those library files along with the .cpp to this other person?
You have mentioned you are using Ubuntu, so the simplest way to use boost is to first install libboost-all-dev package (from synaptic), which will install everything for you including those that needed to be compiled. Then you just need to use g++ in the usual way.
Please note that whether the version is what you want, if not, you may want to install it yourself. On the other hand, boost is mostly header only library, so you only need to extract the files (right click in Ubuntu...) to a folder and link to it while compiling:
g++ hello_world.cpp -I boost_1_49_0/boost
where the last one specify the path for compiler to find the boost headers (please use absolute path).
If you want to send your program to others, dont copy only some boost files, it does not work because of the dependence. Ask them to install the same environment as you while is easy (just unzip a file...).
I don't know about your specific IDE, or about Boost.Asio specifically, but in general:
Whenever you need to link to a library, there is a file named similar to lib???.a, which you need. You need to pass the -l??? flag to g++ to link to the file.
(I'm not too familiar with the details myself, so there might be other file formats and whatnot too...)
Regarding the edit:
The "right" way would be to just have them download the library themselves, and just pass -l??? to their linker. Including Boost in your source code will make it huge, and for no good reason... it's not like you include the STL in your code, after all.
You don't include the library, but instead you declare a dependency on it. Eg. consider you use autoconf and automake then you would add AX_BOOST_BASE1 to require boost and AX_BOOST_ASIO to require the ASIO libraries. In your Makefile.am file(s) you use BOOST_CPPFLAGS and BOOST_LDFLAGS macros and rely on the ./configure to set them properly. Then whoever consumes your code will have to run the well know ./configure script which will analyze the environment for the location of boost and setup appropriate values in the build environment so that the make succeeds.
Well at least this is the theory. In practice there is a reason the whole thing is better known as autohell. Alternatives exists, like CMake or boost's own bjam. But the synopsis is always the same: you declare the dependency in your build configuration and the destination location that consumes you product has to satisfy the requirement (meaning it has to download/install the required version of boost, in your case). Otherwise you enter into the business of distributing binaries and this is frowned with problems due to richness of platforms/architectures/distributions your application is expected to be deployed in.
Obviously if you use a different build system, like ANT, then you should refer to that build system documentation on how to declare the requirement for boost.
1: ax_boost.m4 is not the only boost detecting m4 library, there are other out there, but is the one documented on the GNU autoconf list of macros

Resources