Using the animation system
Result of making an "edge object" parented to cubes zeroth vertex to the closest vertex point on the ico sphere. A cone is constrained to tip of edge and tracked to the cube. Its motion path has been calculated and displayed for 100 frames
Set Up
Set up your scene, blender rotation unit is natively radians, Using Q code and for this example adding keyframes to rotate cube one revolution in total_moves plus one frames.
import bpy
from math import radians
bpy.ops.mesh.primitive_cube_add(
size=0.51,
location=(0,0,0))
cube = bpy.context.object
bpy.ops.mesh.primitive_ico_sphere_add(
radius=3,
location=(0,0,0))
ico = bpy.context.object
wfm = ico.modifiers.new(name="wire", type='WIREFRAME')
total_moves = 100
cube.rotation_euler.z = 0
cube.keyframe_insert("rotation_euler", frame=0)
cube.rotation_euler.z = radians(360)
cube.keyframe_insert("rotation_euler", frame=total_moves + 1)
Add the "edge" mesh
Next will set up the shortest edge mesh. Contend that instead of creating an edge mesh for each frame can create a single edge mesh and move it. (would also note its possible that all verts of cube are equally close to a vert on ico,)
Make a two vert one edge mesh, both coords at origin (0, 0, 0) For use later have added one vertex to vertex group "Tip".
Consider all variables to be "as above" if not defined.
verts = [
(0, 0, 0),
(0, 0, 0),
]
edges = [
(0, 1),
]
me = bpy.data.meshes.new("Edge")
me.from_pydata(verts, edges, [])
edge = bpy.data.objects.new("Edge", me)
vg = edge.vertex_groups.new(name="Tip")
vg.add([1], 1.0, 'REPLACE')
collection.objects.link(edge)
Parenting
Parenting can be our friend here. If we parent the edge to the cube, then the location of the edge can be set using local coordinates of cube.
Instead I'm going to use vertex parenting. The example below parents the edge to the zeroth (index=0) vertex.
edge.parent = cube
edge.parent_type = 'VERTEX'
edge.parent_vertices = [0, 0, 0]
Could set the location (and or parent) to cube vertex and the location of other vert of this one object using code in question in a frame change handler for example. See https://blender.stackexchange.com/a/183688/15543 re handler code using (non vertex) parented edge object to cube.
Shrinkwrap
Instead I'm going to put up the idea of using shrinkwrap.
swm = edge.modifiers.new("SWM", 'SHRINKWRAP')
swm.target = ico
swm.vertex_group = "Tip"

Image shows the result. The closest point on the wireframe ico is a halfway point on an edges (Since the verts are on sphere surface, a straight line to another cuts into the sphere...) Motion trail from tip to vert (gif above) displays the vert chosen.
Make a disc on vert shrinkwrap target
Make another ico with arbitrarily small faces at its verts.
from mathutils import Matrix
import bmesh
bm = bmesh.new()
for v in ico.data.vertices:
co = v.co
M = v.co.to_track_quat('Z', 'Y').to_matrix().to_4x4()
M.translation = v.co
bmesh.ops.create_circle(
bm,
cap_ends=True,
segments=16,
radius=1e-6,
matrix = M
)
me = bpy.data.meshes.new("IcoSpots")
bm.to_mesh(me)
ico2 = bpy.data.objects.new("IcoSpots", me)
ico2.matrix_world = ico.matrix_world.copy()
collection.objects.link(ico2)
This object can now instead be used as a target of the edge objects shrinkwrap modifier.
Notes.
This is put forward by way of concept. It is only creating the one edge object and parenting it to one vertex by way of demonstration. I also didn't use the modified ico mesh to make the "spot" mesh.
To display the shortest would be tempted to add an edge for each cube vert, and drive its visibility based on other lengths.