To solve the given optimization problem, we first need to define the decision variables and the objective function. Let's denote:

- \(x_s\) as the number of strawberry ice cream cakes produced.
- \(x_m\) as the number of mint ice cream cakes produced.

The profit per strawberry ice cream cake is $2.5, and the profit per mint ice cream cake is $4. The objective is to maximize the total profit, which can be represented by the function:

\[ \text{Maximize:} \quad 2.5x_s + 4x_m \]

The constraints are as follows:

1. The ice cream truck must make at least 10 cakes of strawberry ice cream but cannot make more than 20 cakes:
   \[ 10 \leq x_s \leq 20 \]

2. It must also make at least 20 mint ice cream cakes but cannot make more than 40 cakes:
   \[ 20 \leq x_m \leq 40 \]

3. In total, the ice cream truck can make at most 50 total cakes:
   \[ x_s + x_m \leq 50 \]

All variables are non-negative since they represent quantities of ice cream cakes.

Now, let's convert this problem into Gurobi code in Python:

```python
from gurobipy import *

# Create a new model
m = Model("Ice_Cream_Truck_Optimization")

# Define the decision variables
x_s = m.addVar(lb=10, ub=20, name="strawberry_cakes")  # Number of strawberry ice cream cakes
x_m = m.addVar(lb=20, ub=40, name="mint_cakes")        # Number of mint ice cream cakes

# Define the objective function: Maximize profit
m.setObjective(2.5*x_s + 4*x_m, GRB.MAXIMIZE)

# Add the constraint for total cakes
m.addConstr(x_s + x_m <= 50, name="total_cakes_constraint")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found.")
    print(f"Strawberry ice cream cakes to produce: {x_s.x}")
    print(f"Mint ice cream cakes to produce: {x_m.x}")
    print(f"Total profit: ${2.5*x_s.x + 4*x_m.x:.2f}")
else:
    print("No optimal solution found.")
```