[lld] r217189 - [mach-o] Let darwin driver infer arch from .o files if -arch not used.
Shankar Easwaran
shankare at codeaurora.org
Thu Sep 4 14:48:33 PDT 2014
Thanks for the info. The gnu flavor also needs this same functionality.
Shankar Easwaran
On 9/4/2014 4:40 PM, Nick Kledzik wrote:
> On Sep 4, 2014, at 2:17 PM, Shankar Easwaran <shankare at codeaurora.org> wrote:
>
>> Nice!
>>
>> Is this applicable in partial linking mode ?
>>
>> What if the first file was an archive file or a script (that could contain more inputs) ?
> It looks at each file in command line order until if finds a non-fat MH_OBJECT mach-o file. If none are found, it errors out that -arch is needed.
>
>> I think its better to get the first file from the input graph and query for the arch type ?
> The input graph is not built until the end of the command line parsing, but the arch is needed early because it can effect how other options are processed.
>
> I’m not worried about performance.
>
> -Nick
>
>> On 9/4/2014 3:08 PM, Nick Kledzik wrote:
>>> Author: kledzik
>>> Date: Thu Sep 4 15:08:30 2014
>>> New Revision: 217189
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=217189&view=rev
>>> Log:
>>> [mach-o] Let darwin driver infer arch from .o files if -arch not used.
>>>
>>> Mach-O has a "fat" (or "universal") variant where the same contents built for
>>> different architectures are concatenated into one file with a table-of-contents
>>> header at the start. But this leaves a dilemma for the linker - which
>>> architecture to use.
>>>
>>> Normally, the linker command line -arch is used to force which slice of any fat
>>> files are used. The clang compiler always passes -arch to the linker when
>>> invoking it. But some Makefiles invoke the linker directly and don’t specify
>>> the -arch option. For those cases, the linker scans all input files in command
>>> line order and finds the first non-fat object file. Whatever architecture it
>>> is becomes the architecture for the link.
>>>
>>> Added:
>>> lld/trunk/test/mach-o/infer-arch.yaml
>>> Modified:
>>> lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
>>> lld/trunk/lib/Driver/DarwinLdDriver.cpp
>>> lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
>>> lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
>>> lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
>>> lld/trunk/unittests/DriverTests/DarwinLdDriverTest.cpp
>>>
>>> Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=217189&r1=217188&r2=217189&view=diff
>>> ==============================================================================
>>> --- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
>>> +++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Thu Sep 4 15:08:30 2014
>>> @@ -222,6 +222,7 @@ public:
>>> /// Creates a copy (owned by this MachOLinkingContext) of a string.
>>> StringRef copy(StringRef str) { return str.copy(_allocator); }
>>> + static bool isThinObjectFile(StringRef path, Arch &arch);
>>> static Arch archFromCpuType(uint32_t cputype, uint32_t cpusubtype);
>>> static Arch archFromName(StringRef archName);
>>> static StringRef nameFromArch(Arch arch);
>>>
>>> Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=217189&r1=217188&r2=217189&view=diff
>>> ==============================================================================
>>> --- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
>>> +++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Thu Sep 4 15:08:30 2014
>>> @@ -243,6 +243,20 @@ bool DarwinLdDriver::parse(int argc, con
>>> return false;
>>> }
>>> }
>>> + // If no -arch specified, scan input files to find first non-fat .o file.
>>> + if ((arch == MachOLinkingContext::arch_unknown)
>>> + && !parsedArgs->getLastArg(OPT_test_file_usage)) {
>>> + for (auto &inFile: parsedArgs->filtered(OPT_INPUT)) {
>>> + // This is expensive because it opens and maps the file. But that is
>>> + // ok because no -arch is rare.
>>> + if (MachOLinkingContext::isThinObjectFile(inFile->getValue(), arch))
>>> + break;
>>> + }
>>> + if (arch == MachOLinkingContext::arch_unknown) {
>>> + diagnostics << "error: -arch not specified and could not be inferred\n";
>>> + return false;
>>> + }
>>> + }
>>> // Handle -macosx_version_min or -ios_version_min
>>> MachOLinkingContext::OS os = MachOLinkingContext::OS::macOSX;
>>>
>>> Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=217189&r1=217188&r2=217189&view=diff
>>> ==============================================================================
>>> --- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
>>> +++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Thu Sep 4 15:08:30 2014
>>> @@ -11,6 +11,7 @@
>>> #include "ArchHandler.h"
>>> #include "File.h"
>>> +#include "MachONormalizedFile.h"
>>> #include "MachOPasses.h"
>>> #include "lld/Core/PassManager.h"
>>> @@ -125,6 +126,10 @@ uint32_t MachOLinkingContext::cpuSubtype
>>> llvm_unreachable("Unknown arch type");
>>> }
>>> +bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
>>> + return mach_o::normalized::isThinObjectFile(path, arch);
>>> +}
>>> +
>>> MachOLinkingContext::MachOLinkingContext()
>>> : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
>>> _doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
>>>
>>> Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h?rev=217189&r1=217188&r2=217189&view=diff
>>> ==============================================================================
>>> --- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h (original)
>>> +++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h Thu Sep 4 15:08:30 2014
>>> @@ -252,6 +252,8 @@ struct NormalizedFile {
>>> BumpPtrAllocator ownedAllocations;
>>> };
>>> +/// Tests if a file is a non-fat mach-o object file.
>>> +bool isThinObjectFile(StringRef path, MachOLinkingContext::Arch &arch);
>>> /// Reads a mach-o file and produces an in-memory normalized view.
>>> ErrorOr<std::unique_ptr<NormalizedFile>>
>>>
>>> Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp?rev=217189&r1=217188&r2=217189&view=diff
>>> ==============================================================================
>>> --- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp (original)
>>> +++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp Thu Sep 4 15:08:30 2014
>>> @@ -117,6 +117,59 @@ template <typename T> static T readBigEn
>>> return t;
>>> }
>>> +
>>> +static bool isMachOHeader(const mach_header *mh, bool &is64, bool &swap) {
>>> + switch (mh->magic) {
>>> + case llvm::MachO::MH_MAGIC:
>>> + is64 = false;
>>> + swap = false;
>>> + return true;
>>> + case llvm::MachO::MH_MAGIC_64:
>>> + is64 = true;
>>> + swap = false;
>>> + return true;
>>> + case llvm::MachO::MH_CIGAM:
>>> + is64 = false;
>>> + swap = true;
>>> + return true;
>>> + case llvm::MachO::MH_CIGAM_64:
>>> + is64 = true;
>>> + swap = true;
>>> + return true;
>>> + default:
>>> + return false;
>>> + }
>>> +}
>>> +
>>> +
>>> +bool isThinObjectFile(StringRef path, MachOLinkingContext::Arch &arch) {
>>> + // Try opening and mapping file at path.
>>> + ErrorOr<std::unique_ptr<MemoryBuffer>> b = MemoryBuffer::getFileOrSTDIN(path);
>>> + if (b.getError())
>>> + return false;
>>> +
>>> + // If file length < 32 it is too small to be mach-o object file.
>>> + StringRef fileBuffer = b->get()->getBuffer();
>>> + if (fileBuffer.size() < 32)
>>> + return false;
>>> +
>>> + // If file buffer does not start with MH_MAGIC (and variants), not obj file.
>>> + const mach_header *mh = reinterpret_cast<const mach_header *>(
>>> + fileBuffer.begin());
>>> + bool is64, swap;
>>> + if (!isMachOHeader(mh, is64, swap))
>>> + return false;
>>> +
>>> + // If not MH_OBJECT, not object file.
>>> + if (read32(swap, mh->filetype) != MH_OBJECT)
>>> + return false;
>>> +
>>> + // Lookup up arch from cpu/subtype pair.
>>> + arch = MachOLinkingContext::archFromCpuType(read32(swap, mh->cputype),
>>> + read32(swap, mh->cpusubtype));
>>> + return true;
>>> +}
>>> +
>>> /// Reads a mach-o file and produces an in-memory normalized view.
>>> ErrorOr<std::unique_ptr<NormalizedFile>>
>>> readBinary(std::unique_ptr<MemoryBuffer> &mb,
>>> @@ -162,26 +215,8 @@ readBinary(std::unique_ptr<MemoryBuffer>
>>> }
>>> bool is64, swap;
>>> - switch (mh->magic) {
>>> - case llvm::MachO::MH_MAGIC:
>>> - is64 = false;
>>> - swap = false;
>>> - break;
>>> - case llvm::MachO::MH_MAGIC_64:
>>> - is64 = true;
>>> - swap = false;
>>> - break;
>>> - case llvm::MachO::MH_CIGAM:
>>> - is64 = false;
>>> - swap = true;
>>> - break;
>>> - case llvm::MachO::MH_CIGAM_64:
>>> - is64 = true;
>>> - swap = true;
>>> - break;
>>> - default:
>>> + if (!isMachOHeader(mh, is64, swap))
>>> return make_error_code(llvm::errc::executable_format_error);
>>> - }
>>> // Endian swap header, if needed.
>>> mach_header headerCopy;
>>>
>>> Added: lld/trunk/test/mach-o/infer-arch.yaml
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/infer-arch.yaml?rev=217189&view=auto
>>> ==============================================================================
>>> --- lld/trunk/test/mach-o/infer-arch.yaml (added)
>>> +++ lld/trunk/test/mach-o/infer-arch.yaml Thu Sep 4 15:08:30 2014
>>> @@ -0,0 +1,29 @@
>>> +# RUN: lld -flavor darwin -arch i386 -macosx_version_min 10.8 %s -r -o %t \
>>> +# RUN: && lld -flavor darwin -r %t -o %t2 -print_atoms | FileCheck %s
>>> +#
>>> +# Test linker can detect architecture without -arch option.
>>> +#
>>> +
>>> +--- !mach-o
>>> +arch: x86
>>> +file-type: MH_OBJECT
>>> +flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
>>> +sections:
>>> + - segment: __TEXT
>>> + section: __text
>>> + type: S_REGULAR
>>> + attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
>>> + address: 0x0000000000000000
>>> + content: [ 0xC3 ]
>>> +global-symbols:
>>> + - name: _foo
>>> + type: N_SECT
>>> + scope: [ N_EXT ]
>>> + sect: 1
>>> + value: 0x0000000000000000
>>> +
>>> +...
>>> +
>>> +
>>> +# CHECK: defined-atoms:
>>> +# CHECK: - name: _foo
>>>
>>> Modified: lld/trunk/unittests/DriverTests/DarwinLdDriverTest.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/DarwinLdDriverTest.cpp?rev=217189&r1=217188&r2=217189&view=diff
>>> ==============================================================================
>>> --- lld/trunk/unittests/DriverTests/DarwinLdDriverTest.cpp (original)
>>> +++ lld/trunk/unittests/DriverTests/DarwinLdDriverTest.cpp Thu Sep 4 15:08:30 2014
>>> @@ -30,7 +30,7 @@ protected:
>>> }
>>> TEST_F(DarwinLdParserTest, Basic) {
>>> - EXPECT_TRUE(parse("ld", "foo.o", "bar.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "foo.o", "bar.o", "-arch", "i386", nullptr));
>>> EXPECT_FALSE(_context.allowRemainingUndefines());
>>> EXPECT_FALSE(_context.deadStrip());
>>> EXPECT_EQ(2, inputFileCount());
>>> @@ -39,45 +39,40 @@ TEST_F(DarwinLdParserTest, Basic) {
>>> }
>>> TEST_F(DarwinLdParserTest, Output) {
>>> - EXPECT_TRUE(parse("ld", "-o", "my.out", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-o", "my.out", "foo.o", "-arch", "i386", nullptr));
>>> EXPECT_EQ("my.out", _context.outputPath());
>>> }
>>> TEST_F(DarwinLdParserTest, Dylib) {
>>> - EXPECT_TRUE(parse("ld", "-dylib", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-dylib", "foo.o", "-arch", "i386", nullptr));
>>> EXPECT_EQ(llvm::MachO::MH_DYLIB, _context.outputMachOType());
>>> }
>>> TEST_F(DarwinLdParserTest, Relocatable) {
>>> - EXPECT_TRUE(parse("ld", "-r", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-r", "foo.o", "-arch", "i386", nullptr));
>>> EXPECT_EQ(llvm::MachO::MH_OBJECT, _context.outputMachOType());
>>> }
>>> TEST_F(DarwinLdParserTest, Bundle) {
>>> - EXPECT_TRUE(parse("ld", "-bundle", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-bundle", "foo.o", "-arch", "i386", nullptr));
>>> EXPECT_EQ(llvm::MachO::MH_BUNDLE, _context.outputMachOType());
>>> }
>>> TEST_F(DarwinLdParserTest, Preload) {
>>> - EXPECT_TRUE(parse("ld", "-preload", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-preload", "foo.o", "-arch", "i386", nullptr));
>>> EXPECT_EQ(llvm::MachO::MH_PRELOAD, _context.outputMachOType());
>>> }
>>> TEST_F(DarwinLdParserTest, Static) {
>>> - EXPECT_TRUE(parse("ld", "-static", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-static", "foo.o", "-arch", "i386", nullptr));
>>> EXPECT_EQ(llvm::MachO::MH_EXECUTE, _context.outputMachOType());
>>> }
>>> TEST_F(DarwinLdParserTest, Entry) {
>>> - EXPECT_TRUE(parse("ld", "-e", "entryFunc", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-e", "entryFunc", "foo.o", "-arch", "i386",nullptr));
>>> EXPECT_EQ("entryFunc", _context.entrySymbolName());
>>> }
>>> -TEST_F(DarwinLdParserTest, OutputPath) {
>>> - EXPECT_TRUE(parse("ld", "-o", "foo", "foo.o", nullptr));
>>> - EXPECT_EQ("foo", _context.outputPath());
>>> -}
>>> -
>>> TEST_F(DarwinLdParserTest, DeadStrip) {
>>> EXPECT_TRUE(parse("ld", "-arch", "x86_64", "-dead_strip", "foo.o", nullptr));
>>> EXPECT_TRUE(_context.deadStrip());
>>> @@ -130,42 +125,48 @@ TEST_F(DarwinLdParserTest, Arch_armv7s)
>>> }
>>> TEST_F(DarwinLdParserTest, MinMacOSX10_7) {
>>> - EXPECT_TRUE(parse("ld", "-macosx_version_min", "10.7", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-macosx_version_min", "10.7", "foo.o",
>>> + "-arch", "x86_64", nullptr));
>>> EXPECT_EQ(MachOLinkingContext::OS::macOSX, _context.os());
>>> EXPECT_TRUE(_context.minOS("10.7", ""));
>>> EXPECT_FALSE(_context.minOS("10.8", ""));
>>> }
>>> TEST_F(DarwinLdParserTest, MinMacOSX10_8) {
>>> - EXPECT_TRUE(parse("ld", "-macosx_version_min", "10.8.3", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-macosx_version_min", "10.8.3", "foo.o",
>>> + "-arch", "x86_64", nullptr));
>>> EXPECT_EQ(MachOLinkingContext::OS::macOSX, _context.os());
>>> EXPECT_TRUE(_context.minOS("10.7", ""));
>>> EXPECT_TRUE(_context.minOS("10.8", ""));
>>> }
>>> TEST_F(DarwinLdParserTest, iOS5) {
>>> - EXPECT_TRUE(parse("ld", "-ios_version_min", "5.0", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-ios_version_min", "5.0", "foo.o",
>>> + "-arch", "armv7", nullptr));
>>> EXPECT_EQ(MachOLinkingContext::OS::iOS, _context.os());
>>> EXPECT_TRUE(_context.minOS("", "5.0"));
>>> EXPECT_FALSE(_context.minOS("", "6.0"));
>>> }
>>> TEST_F(DarwinLdParserTest, iOS6) {
>>> - EXPECT_TRUE(parse("ld", "-ios_version_min", "6.0", "foo.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-ios_version_min", "6.0", "foo.o", "-arch", "armv7",
>>> + nullptr));
>>> EXPECT_EQ(MachOLinkingContext::OS::iOS, _context.os());
>>> EXPECT_TRUE(_context.minOS("", "5.0"));
>>> EXPECT_TRUE(_context.minOS("", "6.0"));
>>> }
>>> TEST_F(DarwinLdParserTest, iOS_Simulator5) {
>>> - EXPECT_TRUE(parse("ld", "-ios_simulator_version_min", "5.0", "a.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-ios_simulator_version_min", "5.0", "a.o",
>>> + "-arch", "i386", nullptr));
>>> EXPECT_EQ(MachOLinkingContext::OS::iOS_simulator, _context.os());
>>> EXPECT_TRUE(_context.minOS("", "5.0"));
>>> EXPECT_FALSE(_context.minOS("", "6.0"));
>>> }
>>> TEST_F(DarwinLdParserTest, iOS_Simulator6) {
>>> - EXPECT_TRUE(parse("ld", "-ios_simulator_version_min", "6.0", "a.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-ios_simulator_version_min", "6.0", "a.o",
>>> + "-arch", "i386", nullptr));
>>> EXPECT_EQ(MachOLinkingContext::OS::iOS_simulator, _context.os());
>>> EXPECT_TRUE(_context.minOS("", "5.0"));
>>> EXPECT_TRUE(_context.minOS("", "6.0"));
>>> @@ -173,58 +174,67 @@ TEST_F(DarwinLdParserTest, iOS_Simulator
>>> TEST_F(DarwinLdParserTest, compatibilityVersion) {
>>> EXPECT_TRUE(
>>> - parse("ld", "-dylib", "-compatibility_version", "1.2.3", "a.o", nullptr));
>>> + parse("ld", "-dylib", "-compatibility_version", "1.2.3", "a.o",
>>> + "-arch", "i386",nullptr));
>>> EXPECT_EQ(_context.compatibilityVersion(), 0x10203U);
>>> }
>>> TEST_F(DarwinLdParserTest, compatibilityVersionInvalidType) {
>>> EXPECT_FALSE(parse("ld", "-bundle", "-compatibility_version", "1.2.3", "a.o",
>>> - nullptr));
>>> + "-arch", "i386",nullptr));
>>> }
>>> TEST_F(DarwinLdParserTest, compatibilityVersionInvalidValue) {
>>> EXPECT_FALSE(parse("ld", "-bundle", "-compatibility_version", "1,2,3", "a.o",
>>> - nullptr));
>>> + "-arch", "i386", nullptr));
>>> }
>>> TEST_F(DarwinLdParserTest, currentVersion) {
>>> EXPECT_TRUE(
>>> - parse("ld", "-dylib", "-current_version", "1.2.3", "a.o", nullptr));
>>> + parse("ld", "-dylib", "-current_version", "1.2.3", "a.o", "-arch", "i386",
>>> + nullptr));
>>> EXPECT_EQ(_context.currentVersion(), 0x10203U);
>>> }
>>> TEST_F(DarwinLdParserTest, currentVersionInvalidType) {
>>> EXPECT_FALSE(
>>> - parse("ld", "-bundle", "-current_version", "1.2.3", "a.o", nullptr));
>>> + parse("ld", "-bundle", "-current_version", "1.2.3", "a.o",
>>> + "-arch", "i386", nullptr));
>>> }
>>> TEST_F(DarwinLdParserTest, currentVersionInvalidValue) {
>>> EXPECT_FALSE(
>>> - parse("ld", "-bundle", "-current_version", "1,2,3", "a.o", nullptr));
>>> + parse("ld", "-bundle", "-current_version", "1,2,3", "a.o",
>>> + "-arch", "i386", nullptr));
>>> }
>>> TEST_F(DarwinLdParserTest, bundleLoader) {
>>> EXPECT_TRUE(
>>> - parse("ld", "-bundle", "-bundle_loader", "/bin/ls", "a.o", nullptr));
>>> + parse("ld", "-bundle", "-bundle_loader", "/bin/ls", "a.o",
>>> + "-arch", "i386", nullptr));
>>> EXPECT_EQ(_context.bundleLoader(), "/bin/ls");
>>> }
>>> TEST_F(DarwinLdParserTest, bundleLoaderInvalidType) {
>>> - EXPECT_FALSE(parse("ld", "-bundle_loader", "/bin/ls", "a.o", nullptr));
>>> + EXPECT_FALSE(parse("ld", "-bundle_loader", "/bin/ls", "a.o", "-arch", "i386",
>>> + nullptr));
>>> }
>>> TEST_F(DarwinLdParserTest, deadStrippableDylib) {
>>> EXPECT_TRUE(
>>> - parse("ld", "-dylib", "-mark_dead_strippable_dylib", "a.o", nullptr));
>>> + parse("ld", "-dylib", "-mark_dead_strippable_dylib", "a.o",
>>> + "-arch", "i386", nullptr));
>>> EXPECT_EQ(true, _context.deadStrippableDylib());
>>> }
>>> TEST_F(DarwinLdParserTest, deadStrippableDylibInvalidType) {
>>> - EXPECT_FALSE(parse("ld", "-mark_dead_strippable_dylib", "a.o", nullptr));
>>> + EXPECT_FALSE(parse("ld", "-mark_dead_strippable_dylib", "a.o",
>>> + "-arch", "i386", nullptr));
>>> }
>>> TEST_F(DarwinLdParserTest, llvmOptions) {
>>> - EXPECT_TRUE(parse("ld", "-mllvm", "-debug-only", "-mllvm", "foo", "a.o", nullptr));
>>> + EXPECT_TRUE(parse("ld", "-mllvm", "-debug-only", "-mllvm", "foo", "a.o",
>>> + "-arch", "i386", nullptr));
>>> const std::vector<const char *> &options = _context.llvmOptions();
>>> EXPECT_EQ(options.size(), 2UL);
>>> EXPECT_EQ(strcmp(options[0],"-debug-only"), 0);
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>> --
>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation
>>
>
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation
More information about the llvm-commits
mailing list