Building dll on linux

CMake — создание динамических библиотек

Введение

CMake (от англ. cross platform make) — это кроссплатформенная система автоматизации сборки программного обеспечения из исходного кода.

CMake не занимается непосредственно сборкой, a лишь генерирует файлы управления сборкой из файлов CMakeLists.txt.

Динамические библиотеки. Теория

Создание динамических библиотек со статической линковкой в ОС Windows отличается от ОС GNU/Linux.

На ОС Windows для этого требуется связка .dll (dynamic link library) + .lib (library) файлов.
На ОС GNU/Linux для этого нужен всего лишь один .so (shared object) файл.

Динамические библиотеки. Практика

На практике хочется писать удобный, одинаковый код на обеих ОС.

В каждом проекте (или на несколько проектов одна) присутствовала условная компиляция:

Соответственно, для каждого экспортируемого класса из библиотеки необходимо прописать данный макрос:

В данном случае, на ОС Windows экспортируются все классы/методы, которые помечены данным макросом, а на ОС GNU/Linux, по умолчанию, всё экспортируется, т.к. нет макроса для скрытия классов/методов.

С выходом CMake версии 3.4.0, стало возможным создание библиотек с классами, которые экспортируются по умолчанию. Для этого в каждой цели (target), которые объявлены как SHARED (динамическая библиотека), необходимо включить свойство:

Пример небольшой библиотеки:

И убрать определение и использование макросов из кода:

Данное свойство автоматически создает module definition (.def) со всеми глобальными символами из .obj файла для динамической библиотеки на ОС Windows.

Далее данный файл (.def) передается компоновщику для создания .lib файла. На выходе на ОС Windows получается связка .lib + .dll

Источник

Writing Shared Libraries With D On Linux

For comparison purposes and looking at the mechanics, here’s how it’s done in C first.

Statically Linking C

To statically link a C module with a C program,

main.c: dll.c: Build: Results:

Statically Loading a Shared library in C

(The source files, run, and results should be identical.)

-rpath is used to embed the path to libdll.so into main, so that it can be found at runtime. Other ways to do it are (but are not discussed further here):

  1. Setting the environment variable LD_LIBRARY_PATH.
  2. Copy shared library to a standard location and use ldconfig to modify ld.so.

Dynamically Loading a Shared library in C

Add code to main.c to load the library at runtime:

main.c: Build: Results:

Dynamically Loading a C++ Shared library in C

The complication here is noting when the shared library’s static constructors and destructors are run. Instrument dll.c, which is now C++ code, with those static constructors and destructors:

dll.c: Build: Results:

Statically Linking D Program With libphobos2.a

Statically Linking D Program With libphobos2.so

Creating a D Shared Library and Statically Linking With libphobos2.so

When using D shared libraries, the code must be linked with libphobos2.so, not libphobos2.a. This is so that there will be only one instance of the garbage collector.

Dynamically Loading a C++ DLL From a D Program

Dynamically Loading a D DLL From a C Program

Note that libphobos2.so gets automatically dynamically loaded as well.

Dynamically Loading a D DLL From a D Program

It is important to link the main program with libphobos2.so, not libphobos2.a. Otherwise, the result will be multiple instances of the D runtime conflicting with each other.

main.d: Build: Results:

Note how the DLL’s static constructors are called before dlopen() returns, and the static destructors are called by dlclose().

Источник

Building a Win32 DLL from a Linux library source

I’m trying to build a Win32 DLL from an audio-DSP related Linux library (http://breakfastquay.com/rubberband/). There are makefiles and config scripts for Linux, but no help for Windows. The author provides a Win32 binary of a sample app using the library, and I see a number of «#ifdef MSVC» and «#ifdef WIN32» scattered around, so I don’t think I’m starting completely from scratch but I’m stuck nevertheless.

Читайте также:  Неполадки с windows media center

As my programming knowledge in either platform is rather limited, I’d appreciate any help.

First of all, what is the right way to get started here? Visual Studio? Cygwin? Initially I started off creating a Win32 DLL project in Visual Studio, adding the source files, thinking about adding a .def file, etc, but at some point I felt like this was going nowhere.

As for Cygwin, this was the first time using it, and I don’t even know if this is the sort of thing that Cygwin is designed for. Is it?

On Cygwin, I ran ./configure and got stuck at something like this:

«checking for SRC. configure: error: Package requirements (samplerate) were not met: No package ‘samplerate’ found»

After looking through the log, it appears that pkg-config is looking for samplerate.pc. How do I handle packages in Windows? libsamplerate is just an open source library, and I have source and a DLL for this. But I’m not sure how to use them to satisfy the dependency requirements for librubberband (which is what I’m trying to build)

I’m completely lost at this point and if anyone can give me a nudge in the right direction. and, is there an easier way to do this?

Many thanks in advance.

2 Answers 2

Linux to w32 is mostly a tricky thing.
For each of your dependencies, download the source and:

Also, I recommend you to use MinGW + msys in place of CygWin (as the latter produces executables that depend on its libraries). However in your situtation, use the VS approach — ‘t will save you a lot of time.

If you’re still stuck on this I can throw a little light.

You may have to build everything from sources (or have the libraries installed in your environment). You’re using Cygwin, I would recommend MinGW and MSYS too, but sometimes it’s just not possible to use this combination to build the program or library.

So if using Cygwin, first ensure that you have a proper environment installed. This is that you have the correct development headers installed.

Then download libsndfile. Extract the sources to a directory and from the Cygwin bash shell navigate to that directory. There perform:

Notice that I use a prefix, that prefix should point to the directory Cygwin is installed in order to correctly install the libraries (the same happens to MinGW and MSYS, the prefix should point to the MinGW installation directory). Maybe using the usr directory in the prefix works too, I’ve never tried it.

Now download FFTW, as it will be needed for libsamplerate and rubberband. Same procedure as with libsndfile: extract, configure, make & make install using the prefix. Now copy the header files of FFTW (in the example they’d be in /cygdrive/c/cygwin/include ) to the include directory in the usr directory (in the example /cygdrive/c/cygwin/usr/include ).

Next SRC (libsamplerate), same procedure.

Then the Vamp plugin SDK. In order to compile the it you may need to edit the file src\vamp-hostsdk\PluginLoader.cpp , deleting RTLD_LOCAL from a dlopen() call (it’s safe, it’s already the default behaviour).

Also, you may need to install it by hand (in my experiences it didn’t like the prefix). Or set the environmental variable PKG_CONFIG_PATH pointing to the paths of pkgconfig, e.g.:

Now, create a file called ladspa.h in the include directory with the contents of the LADSPA header

Finally, configure and build rubberband, it should find everything it needs.

To build in MSYS using MinGW follow the same procedure, using the according prefix. Using Visual Studio is another alternative, but you may need to use some of the pre-built libraries (for example for libsndfile) as building Linux libraries natively in Windows may be complicated or even impossible (without hacking the source code) in VS.

Anyway, the autor of rubberband provides binaries; I think you should consider use them instead of going through all of this.

Источник

Building dll on linux

Copy raw contents

Читайте также:  Как правильно установить линукс с диска

Copy raw contents

gRPC C++ — Building from source

This document has detailed instructions on how to build gRPC C++ from source. Note that it only covers the build of gRPC itself and is mostly meant for gRPC C++ contributors and/or power users. Other should follow the user instructions. See the How to use instructions for guidance on how to add gRPC as a dependency to a C++ application (there are several ways and system wide installation is often not the best choice).

If you plan to build using CMake

If you are a contributor and plan to build and run tests, install the following as well:

On a Mac, you will first need to install Xcode or Command Line Tools for Xcode and then run the following command from a terminal:

To build gRPC from source, you may need to install the following packages from Homebrew:

If you plan to build using CMake, follow the instructions from https://cmake.org/download/

Tip: when building, you may want to explicitly set the LIBTOOL and LIBTOOLIZE environment variables when running make to ensure the version installed by brew is being used:

To prepare for cmake + Microsoft Visual C++ compiler build

  • Install Visual Studio 2015 or 2017 (Visual C++ compiler will be used).
  • Install Git.
  • Install CMake.
  • Install nasm and add it to PATH ( choco install nasm ) — required by boringssl
  • (Optional) Install Ninja ( choco install ninja )

Clone the repository (including submodules)

Before building, you need to clone the gRPC github repository and download submodules containing source code for gRPC’s dependencies (that’s done by the submodule command or —recursive flag). Use following commands to clone the gRPC repository at the latest stable release tag

NOTE: The bazel build tool uses a different model for dependencies. You only need to worry about downloading submodules if you’re building with something else than bazel (e.g. cmake ).

Build from source

In the C++ world, there’s no «standard» build system that would work for in all supported use cases and on all supported platforms. Therefore, gRPC supports several major build systems, which should satisfy most users. Depending on your needs we recommend building using bazel or cmake .

Building with bazel (recommended)

Bazel is the primary build system for gRPC C++ and if you’re comfortable with using bazel, we can certainly recommend it. Using bazel will give you the best developer experience as well as faster and cleaner builds.

You’ll need bazel version 1.0.0 or higher to build gRPC. See Installing Bazel for instructions how to install bazel on your system. We support building with bazel on Linux, MacOS and Windows.

From the grpc repository root

NOTE: If you are gRPC maintainer and you have access to our test cluster, you should use the our gRPC’s Remote Execution environment to get significant improvement to the build and test speed (and a bunch of other very useful features).

Building with CMake

Linux/Unix, Using Make

Run from grpc directory after cloning the repo with —recursive or updating submodules.

If you want to build shared libraries ( .so files), run cmake with -DBUILD_SHARED_LIBS=ON .

Windows, Using Visual Studio 2015 or 2017

When using the «Visual Studio» generator, cmake will generate a solution ( grpc.sln ) that contains a VS project for every target defined in CMakeLists.txt (+ few extra convenience projects added automatically by cmake). After opening the solution with Visual Studio you will be able to browse and build the code.

Using gRPC C++ as a DLL is not recommended, but you can still enable it by running cmake with -DBUILD_SHARED_LIBS=ON .

Windows, Using Ninja (faster build).

Please note that when using Ninja, you will still need Visual C++ (part of Visual Studio) installed to be able to compile the C/C++ sources.

Using gRPC C++ as a DLL is not recommended, but you can still enable it by running cmake with -DBUILD_SHARED_LIBS=ON .

Windows: A note on building shared libs (DLLs)

Читайте также:  Windows как показать скрытые файлы

Windows DLL build is supported at a «best effort» basis and we don’t recommend using gRPC C++ as a DLL as there are some known drawbacks around how C++ DLLs work on Windows. For example, there is no stable C++ ABI and you can’t safely allocate memory in one DLL, and free it in another etc.

That said, we don’t actively prohibit building DLLs on windows (it can be enabled in cmake with -DBUILD_SHARED_LIBS=ON ), and are free to use the DLL builds at your own risk.

  • you’ve been warned that there are some important drawbacks and some things might not work at all or will be broken in interesting ways.
  • we don’t have extensive testing for DLL builds in place (to avoid maintenance costs, increased test duration etc.) so regressions / build breakages might occur

gRPC’s CMake build system has two options for handling dependencies. CMake can build the dependencies for you, or it can search for libraries that are already installed on your system and use them to build gRPC.

This behavior is controlled by the gRPC_ _PROVIDER CMake variables, e.g. gRPC_CARES_PROVIDER . The options that these variables take are as follows:

  • module — build dependencies alongside gRPC. The source code is obtained from gRPC’s git submodules.
  • package — use external copies of dependencies that are already available on your system. These could come from your system package manager, or perhaps you pre-installed them using CMake with the CMAKE_INSTALL_PREFIX option.

For example, if you set gRPC_CARES_PROVIDER=module , then CMake will build c-ares before building gRPC. On the other hand, if you set gRPC_CARES_PROVIDER=package , then CMake will search for a copy of c-ares that’s already installed on your system and use it to build gRPC.

Install after build

Perform the following steps to install gRPC using CMake.

  • Set -DgRPC_INSTALL=ON
  • Build the install target

The install destination is controlled by the CMAKE_INSTALL_PREFIX variable.

If you are running CMake v3.13 or newer you can build gRPC’s dependencies in «module» mode and install them alongside gRPC in a single step. Example

If you are building gRPC

You can use CMake to cross-compile gRPC for another architecture. In order to do so, you will first need to build protoc and grpc_cpp_plugin for the host architecture. These tools are used during the build of gRPC, so we need copies of executables that can be run natively.

You will likely need to install the toolchain for the platform you are targeting for your cross-compile. Once you have done so, you can write a toolchain file to tell CMake where to find the compilers and system tools that will be used for this build.

This toolchain file is specified to CMake by setting the CMAKE_TOOLCHAIN_FILE variable.

A note on SONAME and its ABI compatibility implications in the cmake build

Best efforts are made to bump the SONAME revision during ABI breaches. While a change in the SONAME clearly indicates an ABI incompatibility, no hard guarantees can be made about any sort of ABI stability across the same SONAME version.

Building with make on UNIX systems (deprecated)

NOTE: make used to be gRPC’s default build system, but we’re no longer recommending it. You should use bazel or cmake instead. The Makefile is only intended for internal usage and is not meant for public consumption.

From the grpc repository root

NOTE: if you get an error on linux such as ‘aclocal-1.15: command not found’, which can happen if you ran ‘make’ before installing the pre-reqs, try the following:

A note on protoc

By default gRPC uses protocol buffers, you will need the protoc compiler to generate stub server and client code.

If you compile gRPC from source, as described above, the Makefile will automatically try compiling the protoc in third_party if you cloned the repository recursively and it detects that you do not already have ‘protoc’ compiler installed.

Источник

Оцените статью