AssemblyFileVersion causing build to fail - tfs

When I try to build my project, I get the following error:
error : Unable to update the AssemblyFileVersion for c:\builddir\MyProject\AssemblyInfo.cs: No stub entry for AssemblyFileVersion was found in the AssemblyInfo file.
I found this article, which implies that a "stub" property is required. So, in my AssemblyInfo.cs, I tried to specify one:
[assembly: AssemblyFileVersion("1.0.0")]
However, it isn't recognised. I finally came across this article, which says that you can't use the AssemblyFileVersion property with the CF. The targets file used by the build script is also used for building other, non CF projects, and needs to update the FileVersion for them.
Is it possible to put something in the AssemblyInfo.cs file, the target file or the build script that stops this from being an issue?

Yes, something like this:
#if !(WindowsCE || PocketPC)
[assembly: AssemblyFileVersion("1.0.0")]
#endif

If using the preprocessor in the manner described in the other answer doesn't work for you, consider putting the AssemblyFileVersion attribute into a separate source file, and conditionally including that source file in the project:
<Compile Include="AssemblyInfo.cs" />
<Compile Include="AssemblyInfo.AssemblyVersion.cs"
Condition="
'$(TargetPlatform)' == 'WindowsCE' OR
'$(TargetPlatform)' == 'PocketPC'"
/>
I'm not sure if there is already a property you can use in the project file, or if you would need to declare your own (perhaps $(Platform) is used for this?)

Related

How to harvest XNA content files using WiX?

Ideally I'd be grabbing the outputs from the project spec itself, but heat.exe doesn't seem to support contentproj files as a project type, nor does it pick up the content if I pass in the game's main csproj.
Currently I have a pre-build step calling heat on the output folder, but that (a) feels dirty, and (b) produces a bunch of File tags referencing the source paths relative to the output folder, such that the build fails when it can't find them relative to the WiX project's folder.
I should note that I'm using Votive and my project layout looks like this:
- Main solution
- XNA "Metaproject" Folder
- Game
- bin/x86/Release (GameContent output appears here)
- GameContent
- WiX Project
I would very much like to minimize the number of times I have to specify a path like "../../Game/Game/bin/x86/Release/Content", because that's error-prone and depressing to type out. Prods in the right direction appreciated!
Assuming a contentproj is just a collection of files, what you can do is add the harvesting directly within the wixproj that is creating the installer:
<PropertyGroup>
<HarvestDirectoryNoLogo>true</HarvestDirectoryNoLogo>
<HarvestDirectorySuppressFragments>true</HarvestDirectorySuppressFragments>
<HarvestDirectorySuppressUniqueIds>true</HarvestDirectorySuppressUniqueIds>
<HarvestDirectoryAutogenerateGuids>true</HarvestDirectoryAutogenerateGuids>
</PropertyGroup>
<ItemGroup>
<HarvestDirectory Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "
Include="$(SolutionDir)\GameContent">
<DirectoryRefId>INSTALLDIR</DirectoryRefId>
<SuppressRootDirectory>true</SuppressRootDirectory>
<PreprocessorVariable>var.GameContentDir</PreprocessorVariable>
<ComponentGroupName>GameContent</ComponentGroupName>
</HarvestDirectory>
</ItemGroup>
You will need to add this manually to the wixproj file and you can repeat the HarvestDirectory for each directory if you require more than one.
To set the var.GameContentDir pre-processor variable edit the DefineConstants property:
<DefineConstants>GameContentDir=$(GameContentDir);</DefineConstants>
which will set the pre-processor var to the msbuild property:
<GameContentDir>$(SolutionDir)\GameContent</GameContentDir>
which means you can then modify this dependant on the build configuration. If you don't need to modify the path, just set a static value in the <DefineConstants> property.
This will then generate a wxs file in the obj directory each build which is then included assuming you have included the ComponentGroupName. If you have included the one you previously generated in your wixproj remove it as you will get conflicts if the ComponentGroupName is the same.

Can I add conditional defines in the msbuild command line?

I have the following sample code:
program boohoo;
{$APPTYPE CONSOLE}
{$IFDEF boo}
{$MESSAGE warn 'boo'}
{$ENDIF}
{$IFDEF hoo}
{$MESSAGE warn 'hoo'}
{$ENDIF}
begin
end.
In the project options the conditional boo is defined. I would like to be able to add the conditional hoo as part of my msbuild command line.
I have tried it like this:
msbuild boohoo.dproj /p:Config=Release;DCC_Define="$(DCC_Define);hoo"
The output shows hoo but not boo. When I use verbose output to see the dcc32 command I see
-D$;hoo
Clearly I can do it like this:
msbuild boohoo.dproj /p:Config=Release;DCC_Define="boo;hoo"
but naturally I want to use whatever conditionals are declared in the project options plus what I specify on the command line.
Is there any way for me to specify this property with reference to the value from the underlying configuration?
Disclaimer: don't use MsBuild myself yet, all taken from the docs and some IDE experimentation
According to MsBuild command line reference ( http://msdn.microsoft.com/en-us/library/ms164311.aspx ):
/property:name=value
Sets or overrides these project-level properties, where name is the
property name and value is the property value. Use a semicolon or a
comma to separate multiple properties, or specify each property
separately. /p is also acceptable. For example:
/property:WarningLevel=2;OutputDir=bin\Debug
setting or overriding is all you can do for a property value. Adding to a property value from the project file is either not possible or a case of a hidden feature.
But I guess what you could do is define a custom property in your dproj file with an " " as its default value:
<PropertyGroup>
<ExtraDefines> </ExtraDefines>
</PropertyGroup>
reference that in your defines statement
<DCC_Define>DUNIT;$(ExtraDefines);$(DCC_Define)</DCC_Define>
which in the IDE should be DUNIT;$(ExtraDefines)
and then specify it on the command line:
msbuild boohoo.dproj /p:Config=Release;ExtraDefines="hoo"
I did test adding the $(ExtraDefines) to the Include options for the project using the IDE. And at least that didn't barf at me, even without having the option defined in the dproj. The commandline the IDE produced from this was:
...rad studio\7.0\bin\dcc32.exe --no-config -B -Q -DDEBUG;DUNIT; -E....
Which seems to indicate that the $(ExtraDefines) got eliminated as it had no value. And that it should be picked up using MSBuild and specififying a value on the command line.
Almost 5 years later, but all answers are not quite elegant ))
Recently, I've faced the same problem
And here is the solution:
Usually, DCC_Define is defined in a .dproj file like this:
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>boo;$(DCC_Define)</DCC_Define>
We all have tried to define DCC_Define via /property:DCC_Define=blah-blah
But accordingly to How to: Build the Same Source Files with Different Options:
The property value that is specified on the command line takes precedence over any value that is set for the same property in the project file, and that value in the project file takes precedence over the value in an environment variable.
So, failure (that is the question here!)
BUT! How to: Use Environment Variables in a Build
To use an environment variable in an MSBuild project
Reference the environment variable the same way you would a variable declared in your project file. For example, the following
code references the BIN_PATH environment variable:
<FinalOutput>$(BIN_PATH)\MyAssembly.dll</FinalOutput>
So, we must define environment variable with the name DCC_Define and values of our ADDITIONAL conditionals
> set DCC_Define=hoo;doo;moo;foo
and then simply run
> msbuild boohoo.dproj /p:Config=Release
DCC32 will get then -Dboo;hoo;doo;moo;foo
Straightforward solution is to create a new build configuration (say, boohooRelease), add both boo and hoo conditional defines to it and compile as msbuild boohoo.dproj /p:Config=boohooRelease. Not exactly what you are trying to do, but it works.
I just tried the following and it worked, so don't know whether Microsoft has changed it:
msbuild "myApp.dproj" /t:build /property:DCC_Define="boo"
remember to add the double quote "", otherwise it won't work
Another way is to create a wrapper project file like this:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Full" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Full">
<CreateProperty Value="$(DCC_Define);$(ExtraDefines)">
<Output TaskParameter="Value" PropertyName="DCC_Define"/>
</CreateProperty>
</Target>
<Import Project="example.dproj" />
</Project>
and invoke like this:
msbuild.exe "/t:Clean;Full;Build" "/p:config=Debug" /p:ExtraDefines=SOME_DEFINE wrapper.proj
It is certainly less elegant but you don't have to modify the .dproj file.

mxmlc and framework linkage - how to specify linkage as rsl

I'm trying to build my flex 4 project using ant. In Flash Builder 4, in project properties it's possible to set the "Framework linkage" to one of "Merged into code", "Runtime Shared Library (RSL)" or "Use SDK Default (Runtime Shared library)". How can I set the equivalent as mxmlc options in build.xml?
My current build.xml looks like this:
<target name="myapp">
<mxmlc
file="${PROJECT_ROOT}/myapp.mxml"
output="${DEPLOY_DIR}/myapp.swf"
actionscript-file-encoding="UTF-8"
keep-generated-actionscript="false"
warnings="false" optimize="true" incremental="false" >
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_FRAMEWORKS}"/>
<compiler.debug>true</compiler.debug>
<runtime-shared-library-path path-element="${FLEX_FRAMEWORKS}/libs/framework.swc">
<url rsl-url="framework_4.0.0.14159.swz"/>
<url rsl-url="framework_4.0.0.14159.swf"/>
</runtime-shared-library-path>
<compiler.source-path path-element="src"/>
<!-- List of external libraries -->
<compiler.source-path path-element="${MY_LIB}/src" />
<!-- List of SWC files or directories that contain SWC files. -->
<compiler.library-path dir="libs" append="true">
<include name="*.swc" />
</compiler.library-path>
<copy todir="${DEPLOY_DIR}" file="${FLEX_FRAMEWORKS}/rsls/framework_4.0.0.14159.swz"/>
<copy todir="${DEPLOY_DIR}" file="${FLEX_FRAMEWORKS}/rsls/framework_4.0.0.14159.swf"/>
</mxmlc>
</target>
I assumed that setting the runtime-shared-library-path directive and copying the framework swf, swz files into my target folder would make things work, but this does not seem to be the case.
The way I'm assessing whether this works is as follows: I use a custom preloader, and for it to work I need to have framework linkage as RSL. With "merged into code", my preloader gets stuck at a certain point and does not progress to my application swf. This is the same behavior i see when i use the above build.xml, which makes me think that the SWF is being built with framework linkage merged into code (rather than RSL linked).
A related question to this is how to determine if my swf is using RSL or not. I guess I could look at the size of the compiled output. But it seems there should be a way to tell if I'm using the external framework file or it's being bundled into the SWF somehow, without my knowledge.
This is a little tricky because the documentation is a little scarce on this. You probably need to set the following option either on the command line or a config file.
static-link-runtime-shared-libraries=false
The documentation from Adobe gives the following slightly cryptic description of what this option does.
Determines whether to compile against libraries statically or use RSLs. Set this option to true to ignore the RSLs specified by the runtime-shared-library-path option. Set this option to false to use the RSLs. The default value is true.
This option is useful so that you can quickly switch between a statically and dynamically linked application without having to change the runtime-shared-library-path option, which can be verbose, or edit the configuration files.
Here is a link to the documentation.
"About the application compiler options"
Note that from the documentation the default value is true. HOWEVER if you are loading a flex-config.xml file (default or custom) you should also check if this setting is present in that file and what it is. In my experience the default value for the frameworks/flex-config.xml is actually false. It appears however that in the example above that this may be set the other way.
(We use a different build system than ANT so I am not that familiar with the build.xml syntax you would need.)

How do I reference types or modules defined in other F# files? [duplicate]

This will hopefully be an easy one. I have an F# project (latest F# CTP) with two files (Program.fs, Stack.fs). In Stack.fs I have a simple namespace and type definition
Stack.fs
namespace Col
type Stack=
...
Now I try to include the namespace in Program.fs by declaring
open Col
This doesn't work and gives me the error "The namespace or module Col is not defined." Yet it's defined within the same project. I've got to be missing something obvious
What order are the files in the .fsproj file? Stack.fs needs to come before Program.fs for Program.fs to be able to 'see' it.
See also the start of
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!444.entry
and the end of
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!347.entry
I had the same problems, and you are right, the order of the files is taken in account by the compiler. Instead of the Remove and Add pattern, you can use the Move Up / Move Down items in the context menu associated to the .fs files. (Alt-Up and Alt-Down are the shortcut keys in most of the standard key-bindings)
All of the above are correct, but how to do this in VS2013 is another question. I had to edit my .fsproj file manually, and set the files in exact order within an ItemGroup node. In this case it would look like this:
<ItemGroup>
<Compile Include="Stack.fs" />
<Compile Include="Program.fs" />
<None Include="App.config" />
</ItemGroup>
I had the same issue and it was indeed the ordering of the files. However, the links above didn't describe how to fix it in Visual Studio 2008 F# 1.9.4.19.
If you open a module, make sure your source file comes after the dependency in the solution explorer. Just right click your source and select Remove. Then re-add it. This will make it appear at the bottom of the list. Hopefully you don't have circular dependencies.
I'm using Visual Studio for Mac - 8.1.4 and i've noticed that some .fs files are not marked as "Compile". You can see this by Viewing Build Output and see if all your files are there and in the correct order.
I've had to manually make sure certain files are marked with "Compile", and have had to move them up and down manually until it "takes".

Setting an item metadata using a property

I have been trying to make a task in my TFS builds more generic, and one of the things I am trying to do is copy some files to different directories depending on the build using the task. I toyed with the idea of using properties, but I couldn't think of a way to do that cleanly, so I tried to go with using item metadata, as I've been able to do so in another place in the same target file I'm working on, only this time, I'd like to use properties.
Here's what I want to do:
<ItemGroup>
<DestinationParent Include="$(DeploymentPath)">
<DestinationParentPath>$(DeploymentPath)</QuartzParentPath>
</DestinationParent>
</ItemGroup>
And later in the build, I tried to copy some files to the destination folder by referencing the item metadata:
<Copy SourceFiles="#(FilesToCopy)" DestinationFiles="#(FilesToCopy->'%(DestinationParentPath)\Destination\%(RecursiveDir)%(Filename)%(Extension)')" ContinueOnError="false" ></Copy>
Unfortunately, after the build runs, my BuildLog shows the following:
Copying file from "$(BinariesRoot)\%(ConfigurationToBuild.FlavorToBuild)\<File being copied>" to "\Destination\<File being copied>".
%(DestinationParentPath) had expanded to an empty string, for whatever reason. Using %(DestinationParent.DestinationParentPath) produced an error, telling me that I should simply be using %(DestinationParentPath). $(DeploymentPath) is expanded to the correct string as expected in several other places in the build.
Another source of confusion is that using %(ConfigurationToBuild.FlavorToBuild) yielded the correct value, i.e. Test, as can be seen in the following:
EDIT: this is defined under the root node Project, whereas the ItemGroup with DestinationParentPath is defined under a Target node. Does this also make a difference?
<ItemGroup>
<ConfigurationToBuild Include="Test|Any CPU">
<FlavorToBuild>Test</FlavorToBuild>
<PlatformToBuild>Any CPU</PlatformToBuild>
</ConfigurationToBuild>
</ItemGroup>
It does not seem as though the Include attribute is relevant when you're only interested in the string in the item's metadata since I'm pretty sure "Test|Any CPU" does not reference any actual file.
So once again, why is %(DestinationParentPath) expanding to an empty string?
EDIT: I forgot to mention that I also tried hard-coding the actual path for DestinationParentPath, but this still resulted in %(DestinationParentPath) expanding to an empty string.
EDIT: this is defined under the root node Project, whereas the ItemGroup with DestinationParentPath is defined under a Target node. Does this also make a difference?
Yes, it makes a difference. The ability to define an ItemGroup inside a Target is new to msbuild 3.5. Despite looking declarative, it's actually executed at runtime just as if you'd called the old style CreateItem / CreateProperty tasks. That alone leads to potential issues: you need to consider when the containing task is (first) called. Order of operations is not always obvious to the naked eye. May be wise to make the task where you use %(DestinationParentPath) dependent on the task where it's created, even if there's no "logical" dependency.
In addition, there are the age-old msbuild scoping quirks/bugs. Dynamically created properties & items are not visible to "sibling" tasks. Also, items updated in nested builds aren't always bubbled up.
Check out the workarounds in the links, you should be able to find something that works for you even if it's icky.

Resources