Distinguish dev builds from Rack library builds

Logging messages is very useful, but I’ve heard that plugins in the library are forbidden from logging to the rack log using DEBUG (et al).

So, is there a predefined symbol I can use to conditionally exclude this dev-logging or is this something I have to figure out how to implement for my own build? Seems like a common enough need that it would be useful for the rack build system to provide a common mechanism to exclude logging.

1 Like

well, it’s kind of like any software - you aren’t supposed to log a ton of stuff. We call it “console spam” where I work. VCV isn’t particularly different in this respect, is it? Traditionally it has always been up to developers to make whatever they want in a “debug build”, and be well behaved in a “release build”, yes? Or am I missing something here?

Exactly. I know this stuff. In all my past experience DEBUG versus RELEASE builds are always baked right into every build system that is created (I was a software engineer at Microsoft for >15 years). Each dev doesn’t need to recreate their own build system.

The thing is, the Rack build system doesn’t appear to have a debug / release build mechanism. There’s no mention of it in the development guide. The debug target doesn’t do a debug build – it runs gdb. I didn’t see any likely targets in the makefile.

I can of course do the grunt work to wire up this basic task of engineering, but I’m asking if there’s something I missed already present in the rack build system. I can do it, but I don’t enjoy messing with build systems. I’ve already had to hack Rack to make working in it easier (like turn down/off optimizations for debugging), but I wish I didn’t need to.

oh, ok, no, I don’t think there’s anything already in there.

Well, I guess I’ll have to roll up my sleeves. I don’t think I’ve had to muck about in makefiles since I was writing documentation for NMAKE back in the 80’s.

Well, it’s not like there are 1000 programmers working on vcv.you are going to need to do some thing yourself.

My first releases of Meander included extensive logging to the log file that was enabled and disabled by “#define” “#if defined()”, etc. So, debug logging could be turned on and off at compile time, so ideally the logging would not be done in the production release. But, I missed one part of the code where I forgot to do a “#if defined()” before logging and as a result, a significant amount of logging was happening. That got flagged during the VCV library review and I was told to fix the problem, which I did by making sure the problem area did in fact not have the define. That allowed me to still have very extensive logging for development. But, it really bulked up the source code.

I needed a lot of debug logging as Meander was originally a MS-Windows for Workgroups application and there was a lot of work required to make it work in Rack. In particular, I had a very hard time with out of bounds array indexing that really caused problems and crashes. Without this level of logging, I probably would never have found some of the bugs before giving up out of frustration. In the end, I went overboard and wrote in debug code that would “audit” every array and index I used and that fairly quickly pointed out all of my problems, which I fixed.

I left this debugging code in place through all versions of Meander for VCV Rack 1.x . When I ported Meander to VCV Rack 2, I finally removed all of that debugging code.

I never got flagged by the VCV library review workflow as long as I did not log any significant amount of stuff to the log file.

Edit: Looking at my old Meander code, most often I defined a global bool doDebug variable. This bulked up the code and slowed execution somewhat, but that is what I used.

So the question is more of the mechanics of where you set it. Do you use a custom makefile? Set an environment variable? Manually change it in code in a different git branch?

No, I do not use a custom makefile. But, I also do not use debuggers. I am old school and use debug logging with great success. I’ve been doing that for about 35 years. I spend more time fighting with debuggers than benefiting from them :wink:

1 Like

Also, I do all of my development on the local machine and do not upload to GitHub until I have the new release ready for the library. I go not use GitHub workflows such as version control on the local machine. I’m old school in all ways, I do my own version control and backups manually.

When I was on a commercial product development team, we used SVN for version control and we had debug builds and release builds. The younger guys loved debuggers.

Well, I did some work on the VS debugger back in the day (actual first or second release of what later became Visual Studio).

When I owned Windows scripting (Vista timeframe) I spent a lot of time debugging other team’s crashes in WinDbg or sometimes the kdb (special debugger for kernel code). Scripting would be in the call stack because many tests were driven by jscript or vbscript. The automated crash analyzer was designed to skip certain team’s code, and move up the stack to find the nearest non-exceptional team’s code, and whoever owned that was assigned the task of debugging it. The crash cause was never once in the code I owned. That built a lot of debugging skills, including reading x86 assembly code.

You have to use a debugger in these scenarios because you have no way to add logging to other team’s code. Plus a full build of Windows in those days could take a week, so there is no practical change/build/run cycle.

Making a Rack module brings me back to the joys of C++ for the first time in 15 or so years. Makes me appreciate Rust where so many of these crashes simply can’t happen in code that compiles.

2 Likes

how can you not have a custom makefile? that’s where you define $SLUG and other things, and where you specify your include paths?

In any case, for sure defining a single symbol is the easiest, most normal way to do this. Something similar from my Makerfile:

# Macro to use on any target where we don't normally want asserts
ASSERTOFF = -D NDEBUG

# Make _ASSERT=true will nullify our ASSERTOFF flag, thus allowing them
ifdef _ASSERT
	ASSERTOFF =
endif

I’m using that to keep asserts out of “real” builds, but the same idea works for logging, of course.

1 Like

You are right. Of course I use a makefile, but I have not messed with it since 2021. I was thinking it is not customized, but… I do not have a $SLUG in it. “slug” is defined in my plugin.json file. So, not sure if the results are dual to the two approaches.I do have include file paths in the makefile, but those are just relative to RACK_DIR.

Yeah, I think the SLUG was something that was required for VCV 0.6 or 1.0 or something, and just ignored now? In any case, you confirmed what I thought you meant. You have not modified the default one much. I also did only what I needed, but that did involve multiple targets and come custom command line options.

1 Like