#include "ld.h" #include "helper.h" #include "libgen.h" #include "target.h" CUtlString CLDProject::Link( void ) { CUtlString szFileName; unsigned int hash = GenerateProjectHash(); switch(linkType) { case ELINK_EXECUTABLE: if (m_target.kernel == TARGET_KERNEL_WINDOWS) szFileName = CUtlString("%s.exe", m_szName.GetString()); else szFileName = CUtlString("%s", m_szName.GetString()); break; case ELINK_STATIC_LIBRARY: szFileName = CUtlString("lib%s.a", m_szName.GetString()); break; case ELINK_DYNAMIC_LIBRARY: if (m_target.kernel == TARGET_KERNEL_DARWIN) szFileName = CUtlString("lib%s.dylib", m_szName.GetString()); if (m_target.kernel == TARGET_KERNEL_LINUX) szFileName = CUtlString("lib%s.so", m_szName.GetString()); break; } CUtlString szTarget = m_target.GetTriplet(); CUtlString szOutputFile = CUtlString("%s/%s/ld/%u_%s/%s",FPC_TEMPORAL_DIRNAME, szTarget.GetString(), hash, m_szName.GetString(), szFileName.GetString()); CUtlString szOutputDir = szOutputFile; szOutputDir = dirname(szOutputDir); IFileSystem2::MakeDirectory(szOutputDir); if (linkType == ELINK_STATIC_LIBRARY) { V_printf(" AR %s\n", m_szName.GetString()); bool shouldRecompile = false; CUtlVector args; for (auto object: objects) { if (IFileSystem2::ShouldRecompile(object.m_szObjectFile,szOutputFile)) { shouldRecompile = true; break; } } if (!shouldRecompile) goto compiled; args = { "rcs", szOutputFile }; for (auto object: objects) args.AppendTail(object.m_szObjectFile); IRunner::Run("ar", args); IRunner::Wait(); } else { V_printf(" LINK %s\n", m_szName.GetString()); bool shouldRecompile = false; CUtlVector args; for (auto object: objects) { if (IFileSystem2::ShouldRecompile(object.m_szObjectFile,szOutputFile)) { shouldRecompile = true; break; } } if (!shouldRecompile) goto compiled; args = { "-o", szOutputFile, "-target", m_target.GetTriplet(), }; if (m_target.kernel == TARGET_KERNEL_DARWIN) { args.AppendTail("-isysroot"); args.AppendTail("/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"); args.AppendTail("-Wl,-export_dynamic"); args.AppendTail("-undefined"); args.AppendTail("dynamic_lookup"); } if (m_target.kernel == TARGET_KERNEL_IOS) { args.AppendTail("-isysroot"); args.AppendTail("/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"); args.AppendTail("-miphoneos-version-min=18.0 "); args.AppendTail("-fembed-bitcode"); args.AppendTail("-Wl,-rpath,@executable_path"); args.AppendTail("-Wl,-all_load"); args.AppendTail("-w"); } if (m_target.kernel == TARGET_KERNEL_WINDOWS) { args.AppendTail("-fuse-ld=ld"); } if (m_target.kernel == TARGET_KERNEL_LINUX) { args.AppendTail("-rdynamic"); } if (linkType == ELINK_DYNAMIC_LIBRARY) { args.AppendTail("-shared"); } if (m_target.kernel == TARGET_KERNEL_WINDOWS || m_target.kernel == TARGET_KERNEL_LINUX) args.AppendTail("-Wl,--whole-archive"); for (auto object: objects) args.AppendTail(object.m_szObjectFile); if (m_target.kernel == TARGET_KERNEL_WINDOWS || m_target.kernel == TARGET_KERNEL_LINUX) args.AppendTail("-Wl,--no-whole-archive"); for (auto lib: libraries) { args.AppendTail("-l"); args.AppendTail(lib); } for (auto &directory: frameworkDirectories) { args.AppendTail("-F"); args.AppendTail(directory); } for (auto &framework: frameworks) { args.AppendTail("-framework"); args.AppendTail(framework); } IRunner::Run("clang++", args); IRunner::Wait(); } compiled: return szOutputFile; };