Nuget .targets AfterTargets="Build" - nuget-package

I am building and using a Nuget package, and the .targets file specifies a Target like this:
<Target Name="CopyOutputFiles" AfterTargets="Build">
I didn't originally create the project, so I assume that AfterTargets="Build" is a default setting, but I'm not sure.
With this setting, the Target ends up executing right after the PostBuild step when I am consuming the package in a project in another solution.
I would like the Target to execute prior to the Post-Build step, and I found that setting the target to AfterTargets="CustomBuildStep" did what I wanted when only compiling the project in the solution that consumes the package.
<Target Name="CopyOutputFiles" AfterTargets="CustomBuildStep">
There are multiple projects in the solution that uses the package, and I'm wondering if it is harmless to change the AfterTargets= value. I'm concerned that this appears to be working when I only build one of the projects in the solution, and that it will cause unexpected problems if I clean and build all, or build the projects randomly. (because I don't fully understand the build sequence, especially when there are multiple interdependent projects in the solution.)
My question is:
Will changing the AfterTargets value from "Build" to "CustomBuildStep" cause problems when multiple projects are building within the solution, or will the behavior be predictable, as though I am only building the project that consumes the package? (i.e. will the Target always execute after the post-build step in the correct project.)

Related

Why Is Doppl Trying To Pull in ReactiveStreams?

I am attempting to convert parts of an Android app to iOS using Doppl, and I am getting a strange result: Doppl keeps trying to pull in android.arch.lifecycle:reactivestreams, even though I don't want it to.
Specifically, in app/build/j2objcSrcGenMain/android/arch/lifecycle/, there is a reactivestrams/ subdirectory with R.h and R.m files in it. This seems to make Xcode cranky and may explain why I had some oddities with pod install.
My app/build.gradle has compile "android.arch.lifecycle:reactivestreams:$archVer", because my activity is using LiveDataReactiveStreams.fromPublisher(). However:
The activity is not in the translatePattern (and since its code is not showing up in app/build/j2objcSrcGenMain/, I have to assume that the translatePattern is fine)
I do not have a doppl statement related to reactivestreams, because there does not appear to be a Doppl conversion of this library (nor should it be needed here)
AFAIK, nowhere else in this app am I referring to LiveDataReactiveStreams, which AFAIK is the one-and-only public class from the reactivestreams library
So, the questions:
What determines whether Doppl creates R.h and R.m files for some dependency? It's not the existence of a doppl statement, as I have doppl statements for a lot of other dependencies (RxJava, RxAndroid, Retrofit) and those do not get R.h and R.m files. It's not whether the dependency is referenced from generated code, as my repository definitely uses RxJava and Retrofit, yet there are no R files for those.
How can I figure out why Doppl generates R.h and R.m for reactivestreams?
Once I get this cleared up... do I re-run pod install, or is there some other pod command to refresh an existing pod with a new implementation?
Look into 'app/build/generated/source/r/debug' and confirm there's an R.java being created for the architecture component. It'll be under 'android/arch/lifecycle/reactivestrams'.
I think there are 2 problems here.
Problem 1
Somehow Doppl/J2objc is of the opinion that this file should be transpiled. It could be either that 'translatePattern' matches with it, or that something in the shared code is referencing it. If you can't figure out which, please post a comment and I'll try to help (or post in slack group).
Problem 2
Regardless of why that 'R.java' is being sucked into the translate step, because of how stock J2objc is configured, the code is being generated with package folders instead of creating One Big Name. That generated file should be called 'AndroidArchLifecycleReactivestramsR.h' (and AndroidArchLifecycleReactivestramsR.m). Xcode really doesn't like package folders. That's why there's a slightly custom J2ojbc being used with Doppl, so we can have files with big names instead of folders.
In cases where you intentionally use package names that match with what J2objc considers to be "system" classes, you need to provide a header mapping file to force long names. The 'androidbase' doppl library needs to add a lot of files that are in the 'android' package, which J2objc considers "system". We override those names in the mapping file.
build.gradle
https://github.com/doppllib/core-doppl/blob/master/androidbase/build.gradle#L19
mapping file
https://github.com/doppllib/core-doppl/blob/master/androidbase/src/main/java/androidbase.mappings
I screwed up.
In my dopplConfig, I have:
translatePattern {
include '**/api/**'
include '**/arch/**'
include '**/RepositoryTest.java'
}
In this case, **/arch/** not only matches my arch package, but also the arch package from the Architecture Components.
Ordinarily, this would not matter, because the Architecture Components source code is not in my project. But, R.java gets generated, due to resources, and the translatePattern includes generated source code in addition to lovingly hand-crafted source code. So, that's where my extraneous Objective-C was coming from.
Many thanks to Kevin Galligan for his assistance with this, out on the #newbiehelp Doppl Slack channel!

Customizing the specific output files for various Typescript input files

I've got a web project using TypeScript that has some reasonably complex requirements for the compiled output files. So for instance, I need all the *.ts files in one directory to compile down to one single .js file, and all the *.ts files in another directory to compile down to a different .js file. (It's more complex than that, but you get the idea.)
I've been able to get this working using the tsc.exe command-line, using input files and what-not, but I'd like to be able to use MSBuild .targets files - among other things, using tsc.exe from the command-line seems to be pretty poorly supported on continuous integration servers, where it can be located who-knows-where, and certainly isn't likely to be in the path.
According to this answer here, it seems like I should be able to do this using custom build targets. So I've created a custom version of Microsoft.TypeScript.targets, and in addition to the default "CompileTypeScript" target, I've created a second one, "PayboardApiV10", so that the relevant part looks like so:
<Target Name="CompileTypeScript" Condition="'$(BuildingProject)' != 'false'">
<Message Text="Compiling TypeScript files normally" Importance="high"/>
<VsTsc
ToolPath="$(TscToolPath)"
ToolExe="$(TscToolExe)"
Configurations="$(TypeScriptBuildConfigurations)"
FullPathsToFiles="#(TypeScriptCompile)"
YieldDuringToolExecution="$(TscYieldDuringToolExecution)"
OutFile="$(TypeScriptOutFile)"
OutDir="$(TypeScriptOutDir)"
>
<Output TaskParameter="GeneratedJavascript" ItemName="GeneratedJavascript" />
</VsTsc>
</Target>
<Target Name="PayboardApiV10" Condition="'$(BuildingProject)' != 'false'">
<Message Text="Compiling TypeScript files for Payboard API v1.0" Importance="high" />
<VsTsc
ToolPath="$(TscToolPath)"
ToolExe="$(TscToolExe)"
Configurations="$(TypeScriptBuildConfigurations)"
FullPathsToFiles="#(TypeScriptCompile)"
YieldDuringToolExecution="$(TscYieldDuringToolExecution)"
OutFile="Payboard.js"
OutDir="$(ProjectDir)api\v1.0\"
>
<Output TaskParameter="GeneratedJavascript" ItemName="GeneratedJavascript" />
</VsTsc>
</Target>
And then I've specified a "CustomTool" in my project configuration for the specific files that I'd like to get picked up by the "PayboardApiV10" build target, like so:
I should note that I have no idea if I'm doing this bit correctly. I can't seem to find any documentation on it, and the only examples I've been able to find are from that previous answer. And more to the point, when I run my builds, all the TS files in my project get caught up in the first build target, including the ones for which I've specified "MSBuild:PayboardApiV10" for the custom tool. The "PayboardApiV10" tool never seems to get run, i.e., I never see the message "Compiling TypeScript files for Payboard API v1.0".
So two questions:
(1) Is there a better way to do what I'm trying to do?
(2) If this is generally the right way to do it, any ideas as to what I'm doing wrong?
The direction you're going is the optimal way (on save). In the meantime you can use post-build events to transform the typescript. Right click on your project and select properties. Select Build Events and in the Post-Build area you can specify command line parameters to use tsc.exe.
On the direction you're going (compile on save) I think the project file may be missing the following on each file you want compiled:
<TypeScriptCompile Include="app.ts" />
The configuration is also likely missing the environment settings.
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<TypeScriptTarget>ES5</TypeScriptTarget>
<TypeScriptIncludeComments>true</TypeScriptIncludeComments>
<TypeScriptSourceMap>true</TypeScriptSourceMap>
</PropertyGroup>
More information on both methods is available at this TypeScript wiki page.
I ended up asking this same question over on the TypeScript forums (https://typescript.codeplex.com/discussions/455781). The conclusions I drew from the conversation there:
There isn't a great way to do it now.
The best hacky way to do it now is probably the way that I was doing it, namely, with batch files, post-build events, and checking the compiled files into source. Other folks recommended Grunt, or the ASP.NET MVC bundling mechanism (the latter won't work in my scenario); I've also used the r.js minifier in the past. And these will work; but to reiterate, none of these are really very good solutions.
The best way to do it in the future will be to create "library projects" of TypeScript files, so that all TS files in a given project get compiled together; and then you can reference the library TS projects from your main Web project, and will automatically get the compiled files merged into your main ~/Scripts folder. But that will require support from the TS team - which Jon Turner basically indicated would be coming, though he didn't say when. (See also https://typescript.codeplex.com/workitem/571.)

How to link ".a" fat-static-libs with Apportable?

How do I link ".a" fat-static-libs with Apportable?
In the beginning, I did get a warning,
Warning: Library not found for lib-name. Try adding this to the
'deps' array in the 'add_params' section of your configuration.json
file. Check ~/.apportable/SDK/System for the directory names that
correspond to 'deps' entries.
I did add it to "deps" in the JSON right where it says this:
// A list of dependencies. Typically these correspond to frameworks in the xcode project.
My library isn't a framework, though. It's just a .a static library that has armv7, armv7s, and i386 parts which I assembled using lipo from two libraries (an armv7 and armv7s .a and a i386 .a) built with Xcode. They both use a single framework which is this Boost framework.
Adding it under deps squelched that warning message, but the apportable linker is still giving undefined references, so it is still not properly linking this file.
Now I know that Apportable has to re-jitter all this stuff, since Android won't know what to do with a Mac-executable format, so it's probably got to go pick apart my library and possibly turn it into an ELF-library before final linking. I'm not sure how to go about debugging this at this point, but is this supported at all?
Since you get "library not found" that means Apportable simply can't find the file. Hence the problem is merely with the file's location (or existence) and not what's in the library or how it is built.
The most common issue with dependent targets, especially Xcode projects dropped into other Xcode projects respectively workspaces with multiple projects, is that the resulting output of each target/project goes to different folders. Then Apportable (as well as xcodebuild under some circumstances) can't find the resulting libraries.
First step you should try is to make sure that the target dependencies are set. Select the app target, go to the Build Phases pane and under Target Dependencies add all frameworks and libraries that appear in the list and that your project depends on. This should ensure that the dependent frameworks/libraries do get built - because Xcode's built-in automatic dependency resolution isn't available to command line tools from what I understand. So you need to explicitly specify the dependent projects respectively their output.
If that doesn't help, you can force all targets to write their output to the same folder. Under Build Settings for every target change the Build Products Path (symbolic name: SYMROOT) to the same folder, for example ~/myprojectsbuildoutput
That way even dependent other projects will place their output in the same folder and xcodebuild as well as Apportable (it depends on xcodebuild) will be able to find the library files.
Tip: make sure your project builds successfully on the command line. Open Terminal, cd into the folder where the .xcodeproj bundle is and enter xcodebuild. If xcodebuild fails merely due to validation, disable Validate Built Product under Build Settings of the app target. If xcodebuild fails, Apportable likely isn't going to work either because it depends on xcodebuild. So as a prerequisite make sure that xcodebuild works on your project.
If xcodebuild also gives you "library not found" try calling it with a specific SYMROOT:
xcodebuild SYMROOT=~/myprojectsbuildoutput
If that then works you know you have to update each target's Build Projects Path. From what I know it's not currently possible (or not documented) to pass custom xcodebuild parameters via Apportable, so it needs to be set up in the .xcodeproj itself.

CVTRES.exe is discarding my DLL exported functions

I'm working on a project that creates a DLL in C for Windows CE 5.0 using STANDARDSDK_500. The project is relatively simple with just one C source file. What I've noticed is that when I clean and build the project using Visual Studio 2005, it fails to create my Import lib. When I tell Visual Studio to rebuild it, it correctly creates the import lib.
Turning on verbose linking, I discover that in the failure case (clean and build) CVTRES.exe is discarding my functions, like so:
Invoking CVTRES.exe:
/machine:thumb
/verbose
/out:"C:\...\Temp\lnkC7E.tmp"
/readonly
/windowsce
".\standardsdk_500 (armv4i)\release\WLTBApi.res"
Microsoft (R) Windows Resource To Object Converter Version 8.00.50727.42
...
adding resource. type:VERSION, name:1, language:0x0409, flags:0x30, size:892
Discarded '.idata$4' from coredll.lib(COREDLL.dll)
...
Discarded WLRegisterStartupApp from WLTBApi.obj // my functions! Oh noes!
...
This discards all of my functions, which causes the linker to not create an import lib because there are no exported functions.
I figured that the input was the .res file mentioned in the commandline - WLTBApi.res. This file is identical in the intermediate directory after trying to compile both the working way (rebuild) and the non-working way (clean. build).
So, my first question is: what are the other inputs to the CVTRES.exe program so that I can find discrepencies between the two builds?
Second: what other troubleshooting techniques would you recommend?
Additional Info - I thought perhaps the .obj files were additional inputs - they differ between the builds. I now believe that they are outputs of CVTRES.exe. If anyone knows whether or not I'm correct in this, let me know.
Okay, so I found a solution, but I'm terribly dissatisfied with it. I discovered that the project I was building had a Dependency, but one that wasn't actually a dependency. In other words, the project, WLTBApi was building a DLL, and had a dependency configured, WLTBApiLib, but it wasn't actually using any of the output of that project. By removing the dependency, the problem went away.
I'd still love to know more about how to find an actual answer to what was going on, but maybe this answer will help someone else in the future.

Cruise Control .NET ignoring project dependencies

I have been using CC.Net successfully for some time, but now I have a problem. I added new solution to CC. It is compiled fine in VS2008, but fails in CC. The main reason is - projects in solution are built in wrong order, with no regard to dependencies. CC just tries to build them in the same order as they are stored on disc (alphabetical order).
For example, in solution there is proect Proj1 and Proj2, Proj1 has reference to Proj2. On CCNET Proj1 is built before Proj2 and throws error "CSC : error CS0006: Metadata file 'D:\xxx\Proj2\bin\Debug\Proj2.dll' could not be found".
I know this could happen when devenv is used to build solutions, but I use MSBuild.
The following code is responsible for building:
<exec>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
<baseDirectory>code\src</baseDirectory>
<buildArgs>/p:Configuration=Debug /t:Rebuild PM.sln</buildArgs>
<buildTimeoutSeconds>1200</buildTimeoutSeconds>
</exec>
What am I doing wrong?
The error Metadata file could not be found:
When it happened to me, it was because there was a file called proj1.exe at that location that should not have been there. So when it used proj1.exe as the reference (instead of a proj1.dll), proj1.exe's reference to a local System.EnterpriseServices.dll failed. This was happening to me with proj1.exe referencing System.EnterpriseServices.dll which referenced System.EnterpriseServices.Wrapper.dll. Where proj1.exe was not supposed to be included in the build but someone had named a unit test app project against our team conventions.
So I recommend checking the references in the project files(unload project and edit project in vs2010 or open each project file with a text or xml editor) to make sure they are ProjectReference not Reference. Also try doing the build with /v:d in the buildArgs list so you get a more detailed build log that will show you where files were resolved to and in what order. Aa different reference that is 'successfully' resolved could be attempting to load x.dll that directly locally references your D:\xxx\Proj2\bin\Debug\Proj2.dll but fails.

Resources