In my scenario I'll need to release my lib project without source code but a compiled form.
Given,
Some library package in the form of compiled .a files,
a main package in form of source code,
all their platform types where they're built on match,
is it possible to compile the main and link it with .a files up into an executable? How to do it if doable?
Not unless the .a files were generated as a result of "installing" (go get or go install) a package. A ".a" library file is "customized" for the OS, machine architecture, go version etc. of the environment in which it will be used. Users of your library are not likely to meet all of the requirements. For that reason, and perhaps others, ".a" files without source code are not useful.
Related
I'm working on the software that is being built on the RHEL using Makefile's. The build system is producing both .a (static libraries) and .so (dynamic libraries). Those libraries are independent pieces of the huge program.
If I change a source code of the binary and run the build I will rebuild the binary and everything will be good. But if I change the source code inside the .a library (one of the files that produce the library) and try to build, the build system will regenerate the library only. It will not relink the binary the .a file is linking to.
Is there any special flag I can use to force the make command to relink the binary that needs to be re-linked?
TIA!
make is just a tool that executes a makefile. The actual build rules are part of the makefile, and it is up to the makefile author to write correct rules. In your case, it seems that the makefile author neglected to list the static library as a prerequisite (dependency) in the rule that builds the binary. This means that make will not automatically relink the binary if the static library changes.
Depending on the complexity of your build system, this could be quite difficult to fix, or it could just be a matter of adding libfoo.a to the list of dependencies of the main binary.
I'm porting an old C++ project to run on RHEL 6.7 with gcc 4.4.7. The code was originally made to run on an SGI machine.
I have a library .a which is presumed to have been compiled on the old machine (and thus there's no hope of running it in the new one) however, along with this .a file I also have the headers and source files. I am assuming that these are the ones that are used to make the .a file. The Makefile that was used is now long gone, I just have the source code.
My question is, is there a way to "reverse engineer" the library? I would like to know what functions the .a library contains so I can make it on my machine.
I will add that I am new to static and shared libraries so I'm not entirely sure what the .a file contains or how it is any different from including the headers.
Update:
I have looked into the included code and realized that the C files only work to interface with functions defined using Fortran95. I think that now I'm supposed to build the Fortran95 codebase and somehow interface that with the C code. Once I do that I will have a library that should (hopefully) compile in my native system. How can I do this?
I need to include libcurl files inside the built file(vs++ project) so the user doesn't have to download them. I have been looking for an answer for quite some time now without success, please help.
You can build the source code yourself. The source code is here.
You can distribute files like libeay32.dll with your app, in which case libcurl is built with dynamic linking. You can either build them yourself (as said before), or you can download pre-built ones.
If you don't want to distribute files like libeay32.dll and instead have the libcurl code embedded into your .exe or .dll, this is called static linking, and you can build the source code that way as well.
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:
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.
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:
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...)
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:
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?
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?
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:
I set up an empty workspace.
I built a C/C++ static library project.
Import my entire source code folder into the static library project.
Set some header search path for the static library project.
Build the static library project. (Now I have a .a library which I could link against)
I set up another project, with a bundle target.
At the bundle project -> Build Phases -> Link Binary with Libraries, add the .a library that I just built.
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.
Then add .h files of my library project to my bundle project as references.
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.
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:
I followed this tutorial to build my source code into a static library: http://www.ccnx.org/?post_type=incsub_wiki&p=1315
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/
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:
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.
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!
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.
These days, I use Flex & Bison generated some codes to develop a SQL-parser alike tools, these code can't compiled silently(may be this another topic) in VS2005,but GCC/G++ works well, then I compiled these code with mingw in dll(in windows xp), and then linked these function facades in VS2005, but it seems can't link the dll during linking.
Does MS VS2005 recognize the dll which compiled using mingw on windows? Is there anything I need to do additional? For example, adding something in the include-file that declare the exported APIs?
Does any one can give some advices?
The condition is, as in VS2005, if you want to export some APIs, you may show a *.def file to tell nmake which API you want to export, and then you may create a(or some) *.h file to declare somthing about these APIs(adding some stdcall alike prefix as a call protocal) and some data-type definition. But with GCC/G++, you do not need to do such boring things, just use [ar], you can get these APIs, so my *.h file do not add call protocol and no *.def, just like common function declaration. After *.dll generated, add the *.h file and [mv] generated *.dll in VS2005 project directory, then set the linking *.dll in project setting. Does these steps generated my Question?
BTW, I found and tested VC6-compiled dll can be linked with mingw in Windows XP, but the reverse can't work.
Anyway, forgive my poor English, and thanks for your concern.
VS2005 does not recognize any DLL to compile anything, and I doubt mingw does.
When your application shall use a DLL, you need to tell VS2005 what functions are provided by the DLL.
Load Time Binding
The entry points are defined in the EXPORT directory of the DLL. The content of the EXPORT directory can be defined with the DEF file, while compiling the DLL. Theses exports can also defined using the #pragma __declspec(dllexport) directive. When you compile the DLL the linker will also generate a *.LIB file for the consuming application. This LIB is called import library.
The signatures of the exported functions must be provided by function prototypes, usually in a *.h file.
When you compile your application with load time binding, you include the *.h file in your source code and add the import library to the project settings. (not the *.DLL) When the O/S loads your application, the static code in the import library will load the DLL, read the EXPORT directory and fix all stubs to access the exported functions (and other symbols).
Dynamic Binding
You can omit the import library and load the DLL with your code using LoadLibrayy at the time that's appropriate. You need to define the pointers to the DLL entrypoints by yourself and must intialize theses pointers before calling GetProcAddress the actual functions.