Ensuring internal shared library versions are correct

拜拜、爱过 提交于 2019-12-12 01:32:14

问题


I'm currently tasked with trying to improve our companies versioning practices when it comes to our internal libraries. I've read about Semantic Versioning 2.0.0 and this seems like a really nice, simple and elegant solution to our current problem where our current versioning practices (e.g. library_v01) don't really tell us much about each library version.

Ideally the applications would check the version of the library being used at compile time as to catch any mismatches before a deployment and/or test. Our applications are written in Visual Studio and we're soon to upgrade to C++11 compiler friendly VS2013 which is why my first idea was to use static_asserts in order to check versions at compile time something like:

// Defined in library code and accessible by applications
struct LibraryVersion {
    static const unsigned int LIB_VERSION_MAJOR = 1;
    static const unsigned int LIB_VERSION_MINOR = 0;
    static const unsigned int LIB_VERSION_PATCH = 0;
}

// Application code
static const unsigned int EXPECTED_LIB_VERSION_MAJOR = 1;
static const unsigned int EXPECTED_LIB_VERSION_MINOR = 0;
static const unsigned int EXPECTED_LIB_VERSION_PATCH = 0;

void lib_version_check() {
    static_assert(LibraryVersion::LIB_VERSION_MAJOR == EXPECTED_LIB_VERSION_MAJOR, "Error Major");
    static_assert(LibraryVersion::LIB_VERSION_MINOR == EXPECTED_LIB_VERSION_MINOR, "Error Minor");
    static_assert(LibraryVersion::LIB_VERSION_PATCH == EXPECTED_LIB_VERSION_PATCH, "Error Patch");
}

Also it'd be nice to have some kind of pre-processor definition within a library prop file which could be used in include paths so that correct library files are always included by each application e.g.

$(LIB_DIR)="C:\Libs\"
$(LIB_VERS)="v1.0.0"
Include_Path = $(LIB_DIR)\$(LIB_VERS);

With the file structure looking something like:

C:\Libs\v1.0.0\include\...
C:\Libs\v1.0.1\include\...
C:\Libs\v1.0.2\include\...
C:\Libs\v1.2.0\include\...

However this to me doesn't seem to be the most elegant solution and having to keep track of two version variables (both the pre-processor value and the unsigned integers representing MAJOR, MINOR and PATCH version) seems a bit much.

So basically I'd like to ask if others have come across anything similar and if they have any insight in to what an elegant solution might be or if there are any pitfalls to using the above solution that maybe I haven't thought of? Perhaps having a file structure like the one described above is problematic and/or there is an easier way? Any feedback would be appreciated. Many thanks.


回答1:


We just generate a header with a template using the git tags as the major, minor and patch. We do what you have done above but it's all automated. This doesn't solve the compilation dependencies.

However, the dependency of what library versions are need is hoisted up into the package dependency of our custom waf build system. For example:

# We need boost
conf.env.BOOST_MINIMUM_VERSION = (1, 50)
conf.load('boost', tooldir=vcawaflib.dir)

# VCA project dependencies
conf.env.VCA_TEST_MINIMUM_VERSION = (0, 2, 3)
conf.project_uselib('sdk/test', 'vca_test')

The build system interfaces with the systems package manager (on Windows it uses a custom python package manager we have written) and that resolves all the dependencies.

That being said, it has been a lot of work to get our build system set up. For your case, you could allow the compiler to work out the library dependencies but I would use std::tuple as that does the Right Thing when it comes to version comparisons

include/my_awesome_library/version.h

namespace my_awesome_library {
  static constexpr auto version = std::make_tuple(1, 0, 0);
}  // namespace my_awesome_library

src/my_program_or_library/dependencies.c

static_assert(my_awesome_library::version >= std::make_tuple(1, 0, 0), "\nmy_awesome_library is old");

This could be preprocessor defined as:

#define VERSION_CHECK(version, ...) \
  static_assert(version >= std::make_tuple(__VA_ARGS__), #version " is old");

VERSION_CHECK(my_awesome_library::version, 1, 0, 0);

You could expand it to do minimum and maximum checks, etc.

Microsoft are doing a great job of becoming more standards compliant in the newer versions Visual Studio but you'll have to check if the above works in whatever MSVC compiler you use.



来源:https://stackoverflow.com/questions/24285925/ensuring-internal-shared-library-versions-are-correct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!