In my project I use different flags to run different code when dealing with multiple targets. Something like
#ifdef MY_FLAG
//do this
#else
//do this other
#endif
Now I'm on my way to take some code to an external library, but I don't want to compile different versions of the library for each flag, so the question is:
Is there a way to pass something like arguments that tells the library (or framework) from outside which code should run in a "global" manner?
What you're doing with #ifdef is establishing which code the compiler can see. So you're going to have to compile different versions for each flag, as libraries are linked against but are already compiled. I guess the question is more what you do with those on disk.
You can store multiple CPU architectures into a single static library. So any of those flags that are merely to do with whether you're targeting ARMv7, ARMv7s or i386 can be handled with a single library.
For the others you're probably going to have to produce different libraries. However that'll just be a matter of the shape of the disk footprint — you can use the project settings of any project you link against your libraries so that it links to a different version of the library depending on the build configuration.
One option is to have the framework provide some sort of initialization method or function that the user of the framework can call. This would tell the framework what "mode" it should run in. The client of the framework could call this at app startup.
Related
I'm trying to clean up a fortran make process for distribution. Currently, two libraries are made, and then the executable is compiled linking to the libraries and including the module files. I see from previous answers (Distribute compiled fortran library with module files) that you can't get rid of the module files and that they can be different for every machine and compiler. This is very annoying.
However, the code in my libraries are made up entirely of modules. It seems like I don't need the library part at all; I can just include the modules. I've tried this and it does compile and run on small examples.
Will this always work (when all I have are modules in the libraries)? Is it best practice? Should I instead consider rewriting my libraries NOT to use modules so I can avoid all these compiler dependencies and only distribute the lib*.a files? Is that what this document is referring to by using submodules (which no one supports static lib with many modules)
It really depends on the features you have in your library. Does it have only a couple of declarations? Then the .mod files would suffice, but why not distribute the source in such a simple case?
Are all your public procedures simple enough, so that they do not require an explicit interface and they are outside of modules? Then you don't need any .mod files.
Do you have a simple public module or an include file with the public API and the rest is private? You can then distribute the source of the API module or the include file. I would recommend to place just the interface blocks and other declarations in this module.
Be aware of one important problem. You can get away (using interface locks or similar) with avoiding the non-portable .mod files, but if the procedures are using some more advanced argument passing, their ABI is often NOT portable between different compilers or even some compiler versions. You would the be able to compile it and get mysterious crashes when calling your library.
Submodules can change it all, but actually I do not expect they will solve portability between compilers. The user of your library will still need the same compiler you had. It is true that interfacing the closed source software will be easier, but not more portable between compilers.
You can link either from a library lib*.a, or from object files. Both will be at least platform dependent and so more difficult to distribute than source code. library file might have the advantage of fewer files. In either case, linking from lib*a or object files, you can present your code to the user as a library of procedures to call. If you don't want to distribute your source code, then you will have to compile for however many platforms you support. Modules are a major advantage of modern Fortran, automating the checking of procedure actual and dummy arguments. Compared to, for example, C header files, they have the advantage of being automatic, but the disadvantage of producing a compiler-dependent intermediate file. If you are providing procedures to other programmers, it would seem a bad idea not to provide them with this interface checking. If you want to hide your source code, then you could write interface blocks describing the procedures and distribute only this source for them to compile.
Does anyone know where I can find a Firebreath sample (either Mac OS X or Windows) that illustrates how to create a plugin that includes 1 or more other libraries (.DLLs or .SOs) that each rely on other sub-projects built as static libraries (LIBs)?
For example, let's say that the Firebreath plugin is called PluginA, and that PluginA calls methods from DLL_B and DLL_C. DLL_B and DLL_C are C++ projects. DLL_B calls methods from another project called LIB_D, and DLL_C calls methods from a project called DLL_E.
Therefore, the final package should contain the following files:
PluginA.dll
DLL_B.dll (which also incorporates LIB_D)
DLL_C.dll
DLL_E.dll
I am currently forced to dump all source files in the pluginA solution, but this is just a bottleneck (for example I cannot call libraries written in other languages, such as Objective-C on Mac OS X).
I tried following the samples on Firebreath, but couldn't get them to work, and I found no samples from other users that claimed they were able to get it to work. I tried using CMAKE, and also running the solutions directly from X-Code, but the end result was the same (received linking errors, after deployment DLL_C couldn't find DLL_E etc.)
Any help would be appreciated - thank you,
Mihnea
You're way overthinking this.
On windows:
DLLs don't depend on a static library because if they did it would have been compiled in when they were built.
DLLs that depend on another DLL generally just need that other DLL to be present in the same location or otherwise in the DLL search path.
Those two things taken into consideration, all you need to do is locate the .lib file that either is the static library or goes with the .dll and add a target_link_library call for each one. There is a page on firebreath.org that explains how to do this.
On linux it's about the same but using the normal rules for finding .so files.
I've got a Cocoa framework that I want to distribute. For people who don't want to pull it in as a submodule and build it themselves, I'd like to provide a pre-built version: ECLogging.framework.
The wrinkle is that the framework has Debug/Release variants that have different behaviour (not just different compiler options, but potentially actually executing different code).
What's the most idiomatic way to distribute this, and for people to set up their Xcode projects?
I want people to be able to do #import , so I can't rename the debug version of the framework as ECLoggingDebug.framework (for example).
So I can give them the frameworks in a folder like this:
ECLogging/
Debug/
ECLogging.framework
Release/
ECLogging.framework
It's easy enough for people to then set up a framework search path ECLogging/$(CONFIGURATION)/, which will pick up the correct one.
This works fine during compiling and linking, but you also need to embed the right version into the built app.
In a Copy Files phase (the normal way to do the embedding), Xcode wants to know where it really is, and I don't think I can somehow use environment variables to tell it.
I can write a script instead, of course, which just copies it. I'm fine with that, but it seems clumsy to have to ask users of the framework to do this.
Is there a better way?
Assuming I'm understanding the scenario correctly, here's what I'd do. I'd make only one version of the framework. Instead of making the behavior of the framework depend on compile-time debug/release configurations (presumably using #ifdefs, etc.), I'd use a (Framework) global variable to indicate debug vs release mode. I'd add a simple method to turn debug mode on (e.g. [ECLogging setDebugModeEnabled:YES]) that users can call upon launch to change the framework's behavior. Then, it's as easy for them as:
#if DEBUG
[ECLogging setDebugModeEnabled:YES];
#endif
I have created a static library containing all my generic classes. Some of these classes use frameworks.
Now I have two projects, one that uses some classes that use frameworks, and one that doesn't use any of the classes that use frameworks.
Because Static Libraries don't support including frameworks (if I am correct). I have to include the frameworks in the project that uses them. But when I compile the project that doesn't use any of the framework-classes the compiler breaks because it still requires the frameworks. Now I know it tries to compile all the (unused) classes from the library because I use the Linker Flag '-ObjC' to prevent 'unrecognized selector' errors.
Does anyone know how to compile only the required source files per project? And prevent from all frameworks having to be included in all projects that use my static library?
First of all, you are right in that a static library cannot include any framework nor other static libraries, it is just the collection of all object files (*.obj) that make up that specific static library.
Does anyone know how to compile only the required source files per project?
The linker will by default only link in object files from the static library that contain symbols referenced by the application. So, if you have two files a.m and b.m in your static library and you only use symbols from a.m in your main program, then b.o (the object file generated from b.c) will not appear in your final executable. As a sub-case, if b.m uses a function/class c which is only declared (not implemented), then you will not get any linker errors. As soon as you include some symbols from b.m in your program, b.o will also be linked and you will get linker errors due to the missing implementation of c.
If you want this kind of selection to happen at symbol rather than at object level granularity, enable dead code stripping in Xcode. This corresponds to the gcc option -Wl,-dead_strip (= linker option -dead_strip in the Build settings Info pane for your project). This would ensure further optimization.
In your case, though, as you correctly say, it is the use of the "-ObjC" linker flag that defeats this mechanism. So this actually depends on you. If you remove the -Objc flag, you get the behavior you like for free, while losing the stricter check on selectors.
And prevent from all frameworks having to be included in all projects that use my static library?
Xcode/GCC support an linking option which is called "weak linking", which allows to lazily load a framework or static library, i.e., only when one of its symbols is actually used.
"weak linking" can be enabled either through a linker flag (see Apple doc above), or through Xcode UI (Target -> Info -> General -> Linked Libraries).
Anyhow, the framework or library must be available in all cases at compile/link time: the "weak" option only affects the moment when the framework is first loaded at runtime. Thus, I don't think this is useful for you, since you would need anyway to include the framework in all of your projects, which is what you do not want.
As a side note, weak_linking is an option that mostly make sense when using features only available on newer SDK version (say, 4.3.2) while also supporting deployment on older SDK versions (say, 3.1.3). In this case, you rely on the fact that the newer SDK frameworks will be actually available on the newer deployment devices, and you conditionally compile in the features requiring it, so that on older devices they will not be required (and will not produce thus the attempt at loading the newer version of the framework and the crash).
To make things worse, GCC does not support a feature known as "auto-linking" with Microsoft compilers, which allow to specify which library to link by means of a #pragma comment in your source file. This could offer a workaround, but is not there.
So, I am really sorry to have to say that you should use a different approach that could equally satisfy your needs:
remove the -ObjC flag;
split your static library in two or more parts according to their dependencies from external frameworks;
resort to including the source files directly.
Abour second part of your question, you can mark a linked framework as Optional :
About first part, it is not clear to me what you intend to do:
A library being declared in a project
A project declaring which files are compiled (via Target > Build phases > Compile sources)
Unless setting complex build rules to include or not files, which if I remember well can be done using .xcconfig files, I don't see any other solutions than splitting your Library. Which I would recommend, for its ease. You should even do several targets in the same project... You could also just use precompiler MACROS (#ifdef...) but that depends on what you want to do.
It sounds like you have library bloat. To keep things small I think you need to refactor your library into separate libraries with minimal dependencies. You could try turning on "Dead Code Stripping" in the "Linker Flags" section of the build target info (Xcode 3.x) to see if that does what you want (doesn't require frameworks used by classes that are dead-stripped.)
When you link against a framework on iOS I don't think that really adds any bloat since the framework is on the device and not in your application. But your library is still a bit bloated by having entire classes that never get used but are not stripped out of the library.
A static library is built before your app is compiled, and then the whole thing is linked into your app. There's no way to include some parts of the library but not others -- you get the whole enchilada.
Since you have the source code for the library, why not just add the code directly to each application? That way you can control exactly what goes into each app. You can still keep your generic classes together in the same location, and use the same code in both apps, but you avoid the hassle of using a library.
I know very little about DLL's and LIB's other than that they contain vital code required for a program to run properly - libraries. But why do compilers generate them at all? Wouldn't it be easier to just include all the code in a single executable? And what's the difference between DLL's and LIB's?
There are static libraries (LIB) and dynamic libraries (DLL) - but note that .LIB files can be either static libraries (containing object files) or import libraries (containing symbols to allow the linker to link to a DLL).
Libraries are used because you may have code that you want to use in many programs. For example if you write a function that counts the number of characters in a string, that function will be useful in lots of programs. Once you get that function working correctly you don't want to have to recompile the code every time you use it, so you put the executable code for that function in a library, and the linker can extract and insert the compiled code into your program. Static libraries are sometimes called 'archives' for this reason.
Dynamic libraries take this one step further. It seems wasteful to have multiple copies of the library functions taking up space in each of the programs. Why can't they all share one copy of the function? This is what dynamic libraries are for. Rather than building the library code into your program when it is compiled, it can be run by mapping it into your program as it is loaded into memory. Multiple programs running at the same time that use the same functions can all share one copy, saving memory. In fact, you can load dynamic libraries only as needed, depending on the path through your code. No point in having the printer routines taking up memory if you aren't doing any printing. On the other hand, this means you have to have a copy of the dynamic library installed on every machine your program runs on. This creates its own set of problems.
As an example, almost every program written in 'C' will need functions from a library called the 'C runtime library, though few programs will need all of the functions. The C runtime comes in both static and dynamic versions, so you can determine which version your program uses depending on particular needs.
Another aspect is security (obfuscation). Once a piece of code is extracted from the main application and put in a "separated" Dynamic-Link Library, it is easier to attack, analyse (reverse-engineer) the code, since it has been isolated. When the same piece of code is kept in a LIB Library, it is part of the compiled (linked) target application, and this thus harder to isolate (differentiate) that piece of code from the rest of the target binaries.
One important reason for creating a DLL/LIB rather than just compiling the code into an executable is reuse and relocation. The average Java or .NET application (for example) will most likely use several 3rd party (or framework) libraries. It is much easier and faster to just compile against a pre-built library, rather than having to compile all of the 3rd party code into your application. Compiling your code into libraries also encourages good design practices, e.g. designing your classes to be used in different types of applications.
A DLL is a library of functions that are shared among other executable programs. Just look in your windows/system32 directory and you will find dozens of them. When your program creates a DLL it also normally creates a lib file so that the application *.exe program can resolve symbols that are declared in the DLL.
A .lib is a library of functions that are statically linked to a program -- they are NOT shared by other programs. Each program that links with a *.lib file has all the code in that file. If you have two programs A.exe and B.exe that link with C.lib then each A and B will both contain the code in C.lib.
How you create DLLs and libs depend on the compiler you use. Each compiler does it differently.
One other difference lies in the performance.
As the DLL is loaded at runtime by the .exe(s), the .exe(s) and the DLL work with shared memory concept and hence the performance is low relatively to static linking.
On the other hand, a .lib is code that is linked statically at compile time into every process that requests. Hence the .exe(s) will have single memory, thus increasing the performance of the process.