Generate package config file automagically using Scons, bjam, and/or cmake - scons

Hey Stackoverflowers: one comment and one question.
Comment: You guys/girls are great, thanks for taking a look.
Question:
Can Bjam, Scons, or Cmake easily install a .pc file for library projects?
I find it really annoying that I have to maintain the same library dependency list in my scons/bjam/make file, the .pc file (for libraries), and rpm/deb package config files.
It would be nice if a build tool could manage the build and installation meta-data.
Thoughts?

Because SCons is such a flexible environment, yes you can in fact use it to manage the entire process from building to deliverable package.
Our build goes through several phases with SCons:
Build - resulting .o, .os, generated files, etc under ./build
Assembly - resulting exe, so/dll, binarys, etc under ./delivery
Packing & configuration - a set of deb/rpm/msi + configuration, etc under ./package
It isn't all out of the box, and requires you to write some python code, find tools etc, but it does work for us pretty well.
Our project is C, C++, Java, & Python building dozens of binary targets for a distributed system with multiple delivery targets for different machine installs on Windows, Ubuntu and Redhat Linux.
Again, be prepared to have to customize your scripts and write custom builders though to wrap different processes.

Related

How to pack files into one executable file for Linux and Windows?

I'm creating an desktop app on Golang with Muon UI (using Ultralight instead of Chromium) and cross-build my app for Linux and Windows. For now the app work fine but it required Ultralight libraries (*.dll for Windows and *.so for Linux). But I wanna distribution my app as single executable file. How I can create two executable files? First file for Linux, it's should include main executable file for Linux and only *.so libraries. And second file should include main executable file for Windows and only *.dll libraries. How I can to do this?
Are there any CLI utils for this? (for using in gitlab CI inside Docker for example) Or maybe I can to do this via Golang (for example using embed package. Can I embedded libraries into exe file, that it is can run)?
Or can I use cgo for link dynamic libs as static into binary file?
The honest answer would be: "With great difficulty, lots of pain, blood and tears."
The somewhat longer answer is, that a precompiled DLL/.so may contain slightly more than a mere static library. It it possible to "convert" a DLL/.so into a static library? Somewhat. It boils down to dumping its contents into object files, reverting all the relocation entries, possibly dealing with versioned symbols and weak symbols. No, there are no kitchen sink utilities out there, doing all that for you on an executable binary level.
If you can limit yourself to Linux, you may want to look into Flatpak. What this does is wrapping everything up into a sort of "self extracting archive", which upon launch will transparently and invisibly unpack itself into an in-situ temporary mount point (which you won't see from the rest of the system).
Now, one option would be to build all the dependencies of your program yourself, and arranging for those builds to be created as static libraries. In that case you're no longer dealing with DLLs. However some libraries do not want to be built for static linking, so your mileage may vary there.
Truth to be told: Why is distributing multiple files any issue at all? On Linux/*BSD you must ship separate icon and .desktop files anyway, so that stuff shows up in the Desktop application menus. Yes, it'd be nice if instead of dealing with XDG desktop entry files we had the option to place all of that information into a special – let's call it .xdgdata – readonly section, with some well known symbol names, so that we could have truly single file distributable executables.
My honest suggestion: Don't sweat about it. Just ship the whole bunch of files and don't worry too much about "how this looks".

best practice for building with/out included libraries

a project ships with a copy of library foo, in a filesystem layout like:
myproject/
myproject/src/ # sources of my project
myproject/libfoo/ # import of "foo" library
the standard (autotools-based) build-system builds libfoo, then builds myproject which dynamically links against libfoo.
libfoo is basically unmodified (with some minor amendments to properly fit into the build-system). libfoo uses autotools itself, so i'm usually calling configure recursively using AC_CONFIG_SUBDIRS.
however, libfoo is already packaged for various distributions, so i would like to avoid building against the imported library on these systems and rather use system-wide installation - this way i get the benefits of a better maintained version of libfoo (less bugs, security issues,...).
otoh, i want keep libfoo in my source-tree, so that i have a fallback for building on systems that do not ship that library (without the user requiring to separately fetch the sources and build the lib themselves).
i can think of a number of configure-flags i could instroduce, so the user can select whether they want to build the project with the system-installed, the local or without the library. (it's an optional dependency).
disabling the "local foo", should completely disable building of libfoo (and probably also configuring foo)
e.g. something like:
./configure --enable-foo=no # aka "--disable-foo": build without foo
./configure --enable-foo # use system-wide foo
./configure --enable-foo=local # use local copy of foo
alternatively:
./configure --disable-foo
./configure --enable-foo --disable-local-foo
./configure --enable-foo --enable-local-foo
but i'd like to do this in a standard-conformant way.
what's the best practice for selecting via autoconf, whether to use a local copy or a library, a system-wide copy or to not use the library at all?
pointers to projects that use such a mechanism are most welcome.
I have a similar in my project where I use the included version of the BuDDy library when (1) the library isn't already installed, or (2) it is installed but does not have to interface I expect, or (3) configure was run with --with-included-buddy.
You can see the configure macro here. After that I just use $(BUDDY_CPPFLAGS) and $(BUDDY_LDFLAGS) in the Makefile.ams, and the top-level Makefile.am only include the buddy directory conditionally in SUBDIRS.
I prefer --with-foo when dealing with external software, but it's just a preference. The examples and documentation at the link might help you decide how you want to do it. I'd go with your first example that uses only one flag rather than the second one that uses two flags for easier documentation/maintenance.
I really don't think you want to do this
You're going to make the build machinery a lot more complicated, and autotools are already considered black magic by most. It'll make things a lot more complicated for the developer, a little more complicated for a potential distro packager and ever-so-slightly easier for the end user.
If you're conditionally configuring then you make the process of building distribution tarballs (make dist/make distcheck) more brittle.
This is the sort of trouble you can cause.
But if you must...
You may be able to adapt the code in my recent answer.

How can I make Cabal search for external programs?

I'm trying to write a Haskell program which requires the output of external programs (such as lame, the mp3 encoder). While declaring dependency on a library is easy in cabal, how can one declare dependency on an executable?
You can't currently add a dependency in the .cabal file for external executables, other than a list of known build tools (see build-tools: alex for example).
You can however specify build-type: Configure, and then use a separate configure script to search for any additional binaries (for example, an autoconf-based configure script is perfectly fine, and can be used to set constants in your source).
Note that searching for a runtime dependency -- such as a lame encoder -- at compile time may be a bad idea, as the build and run environments are different on many package systems. It might be a better idea to dynamically search for required binaries at program startup.
For example, hmp3 hunts for mpg321 with
mmpg <- findExecutable (MPG321 :: String)
where MPG321 is the name of the program determined via a ./configure option. For more information, see the haddocks:
http://hackage.haskell.org/packages/archive/directory/latest/doc/html/System-Directory.html#v:findExecutable

Converting a script/program into an installable tarball?

I am quite familiar with writing small programs or scripts, and I am also familiar with downloading a source tarball and installing it using ./configure && make && make install (or, failing that, doing whatever the INSTALL or README files tell me to do). However, I don't know how to take a script that I've written and package it up (along with its supporting files) so that it can be installed as above.
I've tried Googling, but I'm not sure what search terms to use. If I try something involving the word "package," I get guides on how to convert a tarball to a deb/rpm/miscellaneous-distro-specific-package-format, which is not what I want.
I guess I need to use something called a build system, which might be called autotools, unless it's actually cmake, rake, scons, or something else?
Also, if my program requires some supporting files, how might I need to modify my program so that it can locate those files once they have been installed in /usr/share, /usr/lib, and wherever else they end up after installation?
Basically, I'm looking to graduate from writing scripts to writing distributable programs.
Answering your question "How do I learn how to use autotools to distribute my program as a tarball?"
http://www.gnu.org/software/autoconf/manual/
http://www.gnu.org/software/automake/manual/ and
http://sources.redhat.com/autobook/ (Outdated but still useful)

Create setup for Linux C project

I want to create a setup for my project so that it can be installed on any pc without installing the header files.
How can I do that?
There are two general ways to distribute programs:
Source Distribution (source code to be built). The most common way is to use GNU autotools to generate a configure script so that your project can be installed by doing ./configure && make install
Binary Distribution (prebuilt). Instead of shipping source, you ship binaries. There are a couple of competing standards although the two main ones are RPM and DEB file.
You just changed your question (appreciated, it was kind of vage), so my answer no longer applies ..
make sure you have a C compiler
I'd be surprised if you didn't, Linux normally has one
find an editor you are comfortable with
vi and emacs are the classics
write your first program and compile
learn about makefiles
learn about sub projects and libraries
In many respects, your question is too vague to be answerable. You will need to describe more what you have in mind. All else apart, if you are using an integrated development environment (IDE), then what you do should be coloured strongly by what the IDE encourages you to do. (Fighting your IDE is counter-productive; I've just never found an IDE that doesn't make me want to fight it.)
However, for a typical project on Linux, you will create a directory to hold the materials. For a small project (up to a few thousand lines of code in a few - say 5-20 - files), you might not need any more structure than a single directory. For bigger projects, you will segregate sub-sections of the project into separate sub-directories under the main project directory.
Depending on your build mechanisms, you may have a single makefile at the top of the project hierarchy (or the only directory in the 'hierarchy'). This goes in line with the 'Recursive Make Considered Harmful' paper (P Miller). Alternatively, you can create a separate makefile for each sub-directory and the top-level makefile simply coordinates builds across directories.
You should also consider which version control system (VCS) you will use.

Resources