Linking a Borland C Builder Package against a library - c++builder

I am currently performing maintenance on all kinds of obsolete applications created with Borland C Builder 6. A lot of these applications use a Package to interface to windows drivers. I can update the code of the .bpk easily by just minor changes to the source and linking in a .a or lib provided by a third party but it seems that the Package only supports code or .bpi libraries. Any ideas how to link in the libraries into the package?

You can add this lines in a .cpp file in your package project.
#ifdef __MACH__
#pragma comment(lib, "mylib.a")
#endif
#ifdef __WIN32__
#pragma comment(lib, "mylib.lib")
#endif

Linking in a Library can be done by selecting Project/Add to Project and adding the library than needs to be linked to the project.

Related

Linking C files with a pre-built static library and compile the Swift project in Xcode

I am new to iOS development. I have ample experience with Android Development.
In Android, I have a bunch of pre-built C static libraries. I also have C source code for another component. I build with the help of Android.mk in Android. As a part of the make file, I build a shared library(.so) by linking the static libraries and in turn use with JNI.
The following is a sample code in Android.mk
include $(CLEAR_VARS)
LOCAL_MODULE:= module_name
LOCAL_C_INCLUDES := $(LOCAL_PATH)/filepath/include
LOCAL_SRC_FILES:= $(LOCAL_PATH)/filePath/filename1.c
LOCAL_SRC_FILES:= $(LOCAL_PATH)/filePath/filename2.c
LOCAL_LDLIBS:= -lm
LOCAL_STATIC_LIBRARIES:= static_lib1 static_lib2 ssl crypto
include $(BUILD_SHARED_LIBRARY)
I am porting the same project to iOS. SO, I am trying to use the same C source code and prebuilt C static libraries.
I have placed the files in Linked libraries in Build Phases but not use. I have read about module map, swift package manager, bridging header but not very clear.
Can anyone kindly help me with step by step process of this linking with the swift code?
Thank you

XCode - Adding a external static library in Cocoapods project

I am experimenting with the Cocoapods to understand what settings/configurations it does so everything works so smoothly. While doing that one specific case troubling me.
Basically there is a different behaviour between non cocoapods projects that uses external libs and cocoapods projects that uses external libs.
Both projects and external library can be found on GitHub.
1) External library libImageFilters.a uses CoreMotion framework. So finally when this library will be included in any app, that app will either include CoreMotion framework or use clang modules so that just by doing #import CoreMotion; framework is added. I prefer the second approach and for this in the header file (ImageFilters.h) added below lines
#if __has_feature(modules)
#import CoreMotion;
#endif
2) AppWithoutPods application just add this external lib and header file. Do the below settings
Enable Modules = YES
Link Frameworks Automatically = YES
Build the application and everything build fine as CoreMotion Framework is included through header file.
3) AppWithPods application uses AFNetworking as a pod. So install the pods and open workspace. When built with above clang module settings,everything builds fine. Now if I add external lib and header file. Build fails with linker error saying CMMotionManager is referenced from libImageFilters. When CoreMotion is explicitly included it builds fine.
This is where the confusion is. Modules are enabled and frameworks are linked automatically. Basically there is nothing different in both apps except cocoapods.
I checked all the settings for both projects, nothing is different then why build fails? Can someone help me understand this?

#import vs #import - iOS 7

I am playing around with some of the new iOS 7 features and working with some of the Image Effects as discussed in the WWDC video "Implementing Engaging UI on iOS". For producing a blur effect within the source code for the session, UIImage was extended via a category which imports UIKit like so:
#import UIKit;
I think I saw something about this in another session video but I'm having trouble finding it. I'm looking for any background information on when to use this. Can it only be used with Apple frameworks? Are the benefits of using this compiler directive enough that I should go back and update old code?
It's a new feature called Modules or "semantic import". There's more info in the WWDC 2013 videos for Session 205 and 404. It's kind of a better implementation of the pre-compiled headers. You can use modules with any of the system frameworks in iOS 7 and Mavericks. Modules are a packaging together of the framework executable and its headers and are touted as being safer and more efficient than #import.
One of the big advantages of using #import is that you don't need to add the framework in the project settings, it's done automatically. That means that you can skip the step where you click the plus button and search for the framework (golden toolbox), then move it to the "Frameworks" group. It will save many developers from the cryptic "Linker error" messages.
You don't actually need to use the #import keyword. If you opt-in to using modules, all #import and #include directives are mapped to use #import automatically. That means that you don't have to change your source code (or the source code of libraries that you download from elsewhere). Supposedly using modules improves the build performance too, especially if you haven't been using PCHs well or if your project has many small source files.
Modules are pre-built for most Apple frameworks (UIKit, MapKit, GameKit, etc). You can use them with frameworks you create yourself: they are created automatically if you create a Swift framework in Xcode, and you can manually create a ".modulemap" file yourself for any Apple or 3rd-party library.
You can use code-completion to see the list of available frameworks:
Modules are enabled by default in new projects in Xcode 5. To enable them in an older project, go into your project build settings, search for "Modules" and set "Enable Modules" to "YES". The "Link Frameworks" should be "YES" too:
You have to be using Xcode 5 and the iOS 7 or Mavericks SDK, but you can still release for older OSs (say iOS 4.3 or whatever). Modules don't change how your code is built or any of the source code.
From the WWDC slides:
Imports complete semantic description of a framework
Doesn't need to parse the headers
Better way to import a framework’s interface
Loads binary representation
More flexible than precompiled headers
Immune to effects of local macro definitions (e.g. #define readonly 0x01)
Enabled for new projects by default
To explicitly use modules:
Replace #import <Cocoa/Cocoa.h> with #import Cocoa;
You can also import just one header with this notation:
#import iAd.ADBannerView;
The submodules autocomplete for you in Xcode.
Nice answer you can find in book Learning Cocoa with Objective-C (ISBN: 978-1-491-90139-7)
Modules are a new means of including and linking files and libraries into your projects. To understand how modules work and what benefits they have, it is important to look back into the history of Objective-C and the #import statement
Whenever you want to include a file for use, you will generally have some code that looks like this:
#import "someFile.h"
Or in the case of frameworks:
#import <SomeLibrary/SomeFile.h>
Because Objective-C is a superset of the C programming language, the #import state‐ ment is a minor refinement upon C’s #include statement. The #include statement is very simple; it copies everything it finds in the included file into your code during compilation. This can sometimes cause significant problems. For example, imagine you have two header files: SomeFileA.h and SomeFileB.h; SomeFileA.h includes SomeFileB.h, and SomeFileB.h includes SomeFileA.h. This creates a loop, and can confuse the coimpiler. To deal with this, C programmers have to write guards against this type of event from occurring.
When using #import, you don’t need to worry about this issue or write header guards to avoid it. However, #import is still just a glorified copy-and-paste action, causing slow compilation time among a host of other smaller but still very dangerous issues (such as an included file overriding something you have declared elsewhere in your own code.)
Modules are an attempt to get around this. They are no longer a copy-and-paste into source code, but a serialised representation of the included files that can be imported into your source code only when and where they’re needed. By using modules, code will generally compile faster, and be safer than using either #include or #import.
Returning to the previous example of importing a framework:
#import <SomeLibrary/SomeFile.h>
To import this library as a module, the code would be changed to:
#import SomeLibrary;
This has the added bonus of Xcode linking the SomeLibrary framework into the project automatically. Modules also allow you to only include the components you really need into your project. For example, if you want to use the AwesomeObject component in the AwesomeLibrary framework, normally you would have to import everything just to use the one piece. However, using modules, you can just import the specific object you want to use:
#import AwesomeLibrary.AwesomeObject;
For all new projects made in Xcode 5, modules are enabled by default. If you want to use modules in older projects (and you really should) they will have to be enabled in the project’s build settings. Once you do that, you can use both #import and #import statements in your code together without any concern.
#import Module(ObjC) or Semantic import
instead of usual module using
//as example
#include <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
History:
[#include -> #import] -> [Precompiled Headers .pch] -> #import Module(ObjC); -> [import Module(Swift)]
It is a part of LLVM Modules
#import <module_name>; declaration says to compiler to load(instead of compile) a precompiled binary of module which decrease a building time. Previously compiler compiled dependency every time when runt into it but now it should be compiled beforehand and just loaded
//previously
run into dependency -> compile dependency
run into dependency -> compile dependency
//#import
compile dependency
run into dependency -> load compiled binary
run into dependency -> load compiled binary
[Modulemap] - bridge between module and headers
Xcode
Enable Modules(C and Objective-C)(CLANG_ENABLE_MODULES) - CLANG #include, #import directives are automatically converted to #import that brings all advantages. Modulemap allows to do it seamless because contains a map between headers and sub/modules
Pass -fmodules
#include, #import -> #import
Link Frameworks Automatically(CLANG_MODULES_AUTOLINK) - enables system modules auto linking. Requires activated CLANG_ENABLE_MODULES. Auto-linking allows to pass -framework <framework_name> based on #import, #import(Objective-C), import(Swift)
If NO - passes -fno-autolink flag
CLANG_ENABLE_MODULES == NO and CLANG_MODULES_AUTOLINK == NO
If you want to handle system(#import <UIKit/UIKit.h>) linking manually(instead of auto-linking) you have two variants:
Add dependency into General -> Frameworks and Libraries or Frameworks, Libraries, and Embedded Content
Build Settings -> Other Linker Flags(OTHER_LDFLAGS) -> -framework <module_name>
Next error will be thrown if:
Undefined symbol: _OBJC_CLASS_$_UIView
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_UIView", referenced from:
objc-class-ref in ClassB.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1
CLANG_ENABLE_MODULES is disabled
CLANG_MODULES_AUTOLINK is disabled and no manual linking
Reverse engineering
otool -l <binary>
//-l print the load commands
//find LC_LINKER_OPTION
//cmd LC_LINKER_OPTION
It currently only works for the built in system frameworks. If you use #import like apple still do importing the UIKit framework in the app delegate it is replaced (if modules is on and its recognised as a system framework) and the compiler will remap it to be a module import and not an import of the header files anyway.
So leaving the #import will be just the same as its converted to a module import where possible anyway
It seems that since XCode 7.x a lot of warnings are coming out when enabling clang module with CLANG_ENABLE_MODULES
Take a look at Lots of warnings when building with Xcode 7 with 3rd party libraries
There is a few benefits of using modules. You can use it only with Apple's framework unless module map is created. #import is a bit similar to pre-compiling headers files when added to .pch file which is a way to tune app the compilation process. Additionally you do not have to add libraries in the old way, using #import is much faster and efficient in fact. If you still look for a nice reference I will highly recommend you reading this article.

How to use ARC compatible files in non ARC compatible projects

My project has dependent libraries that don't compile under the LLVM compiler, so my project is not compatible with ARC.
How can I include other third party libraries and source files that are ARC compatible in to my non-ARC project.
Thanks in advance.
You could add a complier flag to each compile source in the Build Phases. The flag you should add is -fobjc-arc
If you're not using LLVM your main project won't be able to use ARC at as it's a LLVM 3.0 feature.
If I was you I'd make your main project/target/app compile under LLVM and include your older external dependencies as static library dependencies. Once the static libraries are compiled the fact that they're ARC or non-ARC doesn't make a difference.
You'll need to move to Xcode workspaces that contain multiple Xcode projects, one for each of your third party libraries and have static library targets for each project. This setup allows independent build settings and greater flexibility. You'll find a lot of people create static libraries for third party things these days.
Checkout a blog post or two on setting up static libraries within an Xcode workspace, it's quite common these days.

GData static library: exclude files from ARC with -fno-objc-arc?

I am using the GData static library in my app that uses ARC. Google's instructions say to link the header files from the library to the project target.
The problem is that when I do so I get compiler errors as the GData library is not compatible with ARC.
Google states that:
ARC Compatibility
When the library source files are compiled directly into a project that uses ARC, then ARC must be disabled specifically for the library sources.
To disable ARC for source files in Xcode 4, select the project and the target in Xcode. Under the target "Build Phases" tab, expand the Compile Sources build phase, select the library source files, then press Enter to open an edit field, and type -fno-objc-arc as the compiler flag for those files.
(reference)
But since I have only the header files I can not use this flag in the app target.
Well I asked and found the unswear 10 minutes later. Any way if it will help someone:
The problem is only with the .h files, Goole remark is only for cases you embed the library not as static library.
After someone reported the problem to google, they added new macros that solve the problem, this is how:
search the header files for file named : GDataDefines.h
and add this code inside:
//
// Simple macros to allow building headers for non-ARC files
// into ARC apps
//
#ifndef GDATA_REQUIRES_ARC
#if defined(__clang__)
#if __has_feature(objc_arc)
#define GDATA_REQUIRES_ARC 1
#endif
#endif
#endif
#if GDATA_REQUIRES_ARC
#define GDATA_UNSAFE_UNRETAINED __unsafe_unretained
#else
#define GDATA_UNSAFE_UNRETAINED
#endif
Then in the GDataObject.h which causes the ARC errors
Change the GDataDescriptionRecord struct to
typedef struct GDataDescriptionRecord {
NSString GDATA_UNSAFE_UNRETAINED *label;
NSString GDATA_UNSAFE_UNRETAINED *keyPath;
GDataDescRecTypes reportType;
} GDataDescriptionRecord;
And the
__weak GDataObject *parent_; // parent in tree of GData objects
to
GDataObject GDATA_UNSAFE_UNRETAINED *parent_;
This is the link to google update:
http://code.google.com/p/gdata-objectivec-client/source/detail?r=712
That's it.
Hope it will help someone
Shani

Resources