You may be confused (as it seems many people are) by taking the shortcut of
compiling and linking in one command.
g++ -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor main.cpp
is a shortcut functionally equivalent to:
# g++ invokes the C++ compiler (cc1plus). The linkage options are ignored.
g++ -c -o deleteme.o main.cpp
# g++ invokes the system linker (ld). The linkage options are passed.
g++ -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor -o a.out deleteme.o
rm deleteme.o
If you executed both steps explicitly, you would do, e.g.
# Compile step
g++ -c -o main.o main.cpp
# Link step.
g++ -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor -o prog main.o
In the link step, g++ covertly adds the default C++ linkage options for the host
system to the commandline, then hands it off to the linker. The C++ compiler is
not involved.
By default, the linker will examine a library at most once, when it is encountered
in the commandline linkage sequence, and it will examine the library only to see
if the library can resolve any hitherto unresolved symbols referenced earlier in the
linkage sequence. At the end of the linkage sequence, if all referenced symbols are
resolved, the linkage succeeds and otherwise fails.
The linkage:
g++ -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor -o a.out deleteme.o
will fail because all the libraries appear before any object file. When each library
is reached, the linker has discovered no unresolved symbols yet so the library is ignored.
When the linker finally reaches the trailing object file and discovers some unresolved
symbols, they remain unresolved.
Conversely,
g++ main.cpp -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
is equivalent to:
g++ -c -o deleteme.o main.cpp
g++ -o a.out deleteme.o -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
rm deleteme.o
in which the linkage order is correct, with the symbols that require definitions
being discovered before the libraries that provide them.