Friday, September 11, 2020

Re: cmake sporadic library versioning problem

On Thu Aug 13, 2020 at 04:47:47PM +0200, Christian Weisgerber wrote:
> Occasionally, print/poppler fails to build with a curious error:
>
> A shared library has been built with the version number from
> SHARED_LIBS, but during the fake stage this is forgotten and the
> upstream version number used. This produces an error, because the
> file doesn't exist.
>
> It only happens _sometimes_ and this has been going on for months.
>
> Now in my latest bulk build, x11/kde-applications/marble has
> failed the same way:
>
> ===> build
> c++ -fPIC -O2 -pipe -std=c++0x -DNDEBUG -shared -Wl,-soname,libmarblewidget-qt5.so.1.0 -o src/lib/marble/libmarblewidget-qt5.so.1.0 ...
> ===> fake
> CMake Error at src/lib/marble/cmake_install.cmake:41 (file):
> file INSTALL cannot find
> "/usr/obj/ports/marble-kf5-19.12.3/build-amd64/src/lib/marble/libmarblewidget-qt5.so.0.28.0":
> No such file or directory.
>
> So whatever this is, it does not affect only poppler.
>
> The fact that this type of error happens only during _some_ bulk
> builds suggests that it might be triggered by something else on the
> machine. Another port that happens to be installed at the same
> time, or something that is building at the same time.
> (Cf. how "rm /tmp/conftest*" in misc/screen caused mysterious
> configure failures in other ports.)
>

I need a little bit C background knowledge and/or feedback. Let's have a
look at our LIBxxx_VERSION handling in cmake. Full handling below.

Look at:

+ char *env_vers_cstr = getenv(env_name.c_str());

and

+ version = env_vers_cstr;
+ soversion = env_vers_cstr;

we set env_vers_cstr in version and soversion. This both are used deeper
in CMake. So far so good.

Is it possible that char* (env_vers_cstr) points to null or garbage
because env changed? Or is this nonsense and this cannot happen and
env_vers_cstr is always valid with the first match?


$OpenBSD: patch-Source_cmGeneratorTarget_cxx,v 1.13 2020/05/25 05:12:00 rsadowski Exp $

+#if defined(__OpenBSD__)
+ // Override shared library version using LIBxxx_VERSION
+ // environment variable. Needed for OpenBSD ports system.
+ if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ this->GetType() == cmStateEnums::MODULE_LIBRARY) {
+ std::string env_name = "LIB" + targetNames.Base + "_VERSION";
+ char *env_vers_cstr = getenv(env_name.c_str());
+
+ if (env_vers_cstr && strlen(env_vers_cstr) > 0) {
+ // This means an override is present.
+ std::string env_vers = std::string(env_vers_cstr);
+
+ size_t first = env_vers.find_first_of(".");
+ size_t last = env_vers.find_last_of(".");
+
+ if ((first != last) || (first == std::string::npos)) {
+ std::string msg = "Bad ";
+ msg += env_name;
+ msg += " specification: ";
+ msg += env_vers;
+ this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg);
+ } else {
+ version = env_vers_cstr;
+ soversion = env_vers_cstr;
+ }
+ }
+ }
+

No comments:

Post a Comment