It really depends on how determined an attacker you need to guard against. Generally any sufficiently determined attacker can reverse engineer your code if they have access to the compiled code, but it may not be worth the effort.
It might be a performance hit, but you could do things like have the binary image use some self-extracting encryption at runtime, like communicating with a licence server and only decrypting the rest of the code if a licence is valid. That can suffer from man-in-the-middle or replay attacks, etc (especially if the underlying hardware can be virtualized), unless you specifically guard against that too. Presumably you don't have cooperation of the hardware in keeping your code secure, but do you need to consider runtime vulnerability, or just in storage?
Chances are compilation is sufficient protection against casual IP theft; obfuscation is a slightly higher bar, then options get progressively more expensive to implement.