如何组织以前由GCC编译的C源文件将其构建为Xcode包?我有一个重复的符号_主要错误 [英] How to organize C source file previously compiled by GCC Make and build them into an Xcode bundle? I have a Duplicate Symbol _main Error

查看:173
本文介绍了如何组织以前由GCC编译的C源文件将其构建为Xcode包?我有一个重复的符号_主要错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从源代码构建一个.bundle?



这可能听起来像一个简单的问题,但一直阻碍我一个星期...



这是我的问题:



我有一堆.c和.h文件组织在一个文件夹,其子文件夹。源代码是用gcc编写和编译的,并由许多其他make工具测试。源代码有一些实用程序和命令行工具,它有更多的代码作为这些实用程序和工具的库。它是作为我想要重用的库的文件。 (通过库我不是指静态库或某些东西,我只是意味着某些子文件夹中的某些.c和.h文件提供了可以由其他.c文件调用的函数,我想要调用这些函数,但是我的问题比这更复杂:我需要将这些.c和.h构建成一个bundle来重用它。我没有在C中写我的应用程序我正在Unity和Unity开发只能在Mac OS上使用.bundle文件。



这是我的目标:



以正确的方式组织源代码文件夹,以便我可以在Xcode 4中将其构建成捆绑包。



这里是我被卡住的地方:



在构建项目时出现以下错误:


$ b中的重复符号_main $ b /Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccndsmoketest.o

/Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccnd_main.o
for architecture i386


我可以与这个错误有关,因为我可以在源代码中找到很多主条目。他们大多数是测试工具。



这是我试过的:




  1. 那些实用程序.c文件,但没有运气。错误仍然存​​在。我删除并删除,直到一些文件找不到他们正在调用的函数的定义。所以我不得不在那里停下来。


  2. 尽管我无法构建捆绑包,但我可以构建一个C / C ++静态库一个延伸)。在我得到.a文件后,我试图将它放入另一个Xcode项目中,并试图将其构建成一个包。我可以以这种方式构建捆绑包,但是我在访问捆绑包的内容时遇到问题。





  3. 注意:某些Xcode目标(如shell工具和静态库)执行
    不会导致创建bundle或包。这是正常的,
    不需要为这些目标
    类型专门创建bundle。为这些目标生成的二进制文件的目的是要
    被使用。


    (引自:



    以下是我想到的:




    1. 我想到用main_sth。但源代码不是由我写的,所以我不想修改它。 (它只是不觉得像一个正确的方式对我做事情)...

    2. 我知道Xcode已经内置了gcc编译器,所以我猜是否gcc可以做到, Xcode可以吗这只是一个狂野的猜测 - 我不熟悉Xcode和gcc。



    以下是我的问题的总结:




    1. 有没有办法正确组织一堆以前由gcc make编译和编写的代码,以便它们可以内置到Xcode包中?

    2. 将.a库放入Xcode项目并将其构建成捆绑包是否有意义?如果它是有意义的,那么在将.a内置到捆绑包中之后,如何调用.a中定义的函数?

    3. 使用其他东西替换所有的main()条目是否合适? li>


    解决方案

    好吧,我想我已经找出了至少一个解决问题的办法。

    重复的主要错误是由我的源代码中的一大堆主要条目引起的。当代码由gcc make编译时,我猜作者定义了一种编译顺序,以便重复的主机不会成为问题。 (如果你知道如何做,请让我知道,我几乎不知道make工具。)但是,当我将整个源代码文件夹添加到我的Xcode项目中时,Xcode当然会在连接期间抱怨...



    由于我不愿意修改源代码(因为源代码库不是由我开发的),我决定使用另一个策略来解决这个问题。



    如果您自己的代码报告了重复的主错误,可以在此停止阅读。但是,如果你像我一样,使用一堆gcc编译的源代码,并且非常需要一个bundle,但不知道该怎么做,我可以帮助。



    这里是我做的:


    1. 我设置了一个空的工作区。 p>


    2. 我构建了一个C / C ++静态库项目。


    3. 导入我的整个源代码文件夹进入静态库项目。


    4. 为静态库项目设置一些标题搜索路径。


    5. 构建静态库项目。 (现在我有一个可以链接的.a库)


    6. 我设置了一个包含目标的项目。


    7. 在包项目 - >构建阶段 - >使用库链接二进制文件,添加刚刚构建的.a库。


    8. 在软件包项目 - >编辑方案 - >构建中,将静态库项目添加到方案中,并将其移动到列表中,以便它在我的捆绑项目之前构建。


    9. 然后将我的图书馆项目的.h文件添加到我的包项目作为参考。


    10. 之后,添加一个.c文件在我的捆绑项目中,基本上作为一个包装器。我选择了一个我想在Unity中调用的函数,在新的.c文件中写了一个包装函数,并且可以构建该包。


    11. 之后几个尝试和错误,我能够将该软件包导入到Unity中,并能够从Unity调用测试函数。


    我真的很兴奋!虽然没有完成,但我认为这给了我希望,我有信心我可以使用源代码!关于这个解决方案的最好的方法是,我不必修改他人开发的库代码。每当他们更新代码时,我只是更新我的.a库,就是这样!



    虽然我列出了11个步骤,有很多我错过的细节。所以这里是我的参考:


    1. 我遵循本教程将源代码构建到静态库中: http://www.ccnx.org/?post_type=incsub_wiki&p=1315


    2. 我按照这个博客将静态库与我的捆绑代码和扭结制作阶段和搜索标头相关联: http://blog.carbonfive.com/2011/04/04/using-open-source -static-libraries-in-xcode-4 /


    3. 我按照此文档将我的软件包导入到Unity3D Pro作为插件: http://unity3d.com/support/documentation/Manual/Plugins.html


    我强烈推荐第二个参考,因为这样解决了我的问题! strong>



    T哦,问题几乎解决了,还有一些我还没有想到的东西:


    1. 我不知道是否包装功能是必要的。我将在明天再试一次,然后回来更新。

    - 我回来更新:包装函数不是必需的。只需要确保你的bundle项目中有所有标头,你将可以使用头文件中定义的所有数据结构和调用函数。


    1. 我没有使用NSBundle类,虽然我读了几篇关于它的文档。以前,我在考虑使用该类来访问我的包中的.a库,但是当我发现上面写的解决方案时,我没有尝试过该类。

    最后,如果你有更好的解决方案,请不要犹豫,让我知道!


    How to build a .bundle from source code?

    This might sound like a simple problem but it has been hurdling me for a week...

    Here is my problem:

    I have a bunch of .c and .h files that are organized in a folder and its sub folders. The source code was written and compiled with gcc make and tested by many other make tools. The source code has some utilities and command line tools and it has more code that serve as library for those utilities and tools. It is the files that serve as libraries that I want to reuse. (By library I don't mean static library or something, I just mean that some .c and .h files in certain subfolders provide functions that can be called by some other .c files. I want to be able to call those functions, too)

    Yet my problem is more complex than that: I need to build those .c and .h into a bundle to reuse it. I am not writing my application in C; I am developing in Unity and Unity can only take in .bundle files on Mac OS.

    Here is my goal:

    Organize the source code folder in a proper way so that I can build them into a bundle in Xcode 4.

    Here is where I got stuck:

    When building the project I got the following error:

    Duplicate symbol _main in /Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccndsmoketest.o and /Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccnd_main.o for architecture i386

    I can relate to this error because I can find lots of main entries in the source code. Most of them are test utilities.

    Here is what I tried:

    1. I tried removing all those utility .c files but with no luck. The error is still there. I delete and delete until some files cannot find the definition of the function they are calling. So I had to stop there.

    2. Though I wasn't able to build a bundle I was able to build a C/C++ static library (with an .a extension). After I got the .a file I tried to put it into another Xcode project and tried to build it into a bundle. I could build a bundle in that way, but then I had problem accessing the content of the bundle. How do I call functions defined in a .a static library if that library is hidden in a bundle? I read about Apple's documentation which says:

    Note: Some Xcode targets (such as shell tools and static libraries) do not result in the creation of a bundle or package. This is normal and there is no need to create bundles specifically for these target types. The resulting binaries generated for those targets are intended to be used as is.

    (quoted from: https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW1)

    Here is what I thought about:

    1. I thought about replacing all main with something like main_sth. But the source code was not written by me so I didn't want to modify it. (It just doesn't feel like a proper way of doing things to me...)
    2. I learnt that Xcode has gcc compiler built in. So I guess if gcc can make it, so can Xcode? It's just a wild guess - I am not familiar with Xcode and gcc.

    Here is a summary of my questions:

    1. Is there a way to properly organize a pile of code previously compiled and made by gcc make so that they can be built into an Xcode bundle?
    2. Is it meaningful to put a .a library in an Xcode project and build it into a bundle? If it is meaningful, how do I call functions defined in .a after it is built into a bundle?
    3. Is it proper to just replace all main() entries with something else?

    解决方案

    Alright I think I have figured out at least one solution to the problem.

    The duplicate main error was caused by a bunch of main entries in my source code. When the code was compiled by gcc make, I guess the author defined a sort of compilation order so that duplicate mains won't be an issue. (If you know how to do this, please let me know. I barely know make tools.) But when I just add the entire source code folder into my Xcode project, of course Xcode would complain during linking...

    As I was unwilling to modify the source code (because the source code library is not developed by me), I decided to use another strategy to walk around this problem.

    If your duplicate main error was reported from your own code, you can stop reading here. But if you are like me, with a bunch of gcc compiled source code and badly need a bundle yet don't know what to do, I may be able to help.

    Okay here is what I did:

    1. I set up an empty workspace.

    2. I built a C/C++ static library project.

    3. Import my entire source code folder into the static library project.

    4. Set some header search path for the static library project.

    5. Build the static library project. (Now I have a .a library which I could link against)

    6. I set up another project, with a bundle target.

    7. At the bundle project -> Build Phases -> Link Binary with Libraries, add the .a library that I just built.

    8. At the bundle project -> edit scheme -> Build, add the static library project to the scheme and move it up the list so that it is built prior to my bundle project.

    9. Then add .h files of my library project to my bundle project as references.

    10. After that, add a .c file in my bundle project that basically functions as a wrapper. I picked a function that I want to call in Unity, wrote a wrapper function in the new .c file, and was able to build the bundle.

    11. After several trial and error, I was able to import the bundle into Unity and was able to call the test function from Unity.

    I was really excited about this! Though it's not completed yet I think this gives me hope and I am confident I can use the source code now! And the best thing about this solution is that I don't have to modify the library code developed by others. Whenever they update their code, I just update my .a library and that's it!

    Though I have listed 11 steps I still feel that there are lots of details that I missed. So here are my references:

    1. I followed this tutorial to build my source code into a static library: http://www.ccnx.org/?post_type=incsub_wiki&p=1315

    2. I followed this blog to link static library against my bundle code and twist build phases and search headers: http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/

    3. I followed this doc to import my bundle to Unity3D Pro as a plugin: http://unity3d.com/support/documentation/Manual/Plugins.html

    I strongly recommend the second reference because that's what solved my problem!

    Though the problem is almost solved there are still a few things that I haven't figured out:

    1. I don't know if a wrapper function is at all necessary. I will try this out tomorrow and come back to update.

    -- I am coming back to update: the wrapper function is NOT necessary. Just make sure you have all the headers in your bundle project and you will be able to use all the data structures and call functions defined in your headers.

    1. I haven't used NSBundle class though I read a few docs about it. Previously I was thinking about using that class to access my .a library encapsulated in my bundle, but as I found the solution I wrote above, I didn't try the class out.

    Lastly, if you have better solution, please don't hesitate to let me know!

    这篇关于如何组织以前由GCC编译的C源文件将其构建为Xcode包?我有一个重复的符号_主要错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆