Built two different Debian packages for different Build Types using CMake - cmake

I have a small CMake project with different Build Types debug and release. I'm also providing a Debian package for this project. Building the Debian Package for release and providing it on my own Debian repository works perfect.
Now I also want to provide another Debian package for debug, due to debugging purposes, with a different package name. For example, my project is called myproject, and the debugging package should be myproject-debug.
I already read documentation about how to solve this in the debian/control file. I want to use Replaces: ... on each package vice versa, so that you can install only one of the both packages at a time. So either myproject or myproject-debug, but not both at the same time, to use the exact same files and filenames but only the binary has more debugging informations and debug prints in the myproject-debug package. Everything else should be the same. Same filename, same paths, etc.
Now the problem is that I don't know how the debian/rules file should look like, to first build the myproject package in a folder and then build the myproject-debug with different CMake options (-DCMAKE_BUILD_TYPE=debug) in a different folder, so the filenames can and should stay the same.
There is this CMake tutorial in the Debian documentation, but this doesn't fit my requirements. Because in this tutorial everything will be built in only one folder, and in this one folder there are different files. Then different .install files will be used to copy the needed files to each package. But since I have the same binary filename for each package myproject and myproject-debug this tutorial does not really fit my needs.
I already have the following lines in my debian/rules file:
override_dh_auto_configure:
dh_auto_configure -- -DCMAKE_BUILD_TYPE=release
But how can I run two different builds with two different build types?
For example, something like this, to split it up:
override_dh_auto_configure_release:
dh_auto_configure -- -DCMAKE_BUILD_TYPE=release
override_dh_auto_configure_debug:
dh_auto_configure -- -DCMAKE_BUILD_TYPE=debug
And run both in different folders so I can add both folders to two different packages.
Or maybe there is even a better solution I cannot imagine yet?

Related

Install jpeg 2000 on Windows 10

I want to investigate a new application for JPEG 2000 encoding and decoding. I downloaded openjpeg-master and managed to cobble together the ability to cmake the files. After a bunch of grinding, this resulted in the following output:
"Build files have been written to: C: openjpeg-master/build
\build> "
Any "normal" Unix installations have a multi-step installation like this:
"UNIX/LINUX - MacOS (terminal) - WINDOWS (cygwin, MinGW)
To build the library, type from source tree directory:
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
Binaries are then located in the 'bin' directory.
To install the library, type with root privileges:
make install
make clean
To build the html documentation, you need doxygen to be installed on your system. It will create an "html" directory in TOP_LEVEL/build/doc)
make doc"
But the Windows 10 equivalent is unclear, to put the most charitable spin on it. You can find it here: "https://github.com/uclouvain/openjpeg/blob/master/INSTALL.md"
Some questions arise:
is there a better starting place for installing JPEG 2000 that actually shows me how to install it and run the tests?
if not, how do I get from the build files to installing the libraries and making the test programs?
Is there more information I can dig out that would help to answer these questions?
Since I'm allergic to Visual Studio, I overlooked a nice tutorial specifying how to install something as complex as openjpeg by direct clone from github. However, in desperation, I found it and it worked. It is Visual Studio Community 2019 Version 16.8.3. I needed only to use -DTHIRDPARTY to get the third party libraries installed. There is a drop-down menu to build and install OPENJPEG. All I need to do now is figure out how to compile and run the utilities that invoke the installed libraries ...
actually, the complete line to add was -DBUILD_THIRDPARTY:bool=true.
Somewhere in my frantic random search for a way forward, I remember seeing the thought that to make the tests work, I merely need to find files like *.vsproj and run them a separate VS solutions. Some random guesswwork with .vdproj files in src/bin/... hasn't produced anything good. Is there not a document somewhere showing how to run the tests?

Force CMake to install targets to architecture-specific directories?

I'm currently having this issue with the Google Protobuf Library, but it is a recurring problem and will likely occur with many if not all 3rd-party packages that I want to build and install from source.
I'm developing for Windows, and we need to be able to generate both 32-bit and 64-bit versions of our DLLs. It was relatively straightforward to get CMake to install our own modules to architecture-specific subdirectories, e.g. D:\libraries\bin\i686 and d:\libraries\lib\i686 (and sim. for bin). But I'm having trouble achieving the same thing with 3rd-party libraries such as Protobuf.
I could, of course, use distinct CMAKE_INSTALL_PREFIX and CMAKE_PREFIX_PATH combinations (e.g. D:\libraries-i686 and D:\libraries-x86_64, and will probably end up doing just that, but it bothers me that there doesn't seem to be a better alternative. The docs for find_package() clearly show that the search procedure does attempt architecture-specific search paths, so why do the CMake files of popular libraries not generally seem to support installing to architecture-specific subdirectories?
Or could it be that it is just a matter of setting the right CMAKE_XXX variable?
Thanks to #arrowd for pointing me in the right direction, I now have my answer, though it is not exactly what I had hoped for.
CMAKE_LIBRARY_OUTPUT_DIRECTORY and CMAKE_RUNTIME_OUTPUT_DIRECTORY, however, specify the build output directories, not the install directories. As it turns out though, there are variables for the install directories too, called CMAKE_INSTALL_BINDIR and CMAKE_INSTALL_LIBDIR - they are actually plainly visible (along with plenty more) in the cmake-gui interface when "Advanced" is checked.
I tried setting those two manually (to bin\i686 and lib\i686), and it works: the Protobuf INSTALL target copies the files where I wanted to have them, i.e. where the CMake script of my consumer project will find them in an architecture-safe manner.
I'm not sure how I feel about this - I would have preferred something like a CMAKE_INSTALL_ARCHITECTURE or CMAKE_ARCHITECTURE_SUBDIR variable that CMake would automatically append to relevant install paths. The solution above requires overriding defaults that I would prefer to leave untouched.
Under the circumstances, my fallback approach might still be the better option. That approach however requires that the choice of architecture be made very early on, typically when running the script that initializes the CMake-specific environment variables that will be passed to cmake when configuring build directories. And it's worse when using cmake-gui, which requires the user to set all directories manually.
In the end, I'm still undecided.

Where to install FindLib.cmake

I'm creating a library (called fmi2) which I intend to install on my local machine (via a package manager) and then link to with a bunch of other libraries.
I'll be providing a Findfmi2.cmake file so that I can call find_package(fmi2) from my other libraries, but where should this file be conventionally installed?
Here are some choices I've considered and their problems:
/usr/share/cmake-3.8/Modules/Findfmi2.cmake
Advantage: find_package(fmi2) will just work
Disadvantage: Only works for one version of cmake
/usr/share/cmake/Modules/Findfmi2.cmake
Advantage: Should work for any version of cmake
Disadvantage: This is not a default folder. We would need to add set(CMAKE_MODULES_PATH /usr/share/cmake/Modules) and this kills any portability.
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Findfmi2.cmake
Advantage: Portable, just need to add set(CMAKE_MODULES_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
Disadvantage: Not system-wide. Need to manually add this file to each library that uses it. This duplicates files in my framework.
You are authoring content in CMake. You don't need a FindModule. That is designed to find external non-CMake outputs.
This Stackoverflow post from ruslo should help you understand the difference between find_package() module mode and config mode. It also answers your question about paths for FindModules, i.e. they are copied into your CMake project, not discovered system-wide, unless they are part of the official FindModules bundled with CMake in the "Modules" directory.
Modern CMake documentation now finally contains good examples to create a config mode package: cmake-packages
If you want explicit full examples, though using slightly older syntax for the config.cmake files, ruslo has more on Github.

Empty ${shlibs:Depends} while packaging a Mapnik plugin with cmake-based build system for Debian/Ubuntu

I am creating a Mapnik plugin (https://github.com/rbuch703/coords-mapnik-plugin), and am currently working on packaging it for Debian/Ubuntu. The binary package consists of only a single shared library that is built from C++ code. But being a Mapnik plugin, this library follows conventions quite different from the usual POSIX library conventions:
the file name has to be <name>.input instead of lib<name>.so
the file is installed in the Mapnik plugin directory (usually /usr/lib/mapnik/input)
the file is not supposed to be found by ldconfig, but rather Mapnik tries to find the plugin by itself at runtime
Now the plugin's build system is cmake, which makes most parts of Debian packaging straight-forward: the debian/rules file contains only the basic lines:
#!/usr/bin/make -f
%:
dh $#
However, I am running into problems with the substitution variable {shlibs:Depends}: it is simply not set (in particular, there is no corresponding line in the debian/<package name>.substvars file), and Lintian rightly complains about that fact (Lintian's actual complaint is missing-dependency-on-libc. But when I manually add a libc dependency, Lintian explains package-depends-on-hardcoded-libc, which means "The given package declares a dependency on libc directly instead of using ${shlibs:Depends} in its debian/control stanza."). I would like to satisfy Lintian in than respect, but are unable to do so.
Now I found that I could add the line
dpkg-shlibdeps debian/<packagename>/usr/lib/mapnik/input/coords.input
to my rules file. That will create the correct ${shlibs:Depends} line, but it will create it in the wrong file (debian/substvars instead of debian/<package name>.substvars), where the build system simply ignores it and Lintian keeps complaining about missing dependencies.
I am guessing that the root of my problem is that my Mapnik plugin does not conform to the POSIX library naming conventions (and as a Mapnik plugin cannot do so), and thus the packaging system does not handle it correctly. But I am at a loss as to how to fix this problem.
Additional notes:
the packages are built using debuild. Apart from the Lintian error messages, the build process work fine and correctly creates the .deb package.
my practical goal is for the package to build cleanly on Launchpad, so that I can add it to my Ubuntu PPA.
you can provide an output file for dpkg-shlibdeps with the -T flag.
something like:
override_dh_shlibdeps:
dh_shlibdeps
dpkg-shlibdeps \
-Tdebian/<packagename>.substvars \
debian/<packagename>/usr/lib/mapnik/input/coords.input
if there are multiple *.input files, you could also do something like:
override_dh_shlibdeps:
dh_shlibdeps
find debian/<packagename>/ -name "*.input" -exec \
dpkg-shlibdeps -Tdebian/<packagename>.substvars {} +

How to properly wrap a C library in a Cocoa application

I want to include the GNU Scientific Library (GSL) in my Cocoa app so that the user needs not installing it locally first. Like most GNU packages, it's the standard configure / make / make install routine. But this won't work:
./configure --prefix ~/libgsl
make
make install
Since the prefix is local to my computer. And neither is this:
./configure --prefix (path to build folder)/libgsl
make
make install
What I want is essentially the GSL being contained entirely in my application, and I can call its functions without the users downloading anything else.
I'm rather new to Xcode 4 and the build system for Clang/GCC, having coming over from .NET. Any help is much appreciated.
Assuming there is not a framework-style build of the library, the way this is typically done when bundling with 3rd party libraries is to build the package as normal, install it in /usr/local, and configure your project to include and link from there. Building is the easy part though.
The tricky part is bundling up the .app correctly. You need to add a custom build stage (after the others) which first copies all the dependent .dylib files into your app bundle's Frameworks folder (using the environment variables to help; see Xcode docs). Then you need to use install_name_tool to get the app binary to look in the framework dir (as the embedded soname still thinks it is in /usr/local). This part is very fiddly and not well documented.
I've just extracted this from a working project where I use GSL. Just add this as an extra build phase in your XCode project as a Custom Script:
# Framework folder for Example.app
FRAMEWORKS_DIR=${TARGET_BUILD_DIR}/Example.app/Contents/Frameworks
# Create path if it doesn't exsit
mkdir -p ${FRAMEWORKS_DIR}
# Find the original linked path for libgsl
GSLLIB=`otool -L ${TARGET_BUILD_DIR}/Example.app/Contents/MacOS/Example | grep libgsl | cut -d" " -f1`
GSLPATH=`dirname $GSLLIB`
# Copy the dylibs into your app
cp /usr/local/lib/lib{gsl,gslcblas}.0.dylib ${FRAMEWORKS_DIR}
# Update embedded paths
install_name_tool \
-change ${GSLPATH}/libgsl.0.dylib \
#executable_path/../Frameworks/libgsl.0.dylib \
${TARGET_BUILD_DIR}/Example.app/Contents/MacOS/Example
This should work with a simple substitution of your app name.
This is basically the same as what you need to do to build a standalone Qt app, so the docs here are very relevant:
Deploying Qt on the Mac
It is worth reading up on bundles, frameworks and packaging. For example:
Mac OS X Framework Reference
This post is also relevant:
How do I link libraries in Xcode 4?
Note that GSL is published under the GPL, so your app would need to be similarly published in order to respect the license. Shipping the source is necessary, but not sufficient for compliance.