Here is a path which would enable a GL driver to do parallel shader compiling and linking,
(1.) At the start of application load, for all shaders run {glShaderSource(), glCompileShader()}, then for all programs run {glAttachShader()s, glLinkProgram()}. Do not call anything which queries a shader or program. This is the critical rule as without queries the driver is not forced to block on the results of a compile or link.
(2.) Do other loading work in parallel.
(3.) Only on a frame which has first use of a given program, then call functions which query a shader or program: for example reflection (to get locations of named values) or get compile or link status. Ideally use GLSL's layout() qualifiers to avoid the need to do any reflection.
(1.) At the start of application load, for all shaders run {glShaderSource(), glCompileShader()}, then for all programs run {glAttachShader()s, glLinkProgram()}. Do not call anything which queries a shader or program. This is the critical rule as without queries the driver is not forced to block on the results of a compile or link.
(2.) Do other loading work in parallel.
(3.) Only on a frame which has first use of a given program, then call functions which query a shader or program: for example reflection (to get locations of named values) or get compile or link status. Ideally use GLSL's layout() qualifiers to avoid the need to do any reflection.