Showing posts with label compilation. Show all posts
Showing posts with label compilation. Show all posts

Tuesday, 28 November 2017

CMake rather than Mammoth makefile marathons

I'm having difficulty communicating with some folks about the beauty of cmake and using ccmake to leverage that beauty.

These are folks whom are either completely ignorant of what a makefile should look like, are happy to manage their own or at worst case are folks put off of makefiles by having inherited projects which have spiralled out of control with mammoth makefiles and a propensity to being so complex as to prevent any cost-effective entry grade for new developers to key into - i.e. they're too hard to learn, or obfuscated sufficiently to allow established developers to retain their positions of glory and power.

I don't subscribe to that ethos however, and believe that as a leader in development you should facilitate everyone to be being able to do everyone else's development role, be that starting a new project or continuing an old.

It perhaps comes from my being able to work alone and defining a role which others are then keyed into, I have been forced to allow entry to my work, to make the cost of someone else bootstrapping my work into their wetware (brain) as simple as possible.

Mammoth makefile marathons are not the way for me to do that, a CMakeLists.txt file, now that's a better proposition.  However, even here you have to take care, some folks are ignorant of the tools available, to leverage cmake in this way one might use this kind of command line...


This is daunting for a newbie, and even an experienced developer has to admit...

ccmake <PATH_TO_CMAKELISTS>

This is a much more succinct and easy to access way of getting into your CMake way of working, the cost of entry being so low as to actually make introducing new developers to Linux development, or just general CMake usage, trivial.

So where am I failing to communicate this?

Well, cmake, ccmake... The naming conventions of both are so close as to confuse people, they don't hear the second C in CCmake, or they think I'm talking about the C Programming language.  This is a lack of understanding on their part, people being people however, they don't want to admit they've no idea what you're talking about.

(As an aside, folks, if you want to be a good developer, a good person, please admit when you don't know something, it causes so much less issues in at development scrum time if you are handed work, and you simply state "I know nothing about that".  Someone else can be assigned the role, or better still, you can get training and schedule the work more effectively!)

My solution to this difficulty therefore?

Rename the programs, I've created two symbolic links in /usr/bin....

sudo ln -s /usr/local/cmake/bin/ccmake /usr/bin/makefile_prep_gui
sudo ln -s /usr/local/cmake/bin/cmake /usr/bin/makefile_prep_cmd

I've essentially bamboozled the communication factor by giving cmake the working name "makefile_prep", this means that those opposed to ceasing direct use of makefiles still feel empowered, but are subtly diverted to using an automated tool.

Immediately questions and opposite to changing the status quo has ceased, and folks are talking about using the new "makefile_prep" tools.... How clean they are, how nice the builds look, how they integrate with CLion easily, and "the output from my makefile_prep looks exactly like the build going on inside the IDE (CLion)"... Little do they realise they're both cmake!

Oiling the cogs of resistance to change, this is where I'm living at present... Its not an easy task, but sometimes it's rewarding.... Now to do the same in the day-office.

Thursday, 2 November 2017

C++ : Ignored qualifiers (-Wignored-qualifiers)

What is an ignored qualifier?  Well, in a class, lets have a student class:

#include <string>

class Student
{
    public:
        const std::string Name;

    private:
        bool m_Present;

    public:

        Student(const std::string& p_Name)
            :
            Name(p_Name),
            m_Present
        {
        }        

        void SetPresent() { m_Present = true; }

        void SetAbsent() { m_Present = false; }
};

Now, we may want to access the present flag, therefore provide a function to do so:

    bool Present() const { return m_Present }

This function is telling the user of our class quite a bit, it tells them that the return type is boolean and that the calling of this function makes no changes to the class  contents (const trailing the parameter list).

However, for me, this isn't quite right, I believe that we want to inform any user that the boolean returned is also constant, it does not change unless you alter the internal value with the "Set" functions, therefore I prefer and like to see code stating:

    const bool Present() const { return m_Present; }

This is perhaps overkill and most of the time completely acceptable code to present, however, some might prefer not to see it, specifically anyone defining "-Wignored-qualifiers" as with the "const bool" the const here is technically superfluous, the return type is boolean and a new instance of it, it is not a reference to the internal value, if it were the function may look something more like this:

    const bool& Present() const { return m_Present; }

Now we are intrinsically returning a reference to the internal boolean, or even:

    const bool* const Present() const { return &m_Present; }

For speed of operation we may directly drive the reference back as a constant boolean constant pointer.

I find this much more informative to the user, they know our intent, the code though more verbose communicates its meaning much more clearly.

As ever, yes I have seen questions asked of interfaces where "bool X()", or "bool X() const" is provided but then programmers have asked "How do I change X", with the const return, ignored qualifier or not, the know not to ask this function to change X and can look up elsewhere in your API.