iPhone - Static libraries, purpose of "Copy Headers"? - iphone

I am creating a library and even though it is working perfectly fine by packaging all my code and putting all the header files in a folder and then zipping the folder and the static library, I just can't figure out the purpose of the "Copy Headers" section under Build Phases.
I have read all this links:
Using open source static libraries
Creating static libraries for iOS
How to create universal static libraries
Stackoverflow: copy headers: public vs private vs project
But I still do not see the point of setting the copy headers, I realize you can set the private and public path under build settings > packaging, and that the header files will go to that folder after build. But what is the point in this?, is this any different than not setting a single copy header file, and simply grabbing the .a file grab all my header files and put them in a folder?. Also what is the purpose of setting copy project headers?, since they are not included in the target at all?.

To my knowledge, adding the headers to the "Public" section of the "Copy Headers" phase is exactly the same as copying them in your release folder.
I use it as a convenience as I automate the library packaging process with a run script (thanks to this StackOverflow question which you should read if you want to provide universal libraries).
By doing this, I just need to add my new public headers to the "Public" section of the "Copy Headers" phase to have them automatically deployed in my release folder with this part of the script :
#########
#
# Added: StackOverflow suggestion to also copy "include" files
# (untested, but should work OK)
#
if [ -d "${CURRENTCONFIG_DEVICE_DIR}/usr/local/include" ]
then
mkdir -p "${CREATING_UNIVERSAL_DIR}/headers"
# * needs to be outside the double quotes?
cp "${CURRENTCONFIG_DEVICE_DIR}/usr/local/include/"* "${CREATING_UNIVERSAL_DIR}/headers"
fi
I've also noticed that those headers are copied in the package when archiving (Product -> Archive), so perhaps it's a first step from Apple to provide a clean way to build static libraries.
Hope this helps

Does the Copy Headers phase work now when producing an archive? Apple's documentation suggests that feature doesn't work and they suggested using a Copy Files build phase instead. Has this been fixed in recent releases of Xcode? https://developer.apple.com/library/ios/#technotes/iOSStaticLibraries/Articles/creating.html

Related

How to include custom library files in Unity build

When I run my Unity app in the editor, it is able to read my .dlls and other custom files the .dlls need and it works fine. However, when I make a build, it only includes the .dll files in the Plugins folder of the build and not the other custom files. Is there a way to force Unity to include the other files as well? I have tried putting them both in the Plugins and Resources folder before building and in both cases it only keeps the .dlls.
The custom files are .obf, but I don't think that's relevant
It is extremely relevant. Unity does not support all type of libraries.
Here are the supported library extensions:
For Windows, you can use .dll.
For Linux, .so is supported.
For Android, you can only use .aar, rar and .so.
For iOS, .a is used but you can also use the non compiled code such as ,.m,.mm,.c and .cpp.
There is no support for .obf. If you want to add it to your project so that you can load and execute it then you are out of luck.
If you just want to make Unity include it to your final project build so that you can read it then you can. This doesn't mean you can load and execute it.
First, rename the extension from ".obf" to ".bytes". Place it in the Resources folder and read it as TextAsset with the Resources.Load function. You can the access the data with TextAsset.bytes.
TextAsset dataAsset = (TextAsset)Resources.Load("YourObfName", typeof(TextAsset));
byte[] data = dataAsset.bytes;
Not sure how helpful just reading it is but this is here to show you how to include it to the build and read it but you can't execute it unless there is a C# API to do so and I don't think that any API of such kind exist.

How to get Google Protobuf working in Matlab?

So if one was to want to use Google protocol buffers in Matlab and using a Windows computer what would be the best way to do that since Matlab is not in the list of supported languages?
I haven't seen an answer on this and I thought the solution was a bit obscure so I am going to post a how to for matlab_out using the protoc.exe
A how to for google protocol buffer matlab out, this is using resources from the internet I will also include a zip file containing all this already done.
Unzip protobuf-‘version#’.zip (looks like: protobuf-#.#.#)
Open file protobuf-#.#.# -> src
Choose your favorite editor (Notepad++ is good) and change Makefile.am (do not include quotes)
a. Under “nobase_include_HEADERS =”
and below “$(GZHEADERS)”
add the line “farsounder/protobuf/compiler/matlab/matlab_generator.h \” (Note the back slash)
b. Under “libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la”
add lines
“farsounder/protobuf/compiler/matlab/matlab_generator.cc \”
“farsounder/protobuf/compiler/matlab/matlab_plugin.cc \”
c. Save the file and exit out
While still in the src directory go into ->google ->protobuf->compiler and change main.cc
a. Under “#include <google/protobuf/compiler/java/java_generator.h>”
add the line “#include <farsounder/protobuf/compiler/matlab/matlab_generator.h>”
b. In main function add the lines
“// Proto2 Matlab
farsounder::protobuf::compiler::matlab::MatlabGenerator matlab_generator;
cli.RegisterGenerator("--matlab_out", &matlab_generator,
"Generate Matlab M files.");”
c. Save the file and exit out
Unzip protobuf-matlab
Open file protobuf-matlab ->src and copy the farsounder directory to protobuf-#.#.# -> src directory
Go back to protobuf-#.#.# directory and into -> vsprojects and open protobuf.sln in Visual Studio, I believe any version should work
There should be a popup that wants to convert the solution file to a more updated version, go ahead and do that
If you do not see solutions explorer open it up using ctrl+alt+L
Open a new windows explorer and go into protobuf-#.#.# ->src->farsounder->protobuf->compiler->matlab, now in visual studio using the solutions explorer expand the libprotoc->Header Files, now in windows explorer copy the matlab_generator.h file and paste it into the Header Files directory
Still in Solutions explorer go into the Source Files directory and copy in the matlab_generator.cc
Contract libprotoc and right click on protoc and click on properties
Under Configuration Properties->Linker->General, Edit Enable Incremental Linking to be No
Under Configuration Properties->Linker->Input, Edit Additional Dependencies
a. Add the lines “Release\libprotobuf.lib” and underneath “Release\libprotoc.lib”
b. Click OK on the Additional Dependencies window and OK on the protoc Property Page
Change the build type to Release
Right-click on libprotobuf and select build, once completed right-click on libprotoc and select build
Once completed right-click on protoc and select build, it should provide you with an protoc.exe under protobuf-#.#.# ->vsprojects->Release, this will now allow you to create matlab .m files by using the matlab_out command
Help to find protobuf-#.#.# and the protobuf-matlab:
Follow these links:
https://code.google.com/p/protobuf-matlab/source/browse/
download the zip file
https://github.com/google/protobuf/releases
download the source code
Extra help, for using protoc.exe
Copy and paste the created protoc.exe to where your .proto file is
Run cmd and change the directory to where your protoc.exe and .proto file is
Run this command (lets pretend the name of my .proto file is “afunprotofile”) “protoc –matlab_out=./ -I./ afunprotofile.proto”
The easiest way is to use Java
The FarSounder code was nice, but it is quite old and unmaintained. The easiest way to produce Matlab compatible code is to just use the Java version of Protobuf. This solution should work on any platform that supports Matlab and Java.
The Steps
Create a .proto file
Process the file with the protoc compiler and output Java source
Using IntelliJ or other tool produce a JAR file that includes the dependencies
Add the JAR file to the Matlab classpath. edit('classpath.txt')
Restart Matlab
The protobuf runtime dependencies
I include these in a single JAR file output of the Protobuf and the two runtime libraries.
protobuf-java-3.3.0.jar
protobuf-java-util-3.3.0.jar
A sample
I wrote a simple Java wrapper class to hide the MyProtobuf.Builder return type from Matlab that I added to the JAR file
public class MyProtobufWrapperWrapper {
public static MyProtobuf.Builder newBuilder()
{
return MyProtobuf.newBuilder();
}
}
In Matlab
p = com.cameronpalmer.MyProtobufWrapper.newBuilder();
p.setIdentifier(java.util.UUID.randomUUID().toString());
p.setTimestampMilliseconds(timestamp);
p.setAngleRadians(0);
p.addAllChannelSamples(channel_vector);
planeWaveBuilt = p.build();
byteArray = planeWaveBuilt.toByteArray();
As Cameron Lowell Palmer's answer suggests, the way to go is via Java.
Is I lost a couple of hours today on this problem, I would like to elaborate some more. I started with Cameron's answer but I had to do a couple of more steps. Essentially, I had to do all of the following:
Compile proto message for java, e.g. protoc --java_out=./ your_file.proto
Remember to install protobuf java runtime, e.g. in ubuntu: sudo apt install libprotobuf-java
Locate the protobuf java runtime on your system, e.g.: /usr/share/java/protobuf-3.6.1.jar; its path will be used later on. The name should always follow the pattern protobuf-version.jar or protobuf-java-version.jar, therefore locate protobuf- | grep jar$ should reduce the search space for you.
Add a short java file to the same directory, where your protobuf java files went (./x/y/z/MyProto.java). Use your package path instead of x/y/z. If you did not declare java package explicitly in the proto file, then protoc just used your filename as package name. Either way, you can probably check where the protoc generated files went by yourself. Contents of MyProto.java are listed below. Just replace YourProtoFileName and YourMessageName with your stuff. Note that this step is not optional, as this will not generate a simple helper class. For the life of me, Matlab would not let me use inner classes directly (in java, YourMessageName is the inner class of YourProtoFileName). But with the above helper, it was quite happy to generate them for me. Note that if you have more than one message defined in your proto file, you might need to expose more than one builder in this way. And if you only need to read protobuffers, then you might need to export just YourMessageName and not Builder.
package x.y.z;
import x.y.z.YourProtoFileName; // if you do not know it, do `ls x.y.z/*.java`
public class MyProto {
public static YourProtoFileName.YourMessageName.Builder newBuilder() {
return YourProtoFileName.YourMessageName.newBuilder();
}
}
Check Matlab's version of java; in Matlab write version -java. In my case it was 1.8, while the default java installed on my system (java -version) is 11. I had to manually select java 1.8 for the next step, otherwise the whole thing did not work. Even worse, Matlab only produced a very nondescript error "No class x.y.z.YourProtoFileName." Thanks Matlab! You might need to install proper version first (sudo apt install openjdk-8-jdk) and then use update-java-alternatives or just locate javac for the appropriate java version on your system.
Compile both your java file and the one generated by protoc. Remember to point classpath at the jar file or protobuffer runtime that you found above. And remember to use your javac path. In a single command: /usr/lib/jvm/java-8-openjdk-amd64/bin/javac x.y.z/*.java -cp /usr/share/java/protobuf-3.6.1.jar. This will generate class files in ./x/y/z/.
Optional: pack the class files in a jar for easier distribution: jar cvf ./YourProtoFilename.jar x/y/z/*.class. Note that this command line works for me, since I've put all classes, including MyProto, in the same package. You might need to adapt it to your needs.
Start Matlab.
% make Matlab aware of your new classes
javaaddpath('./')
% tell Matlab where protobuf dependancy lives (use the path from step 3)
javaaddpath('/usr/share/java/protobuf-3.6.1.jar')
% test if the classes were found
methods('x.y.z.YourProtoFilename.YourMessageName')
% if methods are listed then you are good to go
% use the helper form step 4
b = x.y.z.MyProto.newBuilder();
% now you have a builder you can use to build your protobuf message
See Google's protobuf java primer to go on from here, as using java in Matlab is fairly straight forward: just write java statements. As long as they are simple statements :)
The same procedure works on octave too. With a bit different syntax for java inside octave. And octave was less picky about the java version in my case. YMMV
#WPFUser,
We followed below steps to build protoc for matlab.
1) git clone https://github.com/protocolbuffers/protobuf.git to protobuf-main folder
2) git submodule update --init --recursive
3) git clone https://github.com/farsounder/protobuf-matlab.git - protobuf_matlab folder
4) Copied src folder from protobuf_matlab repo to protobuf-main/src
5) Updated cmake/libprotoc.cmake to include matlab_generator.cc and matlab_generator.h files
6) Updated cmake/extract_includes.bat.in to include matlab_generator.h file
7) \src\google\protobuf\compiler\main.cc to include matlab_generator

Extension not found error with control flow extension

I am trying to use https://github.com/qiemem/ControlFlowExtension as an alternative to if-else.
I have it to added to the extensions folder(C:\Program Files (x86)\NetLogo 5.1.0\extensions). The extracted zipped folder from github.
In the NetLogo code I use the following,
extensions[ControlFlowExtension-master]
But it still shows me the following error:
There is no release for the extension yet. The zip file that you downloaded is just the source code and doesn't contain the compiled JAR files that you need to use the extension with NetLogo.
If you want to try it out, you will have to build it yourself. For that, you will need to install sbt. Then, open a command terminal and cd to the folder where you unzipped the file you downloaded from GitHub. This folder should be under the NetLogo extensions folder and be called cf (rename it if it is not the case). Once you are in the cf folder, run:
sbt package
This should build cf.jar and allow you to use the extension by putting
extensions [ cf ]
at the top of the code tab in your NetLogo model.
Be aware, though, that the extension is still very much experimental. There may be bugs. The syntax could still change. This is why Bryan did not put out an official release yet.

AVR for Xcode 4?

Has anyone had success using xcode 4 as an IDE for AVR microcontrollers? Is it possible to have the same amount of integration as the plugin for eclipse?
Yes. I use Xcode 4 as IDE when writing AVR code.
But it only works as a "wrapper" for the avc-gcc command line tools. I have three Xcode targets in the project: build ("make all": compile only), fuse ("make fuse": program fuses) and flash ("make flash": compile and download to AVR). Just select the appropriate target and hit Cmd-B to build.
There is not much integration. I still have to edit the Makefile to set clock frequency, programmer and device model and fuse values. And if I add more .c files I also have to add the corresponding .o file to the Makefile. But at least I can do it from within Xcode.
I have created a minimal project template that will allow you to create a new AVR project in Xcode. Get the file here http://dl.dropbox.com/u/1194636/AVR_Xcode4_template.zip. Extract the archive and put the Atmel AVR® folder into ~/Library/Developer/Xcode/Templates (you might need to create the Templates folder).
Template from second answer (http://dl.dropbox.com/u/1194636/AVR_Xcode4_template.zip) works fine but with some tweaks.. You have to put these in file "makefile" in the template to be able to include multiple files in the project:
OBJECTS = main.o $(OBJ)
SRC = mynewfile.c
OBJDIR = .
OBJ = $(SRC:%.c=$(OBJDIR)/%.o)
LST = $(SRC:%.c=$(OBJDIR)/%.lst)
in SRC section you need to enter all files that are built in the project (for example mynewfile.c).
One more enhancement is to clear all the obj files from the project, after the linking ... Find the section main.hex in makefile and change rm -f line with following
rm -f main.hex $(OBJ) $(LST) main.o
Other then that, everything stays the same. What i couldnt find out is how i can enable code complete for this template. If anyone knows i would appreciate the help.

Include/exclude resources depending on scheme

I have some large resources that I only need for my simulator runs—I'd like to have them automatically excluded from all device builds. Is there any way to do this with Xcode 4 short of custom build scripts that copy the resources?
I went with a Run Script phase with the following:
if [ ${PLATFORM_NAME} != "iphonesimulator" ]; then
echo "device build -- removing resources..."
rm "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/test_a.mp3"
rm "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/test_b.mp3"
# reveal the binary in the Finder
/usr/bin/open --reveal "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
else
echo "simulator build..."
fi
Targets dictate what's included in a product. Duplicate your target and create a scheme for it. Modify that target's membership.
Art's answer works well.
I'm adding this alternative answer because I have certain requirements and I found a solution that addresses those.
In my case, I need some large resources to be only in some test builds, but I don't want them to be included in the project or checked in with project. I also want to avoid Xcode pointlessly copying a large file from one folder to another during the build.
My solution is as follows:
Create a new folder on disk under your Resources/ folder, titled FolderLinkedResources.
Add a folder reference to this folder in the Xcode project.
This is a link to an actual folder on hard disk, rather than a project folder group. You do it via an option in the Add Files dialog:
Then at build time I have a custom build phase script (placed earlier than compilation) that hard-links the required resource file into the referenced folder on disk:
# COPY_SPECIAL_RESOURCES is only defined in schemas where I require the special resource(s).
# SpecialResources folder is a sibling folder alongside my entire Xcode project folder
if [ ${COPY_SPECIAL_RESOURCES} == "1" ]; then
ln ../SpecialResources/mySpecialResourceFile.bin Resources/FolderLinkedResources/
fi
Now the build will include your special resource.
Note that since the resource file is inside a folder reference in the project, the built app will actually contain the resource file in a folder, rather than at the top level. This means that the usual call to retrieve your resource will not work:
NSString *resourcePath = [[NSBundle mainBundle]
pathForResource:#"mySpecialResourceFile"
ofType:#"bin"];
To fix this, you need to also provide the folder name containing the resource:
NSString *resourcePath = [[NSBundle mainBundle]
pathForResource:#"mySpecialResourceFile"
ofType:#"bin"
inDirectory:#"FolderLinkedResources"];
Note: this technique also works well for when you don't actually know what the resources are until build time! As long as your script step hard-links in the files, they will make it into the build.
In the interests of tidyness and sanity, I include a run script build phase that happens after the compilation, which clears out the hard link:
if [ ${COPY_SPECIAL_RESOURCES} == "1" ]; then
rm -rf Resources/FolderLinkedResources/*.*
fi
Finally, in case anyone is interested in my actual use case for this: I have pre-recorded HTTP communications data for certain offline test builds of my app. This data is in no way a part of the core app, so I don't want it checked in with app itself, or part of the project by default.
Custom build scripts is your best friend in Xcode. Have the script delete the resource after the build and before the code sign.