Autotools suite misplaces "man" file leading to installation failure - c

In a software I have to tweak, the man file is located under doc/ along with a simple Makefile.am file:
man_MANS = software.1
EXTRA_DIST = $(man_MANS)
Upon installation, I expect make install to copy the manual under /usr/local/share/man/, but the script - instead - will try to install the man under /usr/local/share/man/man1 - which does not exist - throwing an error and stopping the process.
I would expect a similar behavior if I assigned software.1 to man1_MANS, though.
What is going on ? How is this possible that automake does not create non-existing folders ?

man_MANS will try to figure out in which section to put the manual depending on the extension you gave it, so it is correct in this case that it would install into ${mandir}/man1.
Since you say that MKDIR_P is empty in your output, try to ensure that AC_PROG_MKDIR_P is being called in your configure.ac (it should be automatically called by AM_INIT_AUTOMAKE but since you said it's old it might have some issues).

Related

Can the meson project version be assigned dynamically?

I am new to Meson so please forgive me if this is a stupid question.
Simple Version of the Question:
I want to be able to assign a dynamic version number to the meson project version at build time. Essentially meson.project_version()=my_dynamic_var or project( 'my_cool_project', 'c', version : my_dynamic_var') (which of course won't work).
I would rather not pre-process the file if I don't have to.
Some background if anybody cares:
My build system dynamically comes up with a version number for the project. In my case, it is using a bash script. I have no problem getting that version into my top level meson.build file using run_command and scraping stdout from there. I have read that using doing it this way is bad form so if there is another way to do this.. I am all ears.
I am also able to create and pass the correct -DPRODUCT_VERSION="<my_dynamic_var>" via add_global_arguments so I COULD just settle for that.. but I would like the meson project itself to carry the same version for the logs and so I can use meson.project_version() to get the version in subprojects for languages other than c/c++.
The short answer, as noted in comments to the question, appears to be no. There is no direct way to set the version dynamically in the project call.
However, there are some work arounds, and the first looks promising for the simple case:
(1) use meson rewriting capability
$ meson rewrite kwargs set project / version 1.0.0
Then obviously use an environment variable instead of 1.0.0.
(2) write a wrapper script which reads the version from the environment and substitutes it into your meson.build file in the project call.
(3) adopt conan.io and have your meson files generated.
(4) use build options. This option, while not as good as (1) might work for other work flows.
Here's how option (4) works.
create a meson_options.txt file in your meson root directory
add the following line:
option('version', type : 'string', value : '0.0.0', description : 'project version')
then create a meson.build file that reads this option.
project('my_proj', 'cpp')
version = get_option('version')
message(version)
conf_data = configuration_data()
conf_data.set('version', version)
When you go to generate your project, you have an extra step of setting options.
$ meson build && cd build
$ meson configure -Dversion=$BUILD_VERSION
Now the version is available as a build option, then we use a configuration_data object to make it available for substitution into header/source files (which you might want to get it into shared libraries or what not).
configure_file(
input : 'config.hpp.in',
output : 'config.hpp',
configuration : conf_data
)
And config.hpp.in looks something like this:
#pragma once
#include <string>
const static std::string VERSION = "#version#";
When we do the configure_file call, #version# will get substituted for the version string we set in the meson configure step.
So this way is pretty convoluted, but like I said, you may still end up doing some of it, e.g. to print copyright info and what not.
As of 0.60.3 you may directly assign version from run_command which means the following will work without any meson_options.txt.
project('randomName', 'cpp',
version : run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip(),
default_options : [])
In particular, it is also possible to assign the result of a bash script, simply invoke it instead of git.

Shows Missing library : ff while building echidna using stack install

I am trying to build echidna using stack install.
https://github.com/crytic/echidna
I am continuously getting the missing library error while installing at a progress state of 171/178.
I believe it to be more of stack error than library error. Error shown is as follows
I have tried installing the library but not getting any C library of such sort.ye
SO, i've installed every library using
sudo apt-get install lib*ff*-dev
isn't working yet.
-- While building package hevm-0.31 using:
/home/aman/.stack/setup-exe-cache/x86_64-linux/Cabal-simple_mPHDZzAJ_2.2.0.1_ghc-8.4.3 --builddir=.stack-work/dist/x86_64-linux/Cabal-2.2.0.1 configure --with-ghc=/home/aman/.stack/programs/x86_64-linux/ghc-8.4.3/bin/ghc --with-ghc-pkg=/home/aman/.stack/programs/x86_64-linux/ghc-8.4.3/bin/ghc-pkg --user --package-db=clear --package-db=global --package-db=/home/aman/.stack/snapshots/x86_64-linux/lts-12.10/8.4.3/pkgdb --package-db=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/pkgdb --libdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/lib --bindir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/bin --datadir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/share --libexecdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/libexec --sysconfdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/etc --docdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/doc/hevm-0.31 --htmldir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/doc/hevm-0.31 --haddockdir=/home/aman/Desktop/new/echidna2/echidna/.stack-work/install/x86_64-linux/lts-12.10/8.4.3/doc/hevm-0.31 --dependency=QuickCheck=QuickCheck-2.11.3-3XHQpBYb83U2mMvNz2AjQX --dependency=abstract-par=abstract-par-0.3.3-Ie3MD7O3orK6ZR8i7FuBEv --dependency=aeson=aeson-1.3.1.1-7JlrwYHW7OR9ca4RRZ9oOf --dependency=ansi-wl-pprint=ansi-wl-pprint-0.6.8.2-9fh9v74MJQDJeSHE7X3Co6 --dependency=async=async-2.2.1-7DQr5PBcpiwJNOuf7ZiSPa --dependency=base=base-4.11.1.0 --dependency=base16-bytestring=base16-bytestring-0.1.1.6-I0igvRcEwRNBMqqPC2yQBh --dependency=base64-bytestring=base64-bytestring-1.0.0.1-4OCIe2BZn8jKI191JIXI37 --dependency=binary=binary-0.8.5.1 --dependency=brick=brick-0.37.2-HmDqAExuwtV4o98FRmS9eK --dependency=bytestring=bytestring-0.10.8.2 --dependency=cereal=cereal-0.5.7.0-ILaYAmVTyR1IcEsGXXUCfI --dependency=containers=containers-0.5.11.0 --dependency=cryptonite=cryptonite-0.25-GgyZs9E1viv2owjaLxA3vq --dependency=data-dword=data-dword-0.3.1.2-CMzWV6RCGtK8L6wsVSErKS --dependency=deepseq=deepseq-1.4.3.0 --dependency=directory=directory-1.3.1.5 --dependency=fgl=fgl-5.6.0.0-E3fRSNebqkULRqplV3ljSc --dependency=filepath=filepath-1.4.2 --dependency=ghci-pretty=ghci-pretty-0.0.2-I5PJbL8ge6MChp3KxZbHqH --dependency=haskeline=haskeline-0.7.4.3-5EI2v7Zmtnz57a7mmnEGOS --dependency=lens=lens-4.16.1-B0f4CyKKTUGAKBzzY965AX --dependency=lens-aeson=lens-aeson-1.0.2-Jly9eqrxMbj6GutGwOKn69 --dependency=megaparsec=megaparsec-6.5.0-G48ltiRFbVUHATB1lTnNRx --dependency=memory=memory-0.14.16-GTCi0eCrvrnI3inLDBWVMK --dependency=monad-par=monad-par-0.3.4.8-Jjk0JT5qYVK4xEO13GFUu8 --dependency=mtl=mtl-2.2.2 --dependency=multiset=multiset-0.3.4.1-DOPR5uXspss8vZY4jdOdOo --dependency=operational=operational-0.2.3.5-4jEcCWo4nKu1T4LZlKqe58 --dependency=optparse-generic=optparse-generic-1.3.0-1jcIewFKPXBLcRetZisV2l --dependency=process=process-1.6.3.0 --dependency=quickcheck-text=quickcheck-text-0.1.2.1-2lR7Kay7WBV5AMKAdKDpZZ --dependency=regex-tdfa=regex-tdfa-1.2.3.1-9PkkapJrmiKFVG38JA02jN --dependency=restless-git=restless-git-0.7-83nBoDMPYLtJIx01bvXzKs --dependency=rosezipper=rosezipper-0.2-GAlMD5j8Qb83GzjCYQknnx --dependency=s-cargot=s-cargot-0.1.4.0-J9AhWfrUxDQ6YMTyzXkHth --dependency=scientific=scientific-0.3.6.2-5di0UflhS5I1xpiiCPzjKz --dependency=semver-range=semver-range-0.2.7-dBvW3ofcsgDQf0zazTsJd --dependency=temporary=temporary-1.3-5Z6bOFbSCb7VhnH5UnI2r --dependency=text=text-1.2.3.0 --dependency=text-format=text-format-0.3.2-Fd261TSu6ptAAzilVN6BFx --dependency=time=time-1.8.0.2 --dependency=transformers=transformers-0.5.5.0 --dependency=tree-view=tree-view-0.5-Kkrk0dCM0oj2Q4xwPbd7Gg --dependency=unordered-containers=unordered-containers-0.2.9.0-IkfpzvG0LzrHAbTzfMidvY --dependency=vector=vector-0.12.0.1-4awQG9XUvVEBfJgKGHBhOb --dependency=vty=vty-5.21-A2OCwk39Wv3J3RjR3BvHey --dependency=witherable=witherable-0.2-2RYbFmOnVolGAqiDDS1CLe --dependency=wreq=wreq-0.5.2.1-IjuXB0jwsxA7O3uIVjcJXu --extra-include-dirs=/home/aman/Downloads/Compressed/ff13c/source/ --extra-include-dirs=/usr/local/opt/readline/include --extra-lib-dirs=/usr/local/opt/readline/lib
Process exited with code: ExitFailure 1
Logs have been written to: /home/aman/Desktop/new/echidna2/echidna/.stack-work/logs/hevm-0.31.log
Configuring hevm-0.31...
Cabal-simple_mPHDZzAJ_2.2.0.1_ghc-8.4.3: Missing dependency on a foreign
library:
* Missing (or bad) C library: ff
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.If the
library file does exist, it may contain errors that are caught by the C
compiler at the preprocessing stage. In this case you can re-run configure
with the verbosity flag -v3 to see the error messages.
The stack install must find this library and end up successfully installing the library I'm using.
So, it is clear from the error provided above, that the installation was not able to find the libff file.
The best solution is to build the libff library manually and copy the required builds at the place it should be.
The best way to debug the problem is to look at the executed command closely and try to find the possible places where the libff should be...
Looking into the very 2nd error line, i.e. the complete command it was trying to execute
here, I sighted the following options being executed
--extra-include-dirs=/usr/local/opt/readline/include --extra-lib-dirs=/usr/local/opt/readline/lib
In order to solve this, I looked for the required libff library and cloned it from GitHub. I cloned the required dependencies and places them in the directory it should be.
https://github.com/scipr-lab/libff
I then followed the "Build guide" to build the required library.
Then with the superuser on, I created the directories, /usr/local/opt/readline/lib and /usr/local/opt/readline/include, and it was solved. And pasted the required builds in it.
Used stack install again, and it worked.
Note:
I thought many beginners may have similar problem while installing the required tools for their use. These small ideas may help them.

CMake: how to break a PRE_LINK infinite loop?

I'm trying to automatically label my application sign-on line with a build number. This application is a plain vanilla C one without graphic UI; it is intended for command line, therefore it is a "simple" one.
The sign-on id is located in a "template" source file which is customized by CMake with a configure_file() command. Recently, I fancied to include a build number in this sign-on id. Consequently, the customization can no longer be statically done at CMake time, but everytime make is invoked.
To achieve that, there are two possibilities in CMake:
add_custom_target(), but it is triggered even when nothing else changes in the source tree which does not reflect the state of the tree;
add_custom_command(), which can be triggered only when the application (target) needs to be linked again.
I opted for the second solution and did not succeed.
Here is an extract of my CMakeLists.txt, the sign-on id being in file ErrAux.c (template in PROJECT_SOURCE_DIR, configured in PROJECT_BINARY_DIR):
add_executable(anathem ... ${PROJECT_BINARY_DIR}/ErrAux.c ...)
add_custom_command(TARGET anathem PRE_LINK
COMMAND "${CMAKE_COMMAND}" "-DVERS=${PROJECT_VERSION}"
"-DSRC=${PROJECT_SOURCE_DIR}"
"-DDST=${PROJECT_BINARY_DIR}"
-P "${CMAKE_HOME_DIRECTORY}/BuildNumber.cmake"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Numbering build"
VERBATIM
)
This launches script BuildNumber.cmake just before the link step. It computes the next build number and customizes ErrAux.c with configure_file().
It works fine, except ...
It happens late in the make sequence and the update to ErrAux.c goes unnoticed. The sign-on id in the executable contains the previous build number.
Next time I run make, make notices the generated ErrAux.c is younger than its object module and causes it to be compiled again, which in turn causes a link which triggers a build number update. This happens even if no other file has changed and this loop can't be broken. This is clearly shown in the compiling log:
Scanning dependencies of target anathem
[ 13%] Building C object AnaThem/CMakeFiles/anathem.dir/ErrAux.c.o
[ 14%] Linking C executable anathem
Numbering build
3.0.0-45
[ 36%] Built target anathem
The crux seems to be that add_custom_command(TARGET ...) can't specify an output file like add_custom_command(OUTPUT ...) does. But this latter form can't be triggered in PRE_LINK mode.
As a workaround, I forced a compilation to "refresh" the object module with:
add_custom_command(TARGET anathem PRE_LINK
COMMAND "${CMAKE_COMMAND}" "-DVERS=${PROJECT_VERSION}"
"-DSRC=${PROJECT_SOURCE_DIR}"
"-DDST=${PROJECT_BINARY_DIR}"
-P "${CMAKE_HOME_DIRECTORY}/BuildNumber.cmake"
COMMAND echo "Numbering"
COMMAND echo "${CMAKE_C_COMPILER}" "\$(C_DEFINES)" "\$(C_INCLUDES)" "\$(C_FLAGS)" -c "${PROJECT_BINARY_DIR}/ErrAux.c"
COMMAND "${CMAKE_C_COMPILER}" "\$(C_DEFINES)" "\$(C_INCLUDES)" "\$(C_FLAGS)" -c "${PROJECT_BINARY_DIR}/ErrAux.c"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Numbering build"
VERBATIM
)
An explicit compilation is forced after sign-on id customization. It mimics what is found in the various Makefile's and my not be safe for production. It's a cheat trick on both CMake and make.
UPDATE: Option -c is required to postpone link step until the final application liniking process.
This addition creates havoc in the link, as shown by the log, where you see a double compilation (the standard make one and the add_custom_command() one):
Scanning dependencies of target anathem
[ 13%] Building C object AnaThem/CMakeFiles/anathem.dir/ErrAux.c.o
[ 14%] Linking C executable anathem
Numbering build
3.0.0-47
Numbering
/usr/bin/cc -DANA_DEBUG=1 -I/home/prog/projects/AnaLLysis/build/AnaThem -I/home/prog/projects/AnaLLysis/AnaThem -g /home/prog/projects/AnaLLysis/build/AnaThem/ErrAux.c
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
AnaThem/CMakeFiles/anathem.dir/build.make:798: recipe for target 'AnaThem/anathem' failed
make[2]: *** [AnaThem/anathem] Error 1
If I force a full recompilation, to make sure all sources are compiled, *main.c* included, I get the same error on `main`.
The only logical explanation is my manual C invocation is faulty and somehow destroys vital information. I checked with *readelf* that `main` is still in the symbol table for *main.c.o* and that it is still taken into account by the link step (from file *link.txt*).
UPDATE: Even with the correct link, I'm still experiencing the infinite loop syndrom. The generated application still has its sign-on id lagging behind the actual build counter.
Can someone give me a clue for the right direction?
FYI I'm quite new to CMake, so I may do things really wrong. Don't hesitate to criticize my mistakes.
The key to the solution is to put the generated module where make expects to find it. CMake organizes the build tree in a non-trivial way.
The shortcomming in my added compilation in add_custom_command() was to believe that by default the binary will be stored in the "usual" CMake locations. Since I forge manually my compiler command, this is not the case.
I found the module in the source directory, which is a consequence of the WORKING_DIRECTORY option, with name ErrAux.o and not ErrAux.c.o.
To obtain the correct behavior, I force an output location with:
-o "${PROJECT_BINARY_DIR}/CMakeFiles/anathem.dir/ErrAux.c.o"
Now, when I run make again, nothing happens since nothing changed.
Side question
To make the solution portable (if needed), are there CMake variables for CMakeFiles and anathem.dir directories? Or in the latter case, for the current target as "anathem" as the target name in add_custom_command()?

BitBake: example not found in the base feeds

I have a BitBake recipe (example_0.1.bb) with a do_install task where I attempt to install a .so file:
do_install() {
install -d ${D}${libdir}
install -m 0644 ${S}/example.so ${D}${libdir}
}
FILES_${PN} += "${libdir}/example.so"
This fails during the build process and returns:
ERROR: example not found in the base feeds
However, if I add a test file to the package, both the .so file and the test file are added to the rootfs.
do_install() {
install -d ${D}${libdir}
install -m 0644 ${S}/example.so ${D}${libdir}
echo "bar" >> ${TOPDIR}/foo
install -m 0644 ${TOPDIR}/foo ${D}${libdir}
}
FILES_${PN} += "${libdir}/libceill.so"
FILES_${PN} += "${libdir}/foo"
How can I add only the .so file without the junk test file?
So you've got a library that is non-standard in that it's not installing a versioned library (libfoo.so.1.2.3, maybe symlinks such as libfoo.so.1 -> libfoo.so.1.2.3), and then an unversioned symlink for compilation time (libfoo.so -> libfoo.so.1). The default packaging rules assume standard libraries.
What's happening is that packages are populated by their order in PACKAGES, which has PN-dev before PN. FILES_PN-dev by default contains /usr/lib/lib*.so, and FILES_PN contains /usr/lib/lib*.so.. When you add /usr/lib/lib.so to FILES_PN what you want to happen isn't happening because PN-dev has already taken the files.
If your library doesn't come with any development files at all (e.g. no headers) then you can set FILES_${PN}-dev = "" to empty that package, and then your addition of lib*.so to FILES_${PN} will work as expected.
Yes, this is something that we should make easier (I've been thinking about a small class for libraries like this) and warn in sanity checks when it happens.
Oh and I'm surprised that the library ends up in the image in your second example, as example will contain /usr/lib/foo and example-dev will contains /usr/lib/libceill.so. Unless of course you've got dev-pkgs enabled, which will automatically install example-dev if you've got example in an image.
Add the line
FILES_SOLIBSDEV = ""
An explanation from the Yocto mailing list:
I had FILES_${PN} += “${libdir}/.so” in there and that didn't work.
Maybe it was because I was missing the FILES_SOLIBSDEV = “" you mentioned.
I'll play with it some more and see what happens. I first started out with
FILES_${PN} += “${libdir}/.so” and when that didn't work I tried other
things in the FILES_${PN} = line to try and get it picked up. When I
couldn't get any of it to work and then saw others (well, at least the link
I provided) were seeing the same thing I figured it was time to quit
spinning my wheels and consult the big guns :)
Heh :) The issue there is that the patterns are matched in the order of the
PACKAGES variable. The first package to include a file gets it, and
${PN}-dev is in PACKAGES before ${PN}. By emptying FILES_SOLIBSDEV, that’ll
remove the .so from FILES_${PN}-dev, letting the ${PN} package get it
instead.
Add the line:
FILES_${PN}_dev_remove="${FILES_SOLIBDEV} "
It will move out the package for development path.

Portable access to sysconfdir via config.h

I'd like my application to have portable access to the configuration files installed during make install (dist_sysconf_DATA). Is it possible to access $(sysconfdir) via config.h?
It is, but you should not do this according to official voices (as in, I am not gonna search the manual for it now) so as to continue supporting overriding it for specific objects to be built.
make CPPFLAGS="-USYSCONFDIR -DSYSCONFDIR=/blah" thisoneobject.o
Hence, what one is supposed to do:
AM_CPPFLAGS = -DSYSCONFDIR=\"${sysconfdir}\"
If you're using autoheader, adding this to your configure.ac will output a SYSCONFDIR macro in your config.h, and it will be defined with the value $(sysconfdir) or ${prefix}/etc.
if test "x$sysconfdir" = 'x${prefix}/etc'; then
if test "x$prefix" = 'xNONE'; then
sysconfdir=$ac_default_prefix/etc
else
sysconfdir=$prefix/etc
fi
fi
AC_DEFINE_UNQUOTED([SYSCONFDIR], ["$sysconfdir"], [location of system configuration directory])
But I would strongly recommend against doing that, and instead, stick with using the -DSYSCONFDIR flag. It's less code and therefore less prone to something going wrong. Using a condition in configure.ac such I mentioned may not be portable or take into account every case that might be encountered. Using -DSYSCONFDIR is the best option. Sometimes appearance just doesn't matter.
What I believe is most commonly done (and this is what I do)
Add the following in your Makefile.am
AM_CPPFLAGS = -DSYSCONFIR='"$(sysconfdir)"'
And now you can access SYSCONFDIR in source

Resources