Won't all languages (that doesn't have concept of virtual machine) be platform independent if someone writes different compiler (just like different JVM for each platform in Java) for different platform?
Well, yes and no. These days most languages are, indeed, more or less platform-independent. But these days, the language is only part of a program: you probably need database access, or graphics, or networking, or file access, or multithreading, or what-have-you. For some languages -- C and C++, of course, being the canonical examples here -- all these things are accomplished using libraries that haven't traditionally been part of the language standard. There are cross-platform APIs for many of these --i.e., you can use Qt for graphics, or Berkeley Sockets for networking -- but in general you can't just assume all those APIs are there. To deploy a program using these across multiple platforms, you have to assemble a hodgepodge of these portable APIs, sometimes with small platform-dependent variations, and make them work together somehow. And then, of course, you have to get your Frankenstein's monster to compile on all the platforms of interest using different platform-specific tools, so you can distribute a platform-specific binary for each platform. And separate 32- and 64-bit binaries too, these days! It's not impossible, but it can sure be a hassle.
Compare this to Java. You can always assume all the core APIs are there, you only have to compile once -- it's an awful lot easier.
There are at least two issues here. First is the language itself. Then second is the runtime support libraries, APIs, etc.
Its more complicated that just building a cross compiler. Some popular languages, for example C, do not define critical concepts in a machine independant way. The size of an "int" in C can vary, which has serious implications when you change platforms. This is good for C, it runs on tiny 8 bit machines up through at least 64 bit machines.
To make a language cross platform, the specs have to define a lot of details. Java was designed from the start to be cross platform, so it includes the specs. But even Java has some issues, a lot of crypto code works with unsigned octets, which are roughly bytes. But Java "byte" and "Byte" are signed. So you have to be very careful with them.
Making the platform and APIs be seriously machine/operating system independent is hard. Java does a good job at it. But the dream of "write once, run everywhere" is marketing. You can do tons of stuff natively, but sometimes, there are system dependencies that you have to program for.
I'm not even sure any more that pure platform independence is a valid goal. I believe it is impossible to have a quality user experience without designing for the device. We no longer write code for text display on a terminal. How you use a touch interface is different from how you use a mouse and display. You need to control things like display resolution, etc.