iOS development-related handling of oc-duplicate symbol _objc/undefind symbol errors

Source: Internet
Author: User

Objective:

As an iOS development, I believe we will encounter similar to the "Duplicate symbol" program error. For many novice, may be a bit unprepared, because this type of error is generally not a code logic error, most of the time in the compilation process error caused, so relatively difficult to troubleshoot. In the last few days, I had this problem in the process of quoting two SDKs, and used different means to solve the problem. Today this article is a detailed analysis of this error and how to deal with a discussion, if there are errors in the place also please point out.

Duplicate Symbol/undefind symbol appears duplicate symbol error reason

The reasons for this error are varied and the solution is therefore not fixed, and there are several situations that can lead to high errors.

      1. The. m file is mistakenly introduced as a header file.
      2. The same project contains a file with the same name. (common in multi-person development process easy to appear)
      3. The introduced third-party framework includes files with the same name as the local
      4. The. o file of the third-party framework has the same name
      5. References to different library files contain the same method name
Undefind symbol Error Reason
      1. The associated. A file is not joined.
      2. The corresponding method is missing from the related. a file.
Cause Analysis:

Although the causes of so many kinds of errors seem complex, they are in fact the same source. As we said earlier, this is a compile-time error, and we start analyzing it from the compiler.

The compiler used by XCODE3 is the GCC compiler, and after Xcode4 and version, the compiler used by Xcode has been replaced with the new LLVM compiler. The front-end of the LLVM compiler is clang, of course, Xcode still supports GCC, but it may need to be downloaded manually. The compiler's process is probably the following figure, but the principle is basically the same, mainly in understanding, on-line to see the explanation (the original look here):

Preprocessing: preprocessing is equivalent to assembling a new C program according to a preprocessing command, but often with I as the extension.
Compile: Translate the resulting I file into the assembly code. S file.
Assembly: Translates the assembly file into machine instructions and packs it into an O file that can relocate the target program. The file is a binary file, and the byte encoding is a machine instruction.
Link: The other O files referenced are incorporated into the O file where our program is located and processed to get the final executable file.

Although this is for the C program to explain, but as the C-family of OC is similar. s file is a compilation file, it seems that the clang of Xcode is not this step, but directly to the. o file. *.O file that's what we're talking about. The target file is binary, and in many third-party libraries, we generally see. A or. Framework or direct XXSDK, in fact these files contain. o files. Do not believe you can find a. A file, and then the console to Ar-x *.A instructions, will extract a lot of. o files, which are written by the author. m files are compiled and packaged into. a files. The. o file will eventually be used to link to become an executable file, For example, the IPA file is. Here's a good way to figure out the link process.

The linker (linker) links a single target file ( and perhaps several libraries ) together to produce a complete executable file.

In the symbol resolution phase, the linker scans all target files and library files in the order they appear on the command line, sequentially from left to right, during which time it maintains several collections :

(1) set E is a collection of all target files that will be merged together to form an executable file;

(2) the set U is a set of unresolved symbols (unresolved symbols , such as symbols that have been referenced but not yet defined ) ;

(3) set D is a collection of symbols that have been previously added to the target file defined by E . At first, E , U , D are empty.

The working process of the linker:

(1): to each input file in the command line F , the linker determines whether it is a target file or a library file, if it is the target file, the F is added to E , and the F The unresolved symbols and the defined symbols are added to the U , D Collection, and then the next input file is processed.

(2):IfFis a library file, the linker tries toUAll unresolved symbols in theFMatch the symbols defined in each target module. If a target modulemDefines aUThe unresolved symbols in themAdded toEIn, and putmThe unresolved symbols and the defined symbols are added to theU、DThe collection. Continue toFAll target modules in the module repeat the process until it reaches adon't move. (fixed point) , at this timeUAndDNo longer changes. And those that were not added to theEIn theFThe target module is simply discarded and the linker continues to process the next input file.

(3): If you add an existing symbol to D during processing, or you are not empty when all the input files are scanned, the linker errors and stops the action. Otherwise, it merges all the target files in E to generate the executable file .

The text see "symbol" This word, is not very familiar (see this article title), the error refers to the symbol of this thing, it actually will we in the program 全局变量名 , 函数名 or 类名 , through the OC message send way, we probably also associate with, In OC, the function names are identified to handle the corresponding functions. In the above we see three sets, the D collection is a set of symbols for the legitimate target program, and that is what we are talking about. O 全局变量名 , 函数名 or 类名 all inside. We can view this form by ourselves, by doing the. o file on the console.

NM *.O >> symbols.txt

For example, I get a list of symbols in Cjson here.

All of the function names in the *.O file are eventually stored in the Symbols.txt. In the process of the compiler linking, each time a symbol name is obtained, the system is put into the table, if there is the same name will be an error.

Now do you know why the program is an error?

Analysis results:
      1. The. m file is mistakenly introduced as a header file. : when the. m file is introduced, the. h file in the. m file is also introduced, the compiler no matter how many, all the function name according to the whole, so the duplicate names, error!
      2. The same project contains a file with the same name. (common in multi-person development process easy to appear)
      3. The introduction of the third-party framework contains the same name as the local file: The framework of the same name in the file, generally open source, containing the same symbol name can be understood
      4. The third-party framework's. o file has the same name as ditto
      5. Reference to different library files containing the same method name ibid .

In fact, the mistake is to define the same function name.

      1. The associated. A file is not joined. the name of the symbol that is not in the link list is used error
      2. The corresponding method is missing from the related. a file. a function name that is not in the link list is used to error
Ii. solutions to duplicate symbol/undefind symbol errors

Now that we know the reason, we begin to solve it.

Duplicate symbol Solution

1. The first three reasons belong to the project factor, it is relatively simple, if the. m file reference error, the H file can be changed. The project has the same name file, or delete, or change the name. Have the same function name, either delete it or modify it. Get!

2. The latter two reasons are the reference to the library file problem, which solves a little trouble.

If the duplicate symbol error is caused by the introduction of a third-party framework, take a good look at the hint, usually with a hint that the same function name is included somewhere.

Here to divide the situation, if the use of the same library file, then directly solve the corresponding SDK, the same half can be deleted. The operation flow is as follows:

The general SDK will involve different architectures for compiling on different platforms, for example, if you want to compile on the emulator requires a compatible i386 architecture, the real machine needs to be compatible with the ARMV7 architecture. I'm going to separate the files from the different schemas first. On the console console command, view the supported schemas for the library file:

$ lipo-info FUNSDK  

Print out:

Explains that the static library supports ARMV7 armv7s i386 x86_64 arm64 5 different schemas.

If we want to change it, we need to peel it all, just select the ARMV7 architecture below to demonstrate:

Unzip the ARMV7.
Lipo Funsdk-thin Armv7-output funrmv7.a

After success can look at the file size of the comparison, probably no separation before the 1/5. Describes the static library. A file is really just a compressed package that compresses files from multiple schemas together.

Said before. A file is actually a lot of. o file collection, I want to delete an. o file also to be decomposed, here to remind you, first set up the good one folder, the obtained ARMV7 Schema library file into the folder, in the folder processing, otherwise. o file too much, bad management, lost is not good, Because the door will be packed back after processing. Instructions:

Ar-x funrmv7.a

You can see a lot of. o files.

Find what you want to delete. o delete it. You can also order

RM cjson.o     //deleted is CJSON.O file

After the deletion is complete, it is time to merge back. Step-by-step, want to pack all the. o Files back

Libtool-static-o. /NEW-ARMV7.A *.O    //Package all o files into new-armv7.a  

Just now it will armv7 a schema of the file, to complete the completion of the other architecture will have to deal with. Eventually get all the schema files merged into Static library directives

Lipo-create-output funsdknew armv76.a  i386.a arm64.a armv7s.a  x86_64.a

Finally, Funsdknew renaming FUNSDK (the name of the original SDK in your project) overwrites the SDK in the original project.

Note the point:

If the name is the same, of course, but, I have analyzed,. o file conflicts are not the direct cause of the file itself, but the symbols contained in the file. If the SDK changes the contents of the Cjson file, then the method can avoid the symbol conflict, but the whole file is deleted, the modified content is also deleted, which may eventually lead to the function of the SDK is gone, which is certainly not what we want to see. In fact, this is the problem that I met, and during the final compilation, because the files in FUNSDK were deleted directly, the symbols were missing, like this:

If you see anything, yes, it's also a point in this article Undefind symbol error.

Although the original Cjson is open source, but funsdk on the basis of open-source modification, directly delete Cjson equals to the FUNSDK added SetStringValue function to delete, pre-compiler and Error! What to do?

Please see:

Undefind symbol Solution

Two ways:

    1. Find the SDK provider to the source code of the. o file, and then package it back after modification (oh, the source code is a bit difficult ah). It is better to negotiate with the supplier to revise.
    2. A trickery approach (which I stumbled upon) the General SDK has conflicting files Most of the reason is because the same open source files, to the Internet can be down to, download, the Missing methods (symbols) inside the project, so that you can overwrite the library methods. But there is a certain risk, good luck may be avoided, because your project does not necessarily use all the methods in the SDK, the missing method in your library is not needed, then just write a method, do not need to implement what, the compilation process can pass. Solve!
    3. Missing library file, see if it is target-----bulid phases to add the corresponding. A file (mainly for this reason)
Third, other methods to solve the problem of duplicate symbol

Does each occurrence of this kind of problem need to carry on the above plan to solve? Not necessarily.

We already know that this is an error when compiling the link, and Xcode provides an optional link when linking.

Project: Target---bulid setting, link, oteher link flags

The library links available here are:-all_load-objc-force_load-dead_strip and so on.

In order to solve the problem of duplicate symbol, the following links can be used:

    • After setting the-dead_strip will be the project ignores the duplicate symbols, the final compilation will pass, but if as previously said, ignored things if modified, some of the SDK can cause some of the API can not be used.
    • -force_load can also be compiled by forcing a link to a static library. Need to specify a linked library file

In most cases, it is possible to use-dead_strip and-force_load links, after all, it's easier than the above method to be a few times, isn't it? It is recommended to use this method if there are no special requests.

Attach a link to the meaning of the way.

iOS development-related handling of oc-duplicate symbol _objc/undefind symbol errors

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.