After tracing edk2 code, I found that the _ASSERT macro used __FILE_NAME__ and __FILE__ extension for getting the filename of source code: MdePkg/Include/Library/DebugLib.h #if defined (_ASSERT) #undef _ASSERT #endif #if defined (__clang__) && defined (__FILE_NAME__) #define _ASSERT(Expression) UnitTestDebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) #else #define _ASSERT(Expression) UnitTestDebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) #endif #else #if defined (__clang__) && defined (__FILE_NAME__) #define _ASSERT(Expression) DebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) #else #define _ASSERT(Expression) DebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression)) #endif #endif That's why pe32+ binary file has many build root folder name. And longer build root name will produce bigger FV image.