Slice the onions thinly.
Melt the butter in a large pot over medium heat. Add the onions and cook slowly for about 30-40 minutes, until deeply caramelized and golden brown. Stir frequently to prevent burning.
Stir in the flour and cook for 1-2 minutes.
Gradually pour in the white wine (if using) and bring to a simmer, scraping up any browned bits from the bottom of the pot.
Add the beef stock, bring to a boil, then reduce heat and simmer for 20-30 minutes.
Season with salt and pepper to taste.
Preheat the broiler. Ladle the soup into oven-safe bowls.
Sprinkle the grated Parmesan and Gruyere cheese over the top of each bowl.
Broil for 2-3 minutes, or until the cheese is melted and bubbly.
Serve immediately.