Plugin as optimizer and compiler - brunch

I'm trying to make a plugin which implements the compile & optimize methods.
In the doc, optimizers and compilers are always in a separated function/class.
Useless I set optimise to true in the config, the compile method is never called.
Is there a way to have both features in a same plugin ?
Edit: I tried MyPluginCompiler.prototype.defaultEnv = '*';

Did you specify either an extension MyPluginCompiler.prototype.extension = 'someExtension'; or a pattern for your plugin? Either one of these is required for a compiler, so that brunch knows what files to pass to the compilers.
I could not reproduce the issue. I created a repo with a simple plugin that is both a compiler and an optimizer for js files: https://github.com/goshakkk/brunch-plugin-optim-n-comp/blob/master/my-brunch/index.js
You can see it prints both 1 and 2 when building the supplied demo app https://github.com/goshakkk/brunch-plugin-optim-n-comp/tree/master/demo
https://github.com/goshakkk/brunch-plugin-optim-n-comp
If that does not fix your issue, please comment on this thread https://github.com/brunch/brunch/issues/1226

Related

MissingTranslation Errors after Upgrading to Gradle 3.3

Since upgrading to Gradle 3.3 I'm having trouble building my code due to missing-translation errors:
Error: xxx is not translated in "af" (Afrikaans), "am" (Amharic), "ar" (Arabic), "az" (Azerbaijani), "az-AZ" (Azerbaijani: Azerbaijan), "be" (Belarusian), "bg" (Bulgarian), "ca" (Catalan), [...], "zh-TW" (Chinese: Taiwan), "zu" (Zulu) [MissingTranslation]
The majority of the reported languages are those supported by a 3rd-party module included in my project, and it now seems to define the supported languages for the entire project, giving me this kind of error for all strings that are not translated into above languages. Before upgrading to Gradle 3.3 this was not causing any problems.
I considered the following solutions:
Remove surplus translations from other modules. I want to avoid that because those modules are external and needlessly altering them would really hurt maintainability of my project.
Disable the "incomplete translation" Lint inspection - the most common suggestion for similar questions on SO. This is sub-optimal because I want to be made aware of translations that are missing in my code (working so far). Besides that, disabling the check does not get rid of the error.
Define the supported configurations in build.gradle as described in this answer. I like this option (specifying languages instead of relying on translations available in the modules), but it also does something strange: I'm getting missing-translation errors for strings that are marked translatable = false.
For now, I'm downgrading again to the previous Gradle version. But what is the best apporach for fixing these build errors?
Hoping that there might have been corrections since I posted this question a few months ago, I checked the situation.
It seems that the issues were introduced with the Gradle plugin 2.3.0 and not Gradle 3.3 itself as I suggested in the question. Downgrading the plugin avoids the errors but can hardly be a long-term solution.
I found that option 3 in the question is the best way to handle it: add this to the app's build.gradle:
android {
defaultConfig {
...
resConfigs "en", "fr"
}
}
This is described in Googles documentation and, as mentioned, also in this answer. It removes all unnecessary resources - and the warnings/errors along with them.
Quoting the documentation:
The Gradle resource shrinker removes only resources that are not referenced by your app code, which means it will not remove alternative resources for different device configurations. If necessary, you can use the Android Gradle plugin's resConfigs property to remove alternative resource files that your app does not need.
For example, if you are using a library that includes language
resources (such as AppCompat or Google Play Services), then your APK
includes all translated language strings for the messages in those
libraries whether the rest of your app is translated to the same
languages or not. If you'd like to keep only the languages that your
app officially supports, you can specify those languages using the
resConfig property. Any resources for languages not specified are
removed.
The "false positives" (missing translation error for a non-translatable string) I got were for strings that were defined in more than one module. Renaming the strings or providing translations for them solved the problem. This, too, seems to be introduced with Gradle plugin 2.3.0.
In build.gradle add below code
lintOptions {
disable 'MissingTranslation'
}

How to load Rust compiler plugins without modifying the source code?

Rust provides various ways to write plugins. To extend checks on Rust code, it allows developer to write Lint Plugins. A typical way to use the plugin is to add a line to the source code indicating the use of this plugin:
#![plugin(myplugin)]
You also need to edit the Cargo.toml file to include your plugin project in the dependencies section:
myplugin = {path = "/path/to/myproject"}
However, if you want to analyze big projects, these modifications seem to be troubling, I wonder if cargo build or rustc provides any way to load my plugins without modifying the source code.
rustc has a command-line parameter for loading additional plugins: -Z extra-plugins=<plugins>. However, this option also requires that the path to the compiled plugin library be passed to the compiler. This is done automatically if the plugin library is declared as a dependency in Cargo.toml. If it's not in Cargo.toml, then you can compile it independently and reference it manually with --extern my_plugin=/path/to/plugin.rlib, in addition to the -Z extra-plugins=<plugins> option.
There's another option. Clippy, a large collection of general lints for Rust, provides a program that can be invoked as cargo clippy. That program basically acts as a fake rustc, implementing a compiler frontend (using internal crates used by rustc) that loads Clippy directly into the compiler's plugin registry (for the main project only, not for the project's dependencies). You can see the code on GitHub (licensed under MPLv2). The advantage of this approach is that you don't have to give a path to the plugin, because the plugin is built in the frontend. This makes it very convenient to use for the plugin's users. The disadvantage is that such a program relies on unstable compiler internals. This means that your program can stop compiling at any time due to a breaking change in rustc's unstable API.

How to prevent dead-code removal of utility libraries in Haxe?

I've been tasked with creating conformance tests of user input, the task if fairly tricky and we need very high levels of reliability. The server runs on PHP, the client runs on JS, and I thought Haxe might reduce duplicative work.
However, I'm having trouble with deadcode removal. Since I am just creating helper functions (utilObject.isMeaningOfLife(42)) I don't have a main program that calls each one. I tried adding #:keep: to a utility class, but it was cut out anyway.
I tried to specify that utility class through the -main switch, but I had to add a dummy main() method and this doesn't scale beyond that single class.
You can force the inclusion of all the files defined in a given package and its sub packages to be included in the build using a compiler argument.
haxe --macro include('my.package') ..etc
This is a shortcut to the macro.Compiler.include function.
As you can see the signature of this function allows you to do it recursive and also exclude packages.
static include (pack:String, rec:Bool = true, ?ignore:Array<String>, ?classPaths:Array<String>):Void
I think you don't have to use #:keep in that case for each library class.
I'm not sure if this is what you are looking for, I hope it helps.
Otherwise this could be helpful checks:
Is it bad that the code is cut away if you don't use it?
It could also be the case some code is inlined in the final output?
Compile your code using the compiler flag -dce std as mentioned in comments.
If you use the static analyzer, don't use it.
Add #:keep and reference the class+function somewhere.
Otherwise provide minimal setup if you can reproduce.

Is there any global flag for Groovy static compilation?

I know that since Groovy 2.0 there are annotations for static compilation.
However it's ease to omit such annotation by accident and still run into troubles.
Is there any way to achieve the opposite compiler behaviour, like compile static all project files by default and compile dynamic only files chosen by purpose with some kind #CompileDynamic annotation for example?
I have found some (I believe recently introduced) feature which allows doing so with Gradle.
In build.gradle file for the project containing groovy sources we need to add following lines:
compileGroovy {
configure(groovyOptions) {
configurationScript = file("$rootDir/config/groovy/compiler-config.groovy")
}
}
or compileTestGroovy { ... for applying the same to test sources. Keep in mind that neither static compilation nor type checking works well with Spock Framework though. Spock by its nature utilizes dynamic 'groovyness' a lot.
Then on a root of the project create folder config/groovy/ and a file named compiler-config.groovy within. The content of the file is as follows:
import groovy.transform.CompileStatic
withConfig(configuration) {
ast(CompileStatic)
}
Obviously path and name of the configurationScript may vary and it's up to you. It shouldn't rather go to the same src/main/groovy though as it would be mixing totally separate concerns.
The same may be done with groovy.transform.TypeChecked or any other annotation, of course.
To reverse applied behaviour on certain classes or methods then #CompileDynamic annotation or #TypeChecked(TypeCheckingMode.SKIP) respectively may be used.
I'm not sure how to achieve the same when no Gradle is in use as build tool. I may update this answer in the future with such info though.
Not at this time, but there is an open Jira issue here you can follow to watch progress for this feature
There was also a discussion about methods for doing this on the Groovy developers list

Link libraries with dependencies in Visual C++ without getting LNK4006

I have a set of statically-compiled libraries, with fairly deep-running dependencies between the libraries. For example, the executable X uses libraries A and B, A uses library C, and B uses libraries C and D:
X -> A
A -> C
X -> B
B -> C
B -> D
When I link X with A and B, I don't want to get errors if C and D were not also added to the list of libraries—the fact that A and B use these libraries internally is an implementation detail that X should not need to know about. Also, when new dependencies are added anywhere in the dependency tree, the project file of any program that uses A or B would have to be reconfigured. For a deep dependency tree, the list of required libraries can become really long and hard to maintain.
So, I am using the "Additional Dependencies" setting of the Librarian section in the A project, adding C.lib. And in the same section of B's project, I add C.lib and D.lib. The effect of this is that the librarian bundles C.lib into A.lib, and C.lib and D.lib into B.lib.
When I link X, however, both A.lib and B.lib contain their own copy of C.lib. This leads to tons of warnings along the lines of
A.lib(c.obj) : warning LNK4006 "symbol" (_symbol) already defined in B.lib(c.obj); second definition ignored.
How can I accomplish this without getting warnings? Is there a way to simply disable the warning, or is there a better way?
EDIT: I have seen more than one answer suggesting that, for the lack of a better alternative, I simply disable the warning. Well, this is part of the problem: I don't even know how to disable it!
As far as I know you can't disable linker warnings.
However, you can ignore some of them, using command line parameter of linker eg. /ignore:4006
Put it in your project properties under linker->command line setting (don't remember exact location).
Also read this:
Link /ignore
MSDN Forum - hiding LNK warnings
Wacek
Update If you can build all involved project in single solution, try this:
Put all project in one sln.
Remove all references to static libraries from projects' linker or librarian properties.
There is "Project Dependencies..." option in context menu for each project in Solution Explorer. Use it to define dependencies between project.
It should work. It doesn't invalidate anything I said before, the basic model of building C/C++ programs stays the same. VS (at least 2005 and newer) is simply smart enough to add all needed static libraries to linker command line. You can see it in project properties.
Of course this method won't help if you need to use already compiled static libraries. Then you need to add them all to exe or dll project that directly or indirectly uses them.
I don't think you can do anything about that. You should remove references to other static libs from static libs projects and add all needed static libs projects as dependences of exe or dll projects. You will just have to live with fact that any project that includes A.lib or B.lib also needs to include C.lib.
As an alternative you can turn your libraries into dlls which provide a richer model.
Statically compiled libraries simply aren't real libraries with dependency information, etc, like dlls. See how, when you build them, you don't really need to provide libraries they depend on? Headers are all that's needed. See? You can't even really say static libraries depend on something.
Static library is just an archive of compiled and not yet linked object code. It's not consistent whole. Each object file is compiled separately and remains separate entity inside the library. Linking happens when you build exe or dll. That's when you need to provide all object code. That's when all the symbol and dependency resolving happens.
If you add other static libraries to static library dependencies, librarian will simply copy all code together. Then, when building exe, linker will give you lots of warnings about duplicate symbols. You might be able to block those warnings (I don't know how) but be careful. It may conceal real problems like real duplicate symbols with differing definitions. And if you have static data defined in libraries, it probably won't work anyway.
Microsoft (R) Incremental Linker Version 9.00.x (link.exe) knows argument /ignore:4006
You could create one library which contains A, B, C & D and then link X against that.
Since it's a library, only object modules which are actually referenced will get linked into the final executable.
Note that one way of getting this warning is to define a member function in a header without the inline statement:
// Foo.h
class Foo
{
void someFunction();
};
void Foo:someFunction() // Warning! - should be "inline void Foo::someFunction()"
{
// do stuff
}
The problem is you are not localizing library C's symbols. So you have a ODR violation when you link in A and B. You need to have a way to make these private. By default all symbols are exported. One way to do this is to have a special linker definition file for both A and B that explicitly mention which files need to be exported.
[1] ODR = One Definition Rule.
I think the best course of action here will be to ignore/disable the linker warnings(LNK4006) since C.lib needs to be part of both A.Lib and B.lib and A.Lib does not need to know that B.lib itself uses C.Lib.
This may not fix your link error, but it might help with your dependency tree issue.
What I do, is just use a #pragma to include a lib in the .cpp file that needs it. For example:
#pragma comment(lib:"wsock32")
Like I said, I'm not sure it would keep the symbols in that object file, I'd have to whip up an example to try it out.
Poor flodin seems frustrated that nobody will explain how to disable the linker warnings. Well, I've had a similar problem, and for years I have simply lived with the fact that several hundred warnings were displayed. Now, however, thanks to the info from Link /ignore, I figured out how to disable the linker warnings.
I'm using Visual Studio 2008. In Project -> Settings -> Configuration Properties -> Librarian -> Command Line -> Additional Options, I added "/ignore:4006" (without the quotes). Now my warnings are gone!

Resources