Cannot find output .a of Cocoa Static Library (in xcode 4) - objective-c

I have a project with two targets, one is a Cocoa Static Library, the other is the accompanying test project. Despite building the main project in different ways over and over again, I cannot find the .a file that I expect it to produce.
In fact, I cannot find the build folder associated with the project. I need to link to the library in an app, but cannot do so if I can't find the file to link to.
These properties are correctly set:
(Build Products Path) SYMROOT = build
(Intermediate Build Files Path) OBJROOT = $(SYMROOT)
All tests pass (which means the code MUST be building right?)
Breaking the code causes the build to break - again suggesting that it is building.
Also, the "Products > libproject.a" file is red in the xcode project navigation
I also checked the DerivedData directory, but all the seems to get created is the objects fot the OCunit stuff. Still no .a file against which I can link.
Where is my .a file?
Any help would be much appreciated.

It's probably in ~/Library/Developer/Xcode/DerivedData/ somewhere.

Related

Cannot get CMake to handle Fortran-90 modules properly

I've had a miserable afternoon trying to add a Fortran-90 module to a large multilanguage library set (mostly C++) built with CMake, and am at the point where I am clearly going in circles. There is an amazing dearth of information online that might help me with this, and the CMake documentation is as inscrutable as always.
The library set is too large to boil down properly (so I've been unable to get a good small reproducer) but the essence of is this. Each library lives in its own directory, with a test directory beneath it. I've added an F90 file containing a module to one of the directories, which I'll call low_library. The contents of this directory are something like:
low_library:
CMakeList.txt
file1.cc
file1.hh
file2.cc
file2.hh
my_module.f90
test:
CMakeList.txt
test1.cc
test2.cc
test3.cc
my_module_test.f90
except many more .cc and .hh files. In the CMakeList.txt file for the library directory, I have instructions that include
add_library(low_library STATIC "")
target_sources(low_library
PUBLIC:
file1.hh
file2.hh
PRIVATE:
file1.cc
file2.cc
)
There's more but it's not obviously relevant.
So the first question is where to put my_module.f90. I want my_module.f90.o to be included in the liblow_library.a file but I need the my_module.mod file to be visible to other libraries I'm building (and to users of the library set). So I add the line
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/fortran_modules)
towards the top of my CMakeList.txt file, add my_module.f90 to the PRIVATE part of the target_sources() PUBLIC list, and ... sigh ... the build system puts the .mod file in the build directory, and not in ${CMAKE_INSTALL_PREFIX}/fortran_modules. The other libraries can't see it and fail to build.
So now I put my_module.f90 in the PUBLIC part of target_sources() and try again. This time the module files goes where I expected it, my test directory can see it and builds successfully, and I'm happy until I move on to building the next library, in directory high_library which depends on low_library. The build comes up with the truly bizarre error:
f951: Fatal Error: Can't rename module file â/scratch/kgbudge/develop/install/fortran_modules/cta_mesh_generator.mod0â to â/scratch/kgbudge/develop/install/fortran_modules/cta_mesh_generator.modâ: No such file or directory
Looking at the rest of the trace, it appears that with my_module.g90 in the public interface of low_library, the build for high_library ignores what's already in my ${CMAKE_INSTALL_PREFIX}/fortran_modules and builds its own copy of the d-mned .mod file in ${CMAKE_INSTALL_PREFIX}/fortran_modules. Which, since we have high-powered build servers and always build in parallel (make -j16 is typical) means a race condition between competing build jobs.
Okay, I know. I needed to include the line
target_include_directories(low_library PUBLIC ${CMAKE_INSTALL_PREFIX}/fortran_modules)
near start of the CMakeLists.txt file for high_library so it knows where to find the modules and wont' try to build its own. Except this doesn't help.
I can find nothing online that gives me any clues what is going on or how to resolve it.
It looks like the problem is that I had my
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/fortran_modules)
only in the libraries that produced or consumed the new modules. But other libraries used the library containing the module and needed to see a copy of the module even though they weren't actually using the module. I think.
Anyway, moving this line into the root CMakeLists.txt allows me to build the whole library successfully. I still seem some warnings:
f951: Warning: Nonexistent include directory â/srcâ [-Wmissing-include-dirs]
but at least it all builds.

How to let some file to be visiable in QtCreator

I'm using cmake to configure my project. It seems QtCreator only show those files referred by add_executable, add_library and configure_file. Other files in project directory are not visiable in the Projects panel.
Although we can still visit those files by file->open, it make me feel bad that many important source files are not visiable in the Projects panel. So...
How does QtCreator decide whether to show a file?
Is there any cmake command that can make arbitrary file to be visiable in QtCreator?
=======================
Some additional info:
My project is a C++ library with PerlXS interface. XS code is preprocessed into C code by xsubpp, and this action is added into cmake project via add_custom_target. However, the XS file is not added into Porjects panel by QtCreator. Besides, a project can have non-source text files such as README, Changes, etc..
I see no reason to put something specific with project, when you can switch to "File System" browser in QtCreator.
But anyway, the answer still the same. If you wish to see something in project - add it to add_executable, add_library.
For example
set(DATA_FILE ${PROJECT_SOURCE_DIR}/build/README.txt)
...
add_executable(${TARGET_NAME} ${SRC_FILES} ${GLB_HDR_FILES} ${DATA_FILE})
And now we can see README.txt in project
Same trick can be done for other files. Just add them to DATA_FILE variable.

XCode 4.3: Static Library Generation

I've done a some looking around but most of the answers I've found have been or felt incomplete and have left me a little confused. I have been given a C Library that I need to compile into a static library using XCode 4.3 and then use in a separate iOS app project, but I'm unsure about how to proceed. I'm not sure if the directory structure matters or not, but here it is anyways:
Library -> Section1 -> src -> .c files
-> sec1 -> .h files
-> sec1.h
-> Section2 -> src -> .c files
-> sec2 -> .h files
-> sec2.h
I've been trying to work from this: http://blog.stormyprods.com/2008/11/using-static-libraries-with-iphone-sdk.html which was linked in a question similar to this one though being from 2008 its fairly out of date, nor could I get it to work. There is also this question: Including external C library with Xcode but it doesn't go into the details of actually generating the library, before then including in a separate project.
If someone could provide a clear and up-to-date answer I, and many others, would very much appreciate it I'm sure. Let me know if any more information is needed!
To build the static library:
Create a static library project in Xcode
Add all the .c and .h file to the project
Compile
The easiest way to use this library is then to add this static library project to you application project. This avoids having to worry about creating fat libraries (i.e. libraries with code for both the simulator and device).
To add the static library project to your application project:
Choose File > Add Files to ""...
Add the .xcodeproj for your static library
Click on your app's .xcodeproj in the Project Navigator to show build options
Click on your app's target and choose the "Build Phases" tab.
Expand the "Link With Binaries Section"
Click the '+' button
Expand the "Workspace" section (you should see your library, a .a file, there)
Click on your library and you should be good to go.
Apologies for excruciating level of detail above, but somehow people always seem to forget to do steps 4-8 and then they wonder why they are getting link errors!
Xcode will not be able to find the headers for your library. You can either add the public headers to your project as you would any other header file or set the "Header Search Paths" in your build settings.
Try the Universal Framework project, as seen on github: https://github.com/kstenerud/iOS-Universal-Framework/. I have used this extensively, and it works nicely. You just create a new XCode project for that library, put in all the source and header files, and it will build a static Framework. That you can use in other projects, and you also don't have to worry about the header search paths.

Hide code in static library (iOS Obj-C)

I'm working to create an iOS static library that I wish to sell. I've walked through the steps for the initial builds and have generated the .a/.h output.
When I include these files in a separate project, I don't see any way to browse the contents on the .a file.
HOWEVER, when a line of code in my library crashes the app (like I said, it's still in development), the debugger shows the entire class (.m) file to me. What's up with this?
I don't really understand what all goes into static libraries, and I'm not sure I compiled that version for both simulator and device. Could that have something to do with it? If so, could someone explain why?
Thanks!!!
Don't worry, your source code is not included in the archive (.a) file.
Xcode is smart enough to find the source code file on your computer, based on the debugging information embedded in the file. If you build the library using the "Release" configuration (or otherwise modify the build settings so that debugging symbols are stripped) and don't have the source anywhere on the machine, a developer will have to resort to their knowledge of x86 or ARM assembly to figure out how your code works.
By the way:
Since a lot of Objective-C is handled at runtime, a lot of class names and selector names will be visible in your library. That's just how it works. You could try to obfuscate it, but I think your time is better spent writing more useful code to sell.
If you want to give people a static library for iOS development, you'll want to build versions for the iOS Simulator (x86) and the iOS Device (arm) and then use lipo to combine them into a single fat static library. Search around for "lipo xcode fat static library" for different ways to do this. Some solutions are more convoluted than others.
I had the same issue. #benzado is right about what he has mentioned. But I had to strip debugging symbols to solve the issue. To do so, I had to change Build Settings of project library before build as mentioned below.
Select your Target and go to Build Settings. Set
' Strip Debug Symbols During Copy ' to YES
' Debug Information Format ' to 'DWARF with dSYM File'
' Generate Debug Symbols ' to 'NO'
' Symbols Hidden by Default ' to 'YES'
To see what are these for, refer Apple Build Setting Reference
And build the library using the "Release" configuration. This worked for me.
If you have a project for static library with all .m files on your computer then every copy of this library (.a file) will be symbolicated with its .m file while debugging in xCode.
xCode doesn't search for appropriate .m file through all your disk. It knows the place of original project. So if you distribute only library it fully hides your initial code.
To make sure you can copy your library in some new project then clear .m file in library project.
From this moment any attempt to debug methods of library will give empty file on screen.

How to embed app with log4cocoa?

I'm having some trouble to embed my application with the log4cocoa framework.I've embed frameworks in my application before with no trouble, but I cannot fix this one.
First of all, this is my system out:
dyld: Library not loaded: #loader_path/Frameworks/Log4Cocoa.framework/Versions/A/Log4Cocoa
Referenced from: /Users/leandro/Documents/Projects/MLoggerApplication/build/Debug/MLoggerApplication.app/Contents/MacOS/MLoggerApplication
Reason: image not found
Well, I think done all necessary steps to get a framework working fine including the copy files phase and changed the installation directory over the build options to #executable_path/../Frameworks .
I hope problem clear enough to receive your help.
Thanks in advance.
Looks like your framework isn't being copied into your target. If a framework isn't part of the system (ie, you have to distribute it with your app), you need to not only link your executable against the framework but to copy it into your app's ./Frameworks folder.
To do this, add a Copy Files build phase, select "Frameworks" as the build phase's destination, then drag the framework (from your Frameworks folder in your Xcode project) under that Copy Files build phase you just created. If you already have a Copy Files build phase for Frameworks, then just use it instead of creating a new one.
Firstly, i mean, Joshua Nozzi is completely right about how is to embed an app with a framework!
But log4cocoa as a little different and could only realize that because it is an opensource code able for download at http://sourceforge.net/projects/log4cocoa/.
The framework could be used with this configuration by adding a "Copy Files build phase, but instead "Frameworks", select "Products Directory" as the build phase's destination, then drag the framework to that "Copy Files build phase.
The difference among this, and the other frameworks relies in this build variable: installation directory.It has as default value: "/Frameworks .
This variable can be accessed by right clicking on the log4cocoa(first item in the targets list), then select "Get Info" and finally "build".
To use it as "normal" framework rebuild it after you have edited the "installation directory" value to "#executable_path/../Frameworks" or if you are going to embed a framework with it, you would prefer "#loader_path/../Frameworks"