See the documentation of
require. It expects a version or expression as an argument.
pckg1::pckg2::$filename is neither one. Namespace can't be built dynamically, you have to access the symbol table to do that. In my code, I use the form of
require that isn't a bareword, so it's understood as a filename (that's why I add ".pm" to it). To be able to access the symbol table, you have to turn strict refs off. Then, you can reference the symbol table of a namespace as a hash of the same name plus
::. See
Of Symbol Tables and Globs to learn more about symbol tables.