How to compile an official VS1003 / VS1053 example for Arduino / ESP8266?
Ok, after long battle with C++ compiler I have a working example (at least for VS1003 and ESP8266) with a checklist how to recreate it (with minimal changes to the example files). I'm sure someone else will have this problem so I'm attaching it:

The things that you need to do in player1003.c:


rename to player1003.h (change file extension only)
remove all 5 includes from the top (stdio, string, stdlib, ctype, "player.h")
turn off REPORT_ON_SCREEN (change #if 1 to #if 0) if you don't want to have a lot of serial output
mass replace "FILE *" to "File " - mind the space (change type of file variables in all methods, mark "Case sensitive" to avoid errors in player1053!)
mass replace fopen( to fopen2(
mass replace printf( to Serial.printf(
mass replace fflush(stdout); to //fflush(stdout); (or Serial.flush();)
remove method: VSTestInitHardware(void)
remove SM_SDISHARE flag from WriteSci(SCI_MODE, SM_SDINEW|SM_SDISHARE|SM_TESTS|SM_RESET); line  (in VSTestInitSoftware(void) method)
in VSTestHandleFile() at the bottom add fp.close(); after VS1003PlayFile(fp); and VS1003RecordFile(fp); lines (especially after the record!). We don't want unclosed files on SD card.


The main sketch (.ino):

#include &lt;SPI.h&gt;
#include &lt;SD.h&gt;
#include "player.h"

using namespace std;


// I use these values below for ESP-12 (ESP8266):
#define MP3_xCS 2
#define MP3_xDCS 4
#define MP3_DREQ 5
#define MP3_xRESET 16
#define SD_CS 15
#define SPI_MOSI 11 //SPI
#define SPI_MISO 12 //SPI
#define SPI_CLK  13 //SPI


#define  WAIT_DREQ()  while(!digitalRead(MP3_DREQ))


File song;


int VSTestInitHardware()
{
  pinMode(MP3_DREQ, INPUT);
  pinMode(MP3_xCS, OUTPUT);
  pinMode(MP3_xDCS, OUTPUT);
  pinMode(MP3_xRESET, OUTPUT);
  pinMode(SD_CS, OUTPUT);

  digitalWrite(MP3_xCS, HIGH);
  digitalWrite(MP3_xDCS, HIGH);

  digitalWrite(MP3_xRESET, LOW); // chip off!
  delay(100);
  digitalWrite(MP3_xRESET, HIGH); // chip on!

  Serial.begin(115200);

  if (!SD.begin(SD_CS))
  {
    Serial.println("Can't initialize SD!");
    return -1;
  }
  Serial.println("SD OK!");

  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV32);  // Bus SPI at 1MHz (for Arduino: 16MHz / 16 = 1MHz)
  SPI.transfer(0xFF);  // Write something to the bus
  delay(10);
  return 0;
}


void setup()
{
  if (VSTestInitHardware() || VSTestInitSoftware())
  {
    Serial.printf("Failed initializing VS10xx, exiting\n");
    exit(EXIT_FAILURE);
  }
  /* ... */
  /* Playback example. You can call these functions many times in a row
  because they leave VS1003 in a stable state. */
  VSTestHandleFile("TEST.mp3", 0);  // remember to use 8.3 file names format on SD!
  /* Recording example */
  VSTestHandleFile("RECORDED.WAV", 1);  // original example for VS1003 has a bug here (OGG extension)

  Serial.println("Playing recorded file...");
  VSTestHandleFile("RECORDED.WAV", 0);

  Serial.println("THE END");
}

void loop()
{
}



void WriteSci(unsigned char reg, unsigned char hsb, unsigned char lsb)
{
  // for debugging:
  Serial.printf("Setting %s to: %d (%X, %X)\n", RegName(reg), (hsb&lt;&lt;8) + lsb, hsb, lsb);

  WAIT_DREQ();
  digitalWrite(MP3_xCS, LOW);

  SPI.transfer(0x02);
  SPI.transfer(reg);
  SPI.transfer(hsb);
  SPI.transfer(lsb);
  WAIT_DREQ();
  digitalWrite(MP3_xCS, HIGH); 
}


void WriteSci(u_int8 addr, u_int16 data)
{
  WriteSci(addr, data &gt;&gt; 8, data &amp; 255);
}


uint16_t ReadSci (unsigned char reg)
{
  WAIT_DREQ();
  digitalWrite(MP3_xCS, LOW);

  SPI.transfer(0x03);
  SPI.transfer(reg);
  delayMicroseconds(10);

  char response1 = SPI.transfer(0xFF);
  WAIT_DREQ();
  char response2 = SPI.transfer(0xFF);
  WAIT_DREQ();

  digitalWrite(MP3_xCS, HIGH);

  unsigned int resultvalue = response1 &lt;&lt; 8;
  resultvalue |= response2;

  // for debugging:
  if (reg != SCI_HDAT0 &amp;&amp; reg != SCI_HDAT1)  // these registers are filtered out because they are intensively used during recording
    Serial.printf("%s is: %d (%X, %X)\n", RegName(reg), resultvalue, resultvalue &gt;&gt; 8, resultvalue &amp; 255);

  return resultvalue;
}


int WriteSdi(const u_int8 *data, u_int8 bytes)
{
  WAIT_DREQ();
  digitalWrite(MP3_xDCS, LOW);

  for(int y = 0 ; y &lt; bytes ; y++)
    SPI.transfer(data[y]);

  digitalWrite(MP3_xDCS, HIGH);
}


const char* RegName(uint8_t reg)
{
  switch (reg)
  {
    case 0x00: return "SCI_MODE";
    case 0x01: return "SCI_STATUS";
    case 0x02: return "SCI_BASS";
    case 0x03: return "SCI_CLOCKF";
    case 0x04: return "SCI_DECODE_TIME";
    case 0x05: return "SCI_AUDATA";
    case 0x06: return "SCI_WRAM";
    case 0x07: return "SCI_WRAMADDR";
    case 0x08: return "SCI_HDAT0";
    case 0x09: return "SCI_HDAT1";
    case 0x0A: return "SCI_AIADDR";
    case 0x0B: return "SCI_MIXERVOL";
    case 0x0C: return "SCI_AICTRL0";
    case 0x0D: return "SCI_AICTRL1";
    case 0x0E: return "SCI_AICTRL2";
    case 0x0F: return "SCI_AICTRL3";
  }
}


void SaveUIState(void)
{
}

void RestoreUIState(void)
{
}

int GetUICommand(void)
{
  while (Serial.available() &gt; 0)
  {
    char c = Serial.read();
    if (c != 10 &amp;&amp; c != 13)
      return c;
  }
  return -1;
}


void exit(int code)
{
  if (code == EXIT_SUCCESS)
    Serial.println("Exited with no error.");
  else
    Serial.printf("Terminated with error: %d\n", code);
  while (true) { yield(); }  // yield() is needed for ESP8266 only
}


File fopen2(const char* fileName, const char* mode)
{
  if (mode[0] == 'w')  // fast workaround!
  {
    Serial.printf("Opening for writing: %s\n", fileName);
    song = SD.open(fileName, O_WRONLY | O_TRUNC | O_CREAT);
  }
  else
  {
    Serial.printf("Opening for reading: %s\n", fileName);
    song = SD.open(fileName, O_RDONLY);
  }

  if (!(song)) 
  {
     Serial.printf("File not found: %s\n", fileName);
     return song;
  }
  Serial.printf("File opened: %s\n", fileName);
  return song;
}

size_t fread ( void * ptr, size_t size, size_t count, File stream )
{
  yield();  // this is needed for ESP8266 only (otherwise reboots)
  return stream.read(ptr, size * count);
}

int fseek ( File stream, long int offset, int origin )
{
  stream.seek(offset);
}

size_t fwrite ( const void * ptr, size_t size, size_t count, File stream )
{
  return stream.write((uint8_t*)ptr, size * count);
}

int fflush ( File stream )
{
  stream.flush();
  return 0;
}


#include "player1003.h"


(i had to manually clean this file out of my additional code, but I hope it will compile just fine).

I have a request:

If you run this example, please write me in comment whether the recording worked. I can't make my VS1003 module record sound. I have a suspicion that mic in my module is broken. That's why I was trying the official example (with the minimum changes as possible). It records only noise in my case, but plays mp3 perfectly. If you have a working example of recording, please share too.

And one more to the people with more rep (moderators): Please add a VS1003 (and VS1053 and VS1063) keywords and assign it to my questions about VS1003, because I'm unable to do it and it should be done. The chip deserves a keyword. (It's really good and not expensive.)