C# - Code compiler for .NET & CF.NET
Asked Answered
G

4

4

I've a same project that need to be compiled with .NET and Compact .NET Framework.

  1. It is possible to create a C# compiler that will compile my project with both framework ?
  2. Some feature aren't present in CF.NET Framework so I created it by myself (creating classes having exactly the same name & options that in .NET Framework. If I decore this classes with an attribute like [CF35] it's possible to parse the project and :

    • Use this class when compile the project using CF.NET
    • Ignore this class when compile the project using .NET

?

Thanks for all constructive answers.

[EDIT]

I know the solution that consists to create two projects referencing the same files. Problem is, you should every time compile both manually. Moreover, when you add a file to one, you need to open the second and reference it too, that it's just borring to do and according that we are many people to work on the same project, I would like to do this part automatically.

Seems to be possible?


[EDIT 2] All works fine except ... resources files !

So, to resume, I've three project :

  • the development project (CF.NET)
  • the release project (CF.NET 3.5), including all files via ""
  • the release project (NET 3.5), including all files via ""

As said, all works fine, but now my problem is using Resources files.

What's the method to apply to use it?

  • When I use the development project, Resource file is correctly retrieved
  • When I use the two other projects, ResourceManager throws MissingManifestResourceException

Any idea?

Germano answered 24/2, 2011 at 18:45 Comment(0)
I
4

The basic idea would be to decorate your code with #if compiler directives for each framework version?

#if CFNET
// .net CF code
#else
// .net code
#endif

From here one you have two options:

A) 1 project file with custom build configurations

If you would like to have everything in 1 csproj file you'll need to modify it manually. Since this is a msbuild file this is more of a msbuild problem. I figure you would need to do the following things:

  1. Use 2 platform names say "NET" and "CF" (instead of the default Any CPU or x86)
  2. Define CF constant (From now on Edit csproj):

    <PropertyGroup Condition="'$(Platform)' == 'CF'"> <DefineConstants>CF</DefineConstants> </PropertyGroup>

  3. Import correct build targets depending on selected platform:

    <Import Condition="'$(Platform)' == 'NET'" Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Condition="'$(Platform)' == 'CF'" Project="$(MSBuildToolsPath)\<CFtargets>.targets" />

    I don't know the targets file name of CF since I don't have it installed. It sould be somewhere in C:\Windows\Microsoft.NET\**.targets

B) 2 project files each containing the appropriate build configuration

As I initially pointed out, and also some commenter pointed out, the best solution is to have 2 project files, that you keep in sync. You can have the same source files in both project files.

So an idea would be (instead of copying the file list manually each time) to

  1. think about using T4 templates, to keep the source files in sync (and have 2 solutions, so you wouldn't be prompted to reload the whole solution each time) or to
  2. modify the two csproj files and use a wildcard compile tag like this:

    <Compile Include="**/*.cs"/>

Indraft answered 24/2, 2011 at 18:56 Comment(5)
That implies to have two projects and when adding a file to project, you need to add it to other too but manually (and manually compile both each time), and that can be a problem. But original question isn't answered, I would like to do it automatically.Germano
Added some ideas for msbuild configurationIndraft
So idea is, I have a project (using directives like said above) and compile it (with CF.NET), and then have a program that will copy all that project, modify the csproj file (more secure passing by a copy). And then compile this project too (with .NET this time bye using the new csproj file). It's okay for me, so can I create a program that will do all that stuff automatically (copy / modification / compiling) ?Germano
No, the idea is to have 1 project (or solution as a matter of fact) and modify the project's csproj file, so that you can have 2 build configurations, and switch between them from within Visual Studio.Indraft
Having been down this road many, many times, I can say that a single project file for CF and FFx is a bad idea. The idea might sounds good, but the reality of implementation just doesn't pan out. Create two separate project files. Yes, you occasionally have to edit to keep them in line, but it's by far the most maintainable solution. BTW, you can manually edit the project file to include all code files in a directory, which can save a lot of that editing.Traceytrachea
B
6

You'll need to create different build configurations for each and define a custom flag like USE_CF. Then wrap your custom classes with #if USE_CF and #endif so they get ignored when compiling without that flag

Burbot answered 24/2, 2011 at 18:54 Comment(2)
+1. It may be even better to get all CF-special classes into single assembly and conditionally refernce it (you'll need to manually edit csproj file, to add condition on the reference AFAIK).Montfort
this solution is a single project - just two different build configurations for it. dotnetperls.com/if-elif-endifBurbot
I
4

The basic idea would be to decorate your code with #if compiler directives for each framework version?

#if CFNET
// .net CF code
#else
// .net code
#endif

From here one you have two options:

A) 1 project file with custom build configurations

If you would like to have everything in 1 csproj file you'll need to modify it manually. Since this is a msbuild file this is more of a msbuild problem. I figure you would need to do the following things:

  1. Use 2 platform names say "NET" and "CF" (instead of the default Any CPU or x86)
  2. Define CF constant (From now on Edit csproj):

    <PropertyGroup Condition="'$(Platform)' == 'CF'"> <DefineConstants>CF</DefineConstants> </PropertyGroup>

  3. Import correct build targets depending on selected platform:

    <Import Condition="'$(Platform)' == 'NET'" Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Condition="'$(Platform)' == 'CF'" Project="$(MSBuildToolsPath)\<CFtargets>.targets" />

    I don't know the targets file name of CF since I don't have it installed. It sould be somewhere in C:\Windows\Microsoft.NET\**.targets

B) 2 project files each containing the appropriate build configuration

As I initially pointed out, and also some commenter pointed out, the best solution is to have 2 project files, that you keep in sync. You can have the same source files in both project files.

So an idea would be (instead of copying the file list manually each time) to

  1. think about using T4 templates, to keep the source files in sync (and have 2 solutions, so you wouldn't be prompted to reload the whole solution each time) or to
  2. modify the two csproj files and use a wildcard compile tag like this:

    <Compile Include="**/*.cs"/>

Indraft answered 24/2, 2011 at 18:56 Comment(5)
That implies to have two projects and when adding a file to project, you need to add it to other too but manually (and manually compile both each time), and that can be a problem. But original question isn't answered, I would like to do it automatically.Germano
Added some ideas for msbuild configurationIndraft
So idea is, I have a project (using directives like said above) and compile it (with CF.NET), and then have a program that will copy all that project, modify the csproj file (more secure passing by a copy). And then compile this project too (with .NET this time bye using the new csproj file). It's okay for me, so can I create a program that will do all that stuff automatically (copy / modification / compiling) ?Germano
No, the idea is to have 1 project (or solution as a matter of fact) and modify the project's csproj file, so that you can have 2 build configurations, and switch between them from within Visual Studio.Indraft
Having been down this road many, many times, I can say that a single project file for CF and FFx is a bad idea. The idea might sounds good, but the reality of implementation just doesn't pan out. Create two separate project files. Yes, you occasionally have to edit to keep them in line, but it's by far the most maintainable solution. BTW, you can manually edit the project file to include all code files in a directory, which can save a lot of that editing.Traceytrachea
P
4

There's only one C# compiler, it emits the exact same IL for whatever platform. What's different are the reference assemblies, you have to use the CF versions for the project that targets CF, the desktop versions for the project that targets .NET. Which requires two projects. They can reference the same source code files. Adding CF-only source code files is now of course no longer a problem.

Keeping projects in sync is a feature available in VS2010. Intended for Silverlight, pointless for a CF project of course since it no longer supports it.

Pilotage answered 24/2, 2011 at 19:20 Comment(0)
P
3

a better way is to create your normal project class library (.NET) and add all of your code. Then create your second class library project (.NET CF) but reference the code files from the first project (not copy, but reference). Then you end up with 2 DLL's and you don't have to deal with nasty ugly compiler directives. You get the result you want with no extra work to maintain both projects. Obvisouly you would need to be careful with what you put in the code since .NET CF is limited compared to .NET. I don't know how to add file references (shortcuts) using visual studio but I open the proj file in notepad and use relative paths to the files to include. I've used this method for .NET/.NET CF and also .NET/Silverlight

Also, have a look at Portable Library Tool CTP http://visualstudiogallery.msdn.microsoft.com/b0e0b5e9-e138-410b-ad10-00cb3caf4981/?localeName=ko-kr

Pedagogue answered 24/2, 2011 at 23:47 Comment(3)
When you use "Add Existing Item" there's a little drop-down arrow next to the Add button that you can select and it will give "Add as link" as an option. That will prevent the file copy and use a file reference.Traceytrachea
I know this tip, but as said, that implies to have two different project to rebuild each time and that can be a source of error... (as said in my edit ;))Germano
how exactly can it be a source of error? You still need to generate dlls for both types of projects and there is a single code base. If you have specific code for CE then you should put it in the CE project. You're setting yourself up for massive headaches using compiler directives in a single project. There is no good reason to do it that way. Plus, you STILL have to write the code twice. At least with file references you only write the code once.Pedagogue

© 2022 - 2024 — McMap. All rights reserved.