There is no "best" solution to that problem. I wrote a G-code post-processor that, reads the G-code output by the CAM software, re-writes it making a bunch of changes. Some of the things I do are:
1) Logical-to-physical tool mapping - In the CAM, I have a very large number of tools defined, each with a full set of parameters, each optimized for a specific type of cut. So, for each physical tool, say a 1/2" 2-flute HSS endmill, I will have a half-dozen or so logical tools defined - for example, one for slotting, one for finishing, one for peripheral milling, etc. So, in the CAM, I just select the right tool for the type of cut, and don't have to mess with parameters at all. But, the G-code output from the CAM will now have a lot of unnecessary toolchanges, since several logical tools maps to a single physical tool. So, my post-post collapses those, removes the unnecessary toolchanges, and also re-numbers the tools sequentially. I will, at some point, create a tool length database, so the tool lengths will be pulled from the data base when the program is loaded into the CNC controller app (I also wrote my own...).
2) Since my mill has four step-pulleys, and two motor speeds, I optimize the selection of motor speeds and pulleys to minimize the number of pulley changes, and keep the VFD frequency within acceptable limits. When a pulley or motor speed change is required, I insert a prompt into the G-code (using M0) telling me what needs to be changed.
3) I insert code before and after all M0s to stop the spindle and coolant before the M0, and restore them after the M0.
4) I write the tool table into the G-code in a format that my controller app recognizes, and can load directly when the G-code is loaded.
5) I expand all drilling operations to do a custom peck-drilling cycle optimized for my machine and tools.
6) I generate a documentation file giving a summary of the sequence of operations, and they parameters, to make it easier to keep track of where I am while the program is running.
Personally, I find entering tool lengths to be a very, VERY minor inconvenience. My average job probably uses perhaps 6 tools, so it takes only 2-3 minutes to measure all the tools, using a digital height gauge, and enter the data into the tool table when I load the program. Given that my programs run, on average, 60-90 minutes, and I'll run the same program 5-10 times in a given day, those few minutes are lost in the noise. Hence, the reason creating a tool length database is WAY down on my list of priorities.