The for a constexpr to be calculated at compile time everything that is used in the initialization of that constexpr also must be calculatable at compile time.
If you declare something as const it does not mean that the value will be available at compile time.
Take the following line:
const double dbl = 2.;
The double's representation is not specified by the standard so the OS will have to deal with this. So when your program is loaded by the OS there is a special assembly subroutine in your binary that will make this happen.
If you use an int the representation is specified by the standard so the compiler will know how to work with it. However the same can be achieved by making the double a constexpr as well, so the compiler will compute it in compile time. In this case the double will also be a const (you cannot make something constexpr without also making it const).
So this will work:
constexpr double kPi = 3.14;
constexpr double kPi2 = 2.0*kPi;
If you use an int the compiler will set the value of that const at compile time so the constexpr will work.
Keep in mind that different compilers can interpret const as constexpr in some cases and make it work. But that is not part of the standard.