Problem Selection order Python 3
Override the context

IMO At issue with code in question is not setting the active object, ie the one you want to copy modifiers from, to the others selected.

To set object ob as active

context.view_layer.objects.active = ob


which sets the active object, aka context.object and context.active_object to ob, but until selected it is not context.selected_objects[0]  Wrote this re using "first selected" for active object.  It causes confusion that relates to your issue here, you're only selecting, not "activating"

Anyhow, forget that, recommend overriding the context.  Build a dictionary of the context members needed and pass it to the operator. No messy selecting and setting active object.

Simple test script. It happens I am working on a tree that has a number of modifiers. I will make the tree object active. Add a cube to scene and override it as selected object.

After some testing have determined that the operator needs to override, screen, scene, object and selected_editable_objects 

To test replace "Tree" with name of object with modifiers (source) and "Cube" with the name of target mesh to copy to.


Modifiers copied from tree to cube with neither selected and empty active

import bpy

context = bpy.context
scene = context.scene
cube = scene.objects.get("Cube")
tree = scene.objects.get("Tree")

override = {}
override["screen"] = context.screen
override["scene"] = context.scene
override["object"] = tree
override["selected_editable_objects"] = [tree, cube]

bpy.ops.object.make_links_data(override, type='MODIFIERS')


can see how this could be made into a little helper method, simply pass it context and the target and source object.