Visual Studio - Custom Build Step

Started by
2 comments, last by Noxil 4 years, 10 months ago

Hello,

So im not quite sure what term to use for this, but as the title says, i would like to create a custom build step.
In Visual Studio i can see that there are options for this, such as "Custom Build Step" and "Build Events" properties.

Im not sure if these are the right ones or how to really go about using them for what i would like to do.
So what i would like to accomplish is to be able to add new custom preprocessor functions, like __FILE__, __LINE__ etc.
Is there an existing solution for doing things like this?

Example of what i would like to do:


// what the developer see
struct Object {
  const char * getName() const {
   return __OBJECT_NAME__;
  }
};

// what the compiler see
struct Object {
  const char * getName() const {
   return "Object";
  }
};

Looking at the existing options that i know of so far, i could use the "Build Events" and from the pre step allow a custom
tool to go in and parse and generate code. This however seems like going the long way instead of the intended route.
And i would then have to restore the files to their original state after compilation was completed.

Also, this might be a stretch. But being able to do something like this would be awesome.


// what the developer see
template< class T >
struct Object {
  const char * getTypeName() const {
    return __TYPE_NAME__(T);
  }
};

// what the compiler see
template< class T >
struct Object {
  const char * getTypeName() const {
    return "int"; // or whatever type T is
  }
};

So that would mean that the tool / buildstep would have to be injected at the right time after templates have been resolved
and im just guessing that this is out of the question.. :( 

Looking at the "Custom Build Step" options im not quite sure how i would use that, it dident look like it would be a step in the
right direction for the problem im trying to solve, but maby im just missing something.

Suggestions and ideas are very welcome :) 

Advertisement

You can't add these to Visual Studio that easily because this is not build into VS rather than the preprocessor that comes along with MSVC. But what you are trying to achieve (if it is really just what your example shows) is however possible without touching the preprocessor in MSVC.

What you are looking for is similar to RTTI using the _PRETTY_FUNC_ macro. Let me show ya a small example for it


#if defined(__clang__)
#define SIGNATURE __PRETTY_FUNCTION__
#elif defined(__GNUC__)
#define SIGNATURE __PRETTY_FUNCTION__
#elif defined(_MSC_VER)
#define SIGNATURE __FUNCSIG__
#endif

#if defined(__clang__)
#define SIGNATURE_PREFIX "char *tui() [T = "
#define SIGNATURE_SUFFIX "]"
#elif defined(__GNUC__)
#define SIGNATURE_PREFIX "char* tui() [with T = "
#define SIGNATURE_SUFFIX "]"
#elif defined(_MSC_VER)
#define SIGNATURE_PREFIX "char *__cdecl tui<"
#define SIGNATURE_SUFFIX ">(void)"
#endif

#define SIGNATURE_LEFT (sizeof(SIGNATURE_PREFIX) - 1)
#define SIGNATURE_RIGHT (sizeof(SIGNATURE_SUFFIX) - 1)

template<int Size> struct TypeIdentifier
{
    public:
        char value[Size];
        inline TypeIdentifier(const char* identifier)
        {
            Runtime::memcpy(value, identifier, Size);
            value[Size - 1] = 0;
        }
};
template<typename T> inline char* tui()
{
    static TypeIdentifier<sizeof(SIGNATURE) - SIGNATURE_LEFT - SIGNATURE_RIGHT> identifier = TypeIdentifier<sizeof(SIGNATURE) - SIGNATURE_LEFT - SIGNATURE_RIGHT>(SIGNATURE + SIGNATURE_LEFT);
    return identifier.value;
}

I use this as basis for my type system. Calling tui - Type Unique Identifier creates a static global initialized struct of certain size that has just one task, to store a c-style string that is prefilled during construction with the SIGNATURE macro that itself is prefilled by the compiler during building with the full name of the function called.

The trick is the template type; it is placed into the function signature at compile time and can then be cutted from the rest so you end up with something like


std::cout << tui<uint64_t>();

to print


unsigned long long int

 

I then wrapped an ammount of convinience around that in my type system but the base of any type-id related function is still my tui<>() call

Hey

This is great!

Thank you for taking the time to reply.
I have only made a small test, but this is really in line with what i want to do.

This topic is closed to new replies.

Advertisement