what dose "Allow Non-modular Includes In Framework Modules" mean? - objective-c

I saw the meaning of "Allow Non-modular Includes In Framework Modules" in Xcode.
Enabling this setting allows non-modular includes to be used from within framework modules. This is inherently unsafe, as such headers might cause duplicate definitions when used by any client that imports both the framework and the non-modular includes.
but it's so abstract,anyone can give me some more detail and example, and tell me what happened behind this?
another question is that this error only happened in dynamic/static framework structure, not in static library, why?

Related

Module not found for framework dependency in Xcode

I have a project with multiple framework targets, that also have pods dependencies.
I have:
No circular dependencies between targets
Everything, including pods, is in Objective-C, no Swift at all.
use_frameworks! in Podfile, so all pods are frameworks, not libraries.
Here is my structure:
TUSystemKit depends on TUModels (which is a framework).
TUModels depends on Pods_TUModels (generated by pods).
Pods_TUModels depends on JSONModel
TUModels is automatically linked with its own pod framework (which contains JSONModel).
TUSystemKit has TUModels as target dependency.
TUSystemKit is linked with TUModels.
Visually, the dependencies are like this:
TUSystemKit ➔ TUModels ➔ Pods_TUModels ➔ JSONModel
When I select MyModels as the build target in Xcode, build succeeds. However, when I select TUSystemKit, the build fails, saying that module JSONModel is not found while building module TUSystemKit (TUUser in screenshot belongs to TUModels):
What am I doing wrong? Obviously I shouldn't be explicitly linking against all the frameworks in the dependency tree. Why does TUModels build perfectly but TUSystemKit errs on a module import inside a linked framework's code? Do I need to change something with pods?
After hours of refactoring, I've managed to build my project. I can't tell what exactly was wrong as it took me literally a day to organize all the dependencies and frameworks and it kept failing at a different point, more than a 100 times, but here are some observations to lead to a successful build:
All the public-facing classes are added as public headers to the target, and not to any other target.
All the code (.m files) are in Compile Sources section of the target, and not in any other target.
All the public facing classes' headers are included at umbrella header (a header with the exact same name with the framework)
The application embeds all the custom frameworks (not the pods).
All the files inside a framework target only #import required files within the same target or a file listed on any targets umbrella header that the framework has a dependency on.
Obvious, redundant, but worth noting again: no classes between frameworks should have circular dependencies (e.g. ClassA in FrameworkA depends on ClassB in FrameworkB, while some class in FrameworkB depends on some class on FrameworkA). I had some, and created delegates. Do whatever pattern fits your design: IoT/dependency injection, notifications/publisher-subscriber etc. But do it: separate the concerns clearly.
Try to avoid using same classes in multiple targets. Instead, have it in one target, and make the other target depend on the containing target, creating a dependency chain.
After refactoring many files and playing with project settings, I managed to build and run everything again. My previous setup had various number of combinations of the issues that I mentioned above, messing everything up. After cleaning all the bits and grouping code into functional, modular frameworks, I could build it.
If you came here due to the parse error -> module not found,
in certain occasions you may be forced to add the path manually.
This is...
go to your project at the top
select your project target
select build settings
search the parameter Framework Search Paths under the title Search Paths
add the one where yours is located. Example: (using cocoa pods) $(SRCROOT)/Pods
indicate/set it to be recursive (access to the option by double-clicking your previously added path)
The problem should have been resolved by the 3erd party lib with commands like install / update / build or similar but if it fails and you are stuck, this is an option in order to continue.
In the same tone, if you get an error from pods indicating that
The sandbox is not in sync with the Podfile because the builder is unable to find files like Podfile.lock, then you may consider to go in the same direction adding some user-defined settings:
select build settings
press the '+' symbol, "Add User-Defined Setting".
add this pair:
param= PODS_PODFILE_DIR_PATH value = ${SRCROOT}/.
param = PODS_ROOT value = ${SRCROOT}/Pods
Cheers

TFS Build ignores configured Code Analysis ruleset

I have a solution that is using an hybrid .csproj and project.json combination (for nuget management purposes). So basically the "project.json" file is working as a "packages.config" file with a floating version capability.
This solution is using a custom RuleSet that is being distributed via Package, and is imported automatically. On the dev machine, works without a problem.
At the build machine (that is, inside the machine itself, working as an user) the solution also compiles without a problem.
However, when a vNext build (is this the name for the new build system?) is queued, it ignores completely the custom ruleset and just uses the StyleCop one (that is also included), which gives a bunch of warnings. Said warnings should not appear as the Custom RuleSet basically suppresses those warnings (ie: Warning SA1404: Code analysis suppression must have justification,
Warning SA1124: Do not use regions, etc)
As far as I have checked, there is no setting to specify the ruleset, and this works with XAML Builds. What is different in this new build system that is causing this? Is there a way to force/specify the Code Analysis Rule Set from the definition?
Thanks in advance for any help or advice on the matter.
Update/Edit
After debugging back and forth with the wonderful help of jessehouwing I must include the following detail on my initial report (that I ignored as I did not know that it was influential):
I am using SonarQube Analysis on my build definition.
I initially did not mention it as I did not know that it replaces the Code Analysis at Build Time (and not only when it "analyzes", as I thought).
If you are using the SonarQube tasks
The SonarQube tasks generate a new Code Analysis Ruleset file on the fly and will overwrite the one configured for the projects. These rulesets will be used regardless of what you've previously specified.
There is a trick to the naming of the rulesets through which you can include your own overrides.
More information on the structure can be found in the blog post from the SonarQube/Visual Studio team. Basically when you Bind your solution to SonarQube it will generate 2 ruleset files. One which will be overwritten during build, the other containing your customizations.
There is a toolkit/SDK to generate a SonarQube plugin for custom analyzers which allow you to import your rules into SonarQube, so it will know what rules to activate for your project(s).
If you're not using SonarQube
Yes you can specify the ruleset you want to use and force Code Analysis to run. It requires a couple of MsBuild arguments:
/p:RunCodeAnalysis=true /p:CodeAnalysisRuleset="PathToRuleset"
Or you can use my MsBuild helper extension to configure these settings with the help of a UI template:

HTTparty in Rhodes

I am using Rhodes to develop android application.
I have installed HTTpary gem in Rhodes. Now when I am writing the statement "require 'httparty' " at top of the application it gives me error like "No such file to load".
What should I do to solve this problem?
From the documentation, scroll down to the section beginning "Adding Ruby Extension Libraries to Your Rhodes Application". It details 3 ways you can include external libraries into your application, summarized below.
Add ruby extension to an individual application
Add ruby library to an individual application
Add ruby library to the Rhodes framework to be built for all applications
The base Rhodes framework only contains things deemed generic enough to be included - so the built application package size can be kept low. Anything not in the base framework can be included in the application through the aforementioned methods.
This is just a guess since w/ Rhodes environment; but if this were a normal ruby script you would need to have require 'rubygems' first (assuming your used rubygems...).
The Motorola documentation is horrendous; allow me to help if I can. Firstly, examine the constant $LOAD_PATHS from your Ruby code to see the entire list of paths that Rhodes searches. Any .rb file in this path is automatically made available to require.
Then you have to decide whether to add this library to the entire Rhodes framework or just your app; personally I opt for one app at a time, because that way it reduces the chances of incompatibilities, and your apps are still provided all the libraries in rhodes-*version/lib/framework
If you want to add a library to your app, the docs suggest plopping it into the directory app/lib, but keep in mind that only this exact path is searched, so if you don't have a .rb file of the same name as your require statement directly under this path, it won't be detected automatically. I mention this because the common structure is a single file with the library name placed directly in lib, and the actual library contents inside a folder of the same name.
Example: the mime-types library is made up of: lib/mime-types.rb and lib/mime/, which are named differently and can lead to exactly this kind of confusion when including in Ruby.

A framework header cannot find its own header files in Xcode?

In Xcode, suppose that there is a framework named Foo. Inside the Foo.framework/Headers folder there are files File1.h and File2.h. The header file File1.h includes File2.h via the following directive:
#include <File2.h>
The Foo framework is a re-package of a C++ library not specifically targeted for the Mac.
Now suppose I have a project that links to the Foo framework. It has a file MyFile.mm that includes File1.h via the following directive:
#import <Foo/File1.h>
Now when I tried to compile MyFile.mm, it always fails because it can't find File2.h. How can I get this to compile and run without modifying the header files of the Foo framework?
For the curious, the actual framework in question is a framework-packaged version of Taglib taken from the Max source tree. The file that I tried to include was <taglib/mp4.tag> and compiling the .mm file that includes it always fail due to mp4tag.h is including <tag.h> without the <taglib/...> prefix in the include directive. The error is not only in this one header files, but there are similar issues in a large number of header files and thus modifying all of these include statements is non trivial. All of the required "missing" header files are actually present in the framework's Header subdirectory.
I'm trying to use Taglib in my app and although I was able to compile Taglib as a framework with header files and add it to my app, I can't seem to get the app to compile due to the issues above.
Anybody has any pointers?
Thanks.
I think that File1.h should say:
#include "File2.h"
Try checking the "Always Search User Paths" option in Xcode.
Here are the steps to fix it:
Change the code to in File1.h to use '#include '.
In the framework project/default target/build phases, set the "copy files" phase and add both File1.h and File2.h.
Make sure that the "copy files" phase is before "compile" phase.
This should fix the issue, as the framework will refer to the files exactly the same way as the code that uses the framework.

What exactly is the "Multi-threaded Debug DLL" Runtime Library option doing in VS 2008?

I have a solution in VS 2008 that creates a DLL. I then use that DLL in another application. If I go in to the DLL projects property pages and change the following configuration for a DEBUG build then the built dll no long provides the desired functionality. If I change it back and rebuild the DLL, then the DLL does provide the correct functionality:
Property Pages => Configuration Properties => C/C++ => Code Generation => Runtime Library
If set to "Multi-threaded Debug DLL (/MDd)"
then everything works as it should. I get the correct functionality from the DLL
If set to "Multi-threaded DLL (/MD)" then the DLL does not function properly...no runtime errors or anything, it just doesn't work (The DLL is supposed to plot some lines on a map but does not in this mode).
So the question is, why does using the /MDd flag result in correction functionality of the underlying code, while /MD results in incorrect functionality?
A little background...somebody else developed the DLL in C++ and I am using this DLL in a VB.net application.
All DLL's/debug code generation must match across everything that uses them. There may be another referenced library or object or dll or some code in there that is built using the wrong options; or specific options for an individual element that override the global project options.
The only way of figuring it out is to meticulously check all of the options for each file, checking the included and referenced libraries (.lib and .dll) and object files. Check the linker options too.
The reason why it doesn't work is probably because the debug version adds extra guard blocks around memory to allow detection of errors.
I had similar problems. My application which "used" a 3rd party DLL crashed when its runtime library was set to "Multi-threaded DLL (/MD)", but worked when its runtime library was set to "Multi-threaded Debug DLL (/MDd)".
It has something to do with passing std::strings and std::lists across the DLL interface.
Our guess was the low level definition of these types was somehow different in the two runtime libraries.
We solved our related problems using this rule...
The DLL and the DLL user must be build using the exact same runtime library.
The main difference between the two options is in the libraries that your code will be linked at later. for the debug version for example this will include LIBCMTD.LIB and a few others. if your library is going to be built as debug the you should always link with MDd. failing to do so will result in lots of unresolved external linker errors at best. and sometimes the code compiles normally but crashes at runtime. if this happens in vb.net then a catch can easily hide the error. I guess you should make sure you build setting is correct. for more detailed information check this.