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

这一生的挚爱 提交于 2019-12-01 08:35:00

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!

Payne Chu

I tried to follow the steps in the accepted answer, but had no luck. In the end, I realised step 10 needed to be modified slightly:

  • Create a dummy.c under (.bundle) project and the dummy.c can just be totally empty.
  • Remove the setting for the library you want to link inside Link Binary With Libraries
  • Instead use -Wl,-force_load,$(CONFIGURATION_BUILD_DIR)/libYourLib.a or -all_load to Other Linker Flags

PS: And also can use sub-project instead of workspace. and use Target Dependencies instead of Edit Scheme to achieve the same effect.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!