How can I organize the C source file previously compiled by GCC Make and bundle them into an Xcode package? I have a duplicate _main Error symbol

How do I create a .bundle from source?

This may seem like a simple problem, but it kept me down for a week ...

Here's my problem:

I have a bunch of .c and .h files that are organized into a folder and its subfolders. The source code was written and compiled with gcc make and tested with many other make tools. There are some command line utilities and tools in the source code, and it has more code that serves as a library for these utilities and tools. These are the files that serve as libraries that I want to reuse. (By library I don't mean static library or anything, 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 these functions, too)

However, my problem is more complicated: I need to bundle these .c and .h into a package in order to reuse it. I am not writing my application in C; I am developing in Unity and Unity can only accept .bundle files on Mac OS.

Here is my goal:

Organize your source folder appropriately so that I can build them into a package in Xcode 4.

This is where I got stuck:

I got the following error when building the project:

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

I can relate this error because I can find a lot of basic entries in the source code. Most of them are test utilities.

Here's what I've tried:

  • I tried deleting all these .c files but no luck. The error still exists. I delete and delete until some files can find the definition of the function they are calling. So I had to stop there.

  • Although I was unable to build the package, I was able to create a static C / C ++ library (with a .a extension). After I got the .a file, I tried to put it in another Xcode project and tried to package it. I could build the package this way, but then I have problems accessing the contents of the package. How do I call functions defined in a static library .a if that library is hidden in the bundle? I read about Apple documentation which says:

Note. Some Xcode targets (such as wrapper tools and static libraries) will not create a package or package. This is fine and there is no need to create packages specifically for these types of purposes. The resulting binaries generated for this purpose are intended to be used as is.

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

This is what I was thinking:

  • I was thinking about replacing everything basic with something like main_sth. But the source code was not written by me, so I didn't want to change it. (It just doesn't seem like the right way to do things for me ...)
  • I found out that Xcode has a built-in gcc compiler. So I guess if gcc can do it, then Xcode? This is just a wild guess - I'm not familiar with Xcode and gcc.

Here is a summary of my questions:

  • Is there a way to properly organize a bunch of code previously compiled and done by gcc make so that they can be built into the Xcode package?
  • Does it make sense to put the .a library in an Xcode project and build it bundled? If that makes sense, how do I call the functions defined in .a after it's embedded in the package?
  • Is it correct to just replace all main () entries with something else?
+3


source to share


2 answers


Ok, I think I have solved at least one solution to the problem.

A recurring major error was caused by a bunch of basic entries in my original code. When the code was compiled with gcc make, I assume the author has defined some sort of compilation order so that duplicate networking won't be a problem. (If you know how to do this, please let me know, I don't know what to do with the tools.) But when I just add the entire source code folder to my Xcode project, of course Xcode will complain during linking ...

Since I didn't want to change the source code (because the source code library was not developed by me), I decided to use a different strategy to solve this problem.

If your recurring major error was pointed out from your own code, you can stop reading here. But if you're like me, with a bunch of gcc-compiled source code, and don't really need a bundle but don't know what to do, I can help.

Ok, here's what I did:

  • I have set up a blank workspace.

  • I have built a C / C ++ static library project.

  • Import the entire source code folder into your static library project.

  • Give some header search path for the static library project.

  • Create a static library project. (I now have a .a library that I could link from)

  • I have set up another project with the purpose of linking.

  • In the project bundle -> Build Phases -> Link Binary with Libraries add the .a library I just created.

  • In the project bundle -> edit scheme -> Build, add the static library project to the schema and move it up so it builds before my package project.

  • Then add the .h files of my library project files to my package project as references.

  • After that add the .c file to my package project, which basically works like a wrapper. I selected the function I want to call in Unity, wrote a wrapper function in a new .c file and was able to build the package.

  • After some trial and error, I was able to import the package into Unity and was able to call the test function from within Unity.

I was very excited about this! Although it is not yet complete, I think it 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 need to modify the library code developed by others. Whenever they update their code, I just update my .a library and that!

Although I have listed 11 steps, I still feel like there are a lot of details that I missed. So here are my links:



I highly recommend the second link because it solved my problem!

While the problem is almost resolved, there are a few more things I didn't understand:

  • I don't know if a wrapper function is needed at all. I'll try this tomorrow and come back to update.

- I go back to the update: the wrapper function is NOT needed. Just make sure you have all the headers in your bundle project and you can use all the data structures and call functions defined in your headers.

  • I have not used the NSBundle class, although I read several docs about it. I used to think about using this class to access my .a library encapsulated in my package, but since I found the solution I wrote above, I haven't tried the class.

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

+1


source


I've tried following the steps in the accepted answer, but no luck. Eventually, I figured out that step 10 needed to be changed a little:

  • Create a project dummy.c

    under (.bundle), or dummy.c

    maybe just empty.
  • Remove the setting for the library you want to link internally Link Binary With Libraries

  • Use -Wl,-force_load,$(CONFIGURATION_BUILD_DIR)/libYourLib.a

    or -all_load

    before insteadOther Linker Flags



PS: And it is also possible to use a subproject instead of a workspace. and use Target Dependencies

instead Edit Scheme

to achieve the same effect.

-2


source







All Articles