I'm trying to set up a build environment for the Mono C# compiler on my Mac. The purpose is to extend the grammar for a research project. I've struggling to set up the build. I'm sure the answer is very easy but so far I've be unable to find any useful informaiton.
I would prefer to have a solution in MonoDevelop that the grammar is part of and where any changes to the grammar is taking into account when the project compiles.
The solution file I've found so far as my only starting point includes a cs-parser.cs file which does not exist in the source drop I've gotten from the project pages. I'm guessing that this file is the result of running the parser generator on cs-parser.jay but I can't find information on how to set this up as a build step (or for that matter running the parser generator by hand)
Links to walk-throughs tutorials on how to work with the mcs would be appreciated or a simple step by step
From README.makefiles:
If your program has 'built sources', that is, source files generated
from other files (say, generated by jay), define a variable called
BUILT_SOURCES and do not list the sources in $(PROGRAM).sources:
========================================
PROGRAM = myprogram.exe
LOCAL_MCS_FLAGS = /r:System.Xml.dll
BUILT_SOURCES = parser.cs
CLEAN_FILES = y.output
include ../build/executable.make
parser.cs: parser.jay
$(topdir)/jay/jay $< > $#
========================================
executable.make will automatically delete the $(BUILT_SOURCES) files
on 'make clean'. Since this situation is a common occurrence and jay
happens to leave behind y.output files, you can also define a variable
called $(CLEAN_FILES) that lists extra files to be deleted when 'make clean' is
called. (That's in addition to your executable and the built sources).
So, cs-parser.cs is made in precisely this fashion:
[mono] ~/custom/MONO/mono/mcs/jay # make
/usr/bin/make all-local
make[1]: Entering directory `/home/sehe/custom/MONO/mono/mcs/jay'
make[1]: Nothing to be done for `all-local'.
make[1]: Leaving directory `/home/sehe/custom/MONO/mono/mcs/jay'
[mono] ~/custom/MONO/mono/mcs/jay # cd ../mcs
[mono] ~/custom/MONO/mono/mcs/mcs # make
/usr/bin/make all-local
make[1]: Entering directory `/home/sehe/custom/MONO/mono/mcs/mcs'
./../jay/jay -cv < ./../jay/skeleton.cs cs-parser.jay > jay-tmp.out && mv jay-tmp.out cs-parser.cs
./../jay/jay: 9 shift/reduce conflicts.
(reduced output)
It resulted in 10470 lines of un-user-servicable code in cs-parser.cs
Alternative, thinking out of the box:
Just a thought, can you not use a preprocessing c# -> c# converter? This has the additional benefits that you can make it work with any C# tool/compiler. Think of using #line pragmas to map back to the original source for debug information
Also, there are a number of Aspect Oriented code weavers for C#/.NET. You might leverage a combination of 1. and 2. to get the functionality you want?
Related
I am building an application for UWP in Visual Studio 2017 (it is actually a Unity game, the solution is exported from Unity). During build, I get the following warnings, and the files which are reported as such do not show up in the final appxupload file, and thus cannot be found at runtime:
1>GENERATEPROJECTPRIFILE : warning PRI263: 0xdef01051 - No default or neutral resource given for 'Files/Data/GI/level1/ca51e77bb6146d425e0c9319844929a0.vis'. The application may throw an exception for certain user configurations when retrieving the resources.
There is a warning message for the resource situation in general, which reads like this:
1>GENERATEPROJECTPRIFILE : warning PRI257: 0xdef00522 - Resources found for language(s) 'be,ca,fa' but no resources found for default language(s): ''. Change the default language or qualify resources with the default language. http://go.microsoft.com/fwlink/?LinkId=231899
The languages that are reported as such are in folders which have language iso codes (for example, in the error message, the file is actually in the folder Files/Data/GI/level1/ca/). However, these folders are NOT language specific, they are named this way due to an internal indexing scheme of Unity which I cannot change.
So, what I am asking is this: How, and where, can I configure Visual Studio or whatever part of MSBuild is responsible to NOT treat these folders as language-specific? Or is there any other solution to this problem?
Thank you.
I found a solution/workaround. Part of the build is a call to makepri.exe which creates the Package Resource Index (PRI) files which more or less contain a directory of files in the build. Makepri, by default, looks for language-named folders and splits the build along the languages it finds - which moves the language-specific files into resource packs.
Luckily, this behavior can be configured, as is described here - makepri can be instructed to just place everything in one big resource file instead of splitting up. This is achieved by editing the .csproj file, and adding the following two lines to the configuration section for Master|x64:
<AppxBundleAutoResourcePackageQualifiers>
DXFeatureLevel
</AppxBundleAutoResourcePackageQualifiers>
<AppxDefaultResourceQualifiers>
Language=en-us;de-de;es-es
</AppxDefaultResourceQualifiers>
The first tag disables auto-language qualifiers (since "Language" is MISSING from the list of qualifiers). Since languages are now no longer auto-detected, they must be explicitly listed (second tag).
I've not found a way to do what I originally wanted - specifying that certain folders should not be considered language-specific - but this works for me.
I create a project, and add a file. I can build an exe and so on, works fine.
Question is: what if I have multiple files in my project and I want to check the syntax of my code in one single file, and don't want to build an exe or dll?
When programming c, I press ctrl+F7 in the Visual Studio IDE and that compiles my code. I understand that there are no object files in c#. Microsoft c# reference states: "There are no object (.obj) files created as a result of invoking the C# compiler; output files are created directly.".
Is there a csc.exe switch to tell me 'ok your code looks fine', or 'the expression at line xx doesn't make sense'?
Note: please do not give the link to Command-line Building With csc.exe. All the sample command lines are for creating an exe or dll, from one or multiple files. Or on how to exclude a file from building. I don't want that.
The compiler is the syntax checker. It will tell you if your C# code is valid or not when it compiles it. Any errors or warnings will be available at the end of the attempted compilation. If there are none, then it's valid code.
You can individually compile any arbitrary piece of C# code any time you like. However, if that code depends on other code then in order for it to be valid that other code will need to be included in the compilation as well. Code which uses otherwise undefined symbols (such as classes defined in other code files) isn't valid. Those symbols need to be defined.
In the comments above you indicate a concern that such compilation of an entire project might take a long time. This would be addressed by organizing your code into smaller components. If you have one enormous C# project that takes a long time to compile, then what you have is a mess. Break it apart into smaller components. Each of those components can be in their own projects which can be compiled separately. Different projects will depend on each other, and dependent projects will be included in that compilation. But that dependency graph also shouldn't be too large and unwieldy. If it is, you still have a mess but just on a different scale. Keep the dependency graph shallow and maintainable between your projects.
Sort of answering my own question. When I posted this I wasn't aware that splitting definition and implementation in c#, as you did in c or c++, was not possible. https://social.msdn.microsoft.com/Forums/en-US/64800602-4ff2-4747-8c42-a4e1980d4124/c-no-header-files-all-code-is-written-inline-why?forum=csharplanguage states that Interfaces do this, but not in a way I asked in the original post. Looks like in a multi file project, only the IDE gives me this piece of information (syntax checking), other than building the whole project.
It appears that ctrl+F7 on a single file (Visual Studio), or -c or -fsyntax-only switches (on gcc) are not possible with c#.
It was a long WTF moment and I could not find any information on the issue, so I decided I put it here.
Setup: Windows 7 x86_64, sonarqube-4.3, sonar-runner-2.4, jre 1.7.0_55-b14
I followed quick start guide to configure Sonar.
I copied sonar-project.properties from a sample to my solution, put it in the directory with .sln, and made necessary adjustments:
sonar.projectKey=org.whatever.project
sonar.projectName=Project
sonar.projectVersion=2.0
sonar.sourceEncoding=UTF-8
sonar.sources=.
sonar.visualstudio.enable=true
Problem: Analysis ran without any exceptions but only C# files were analyzed.
Long story short, following line in config was causing the issue:
sonar.sources=.
After moving sonar-project.properties one level up and changing it accordingly, the problem was resolved.
sonar.sources=src
I think it actually relates to the usage of the Visual Studio Bootstrapper. Can you try the same without it?
Here is what happens: The Visual Studio bootstrapper reads all the <Compile> tags from the *.csproj files to determine which files must be imported. Javascript files are not referenced by <Compile> (as they do not need to be compiled), and will therefore not be imported in SonarQube.
See this related Jira ticket: https://jira.codehaus.org/browse/SONARVS-27
I have a C# solution with an Antlr3 grammar file, and I'm trying to upgrade to Anltr4. It turns out the grammar was the easy part (it became better, and one third the size!). Generating the parser turned out to be the tricky part.
In the old solution I merely ran AntlrWorks to update the lexer and parser .cs files when the grammar file changed. The lexer and parser were included directly in the same project as the grammar so the framework around the parser could make use of them directly.
With the Antlr4 targets for C# I noticed that (at least by default) the output path of the generated Parser C# classes is in the intermediate directory, e.g. obj\Debug. This means I can't use the parser directly in the same project. Am I supposed to change the output path if I want the generated source usable in my sln? Don't I want it in my sln?
I tried making a separate project for the parser generation, that is, a project containing only the grammar file. When this project is built using the Antlr4 targets, the resulting assembly can be referenced from projects needing the parser classes. However, if this project is included in the solution I still don't get any intellisense in visual studio since it bases its intellisense on source files for loaded projects, so it is still not quite usable. The only way I could get it working properly was to build then unload the parser project, and have other projects reference it as an assembly file rather than a project.
EDIT:
After looking on the antlr-interest list I found this thread indicating that the problem with intellisense may be Resharpers fault. If this is the case, then my question is rather how to keep using both Antlr4 and Resharper in my solution?
https://groups.google.com/forum/#!topic/antlr-discussion/QSuJXphaBDg
I found an extension for Resharper: ReSharper.ExternalCode.
Tip for Antlr: add obj\Debug in Resharper -> Code Inspection -> External Code and reload solution.
It's works for me.
There is an easy way to get the best of both Antlr 4 and Visual Studio. You are on the right track in having a separate grammar project and implementation project, but you are missing a couple steps.
Follow these steps to get the Intellisense working
In Visual Studio, go to Tools -> Extensions and Updates and search the Online section for "ANTLR Language Support" by Sam Harwell.
This does a few things:
Adds Templates for the combined grammars.
Adds Syntax Highlighting
Adds an MSBuild target for the grammar to generate the parser.
In your solution, set up your project structure like this:
Solution
Grammar Project
ANTLR 4 Combined Grammar
Implementation Project
Folder for Links to Generated files
Listener Implementation Class
Write and Compile your grammar.
In your folder for the Links to Generated Files, Right-Click the folder and click Add -> Existing Item
Browse to Grammar Project\obj\Debug and select all the generated parser files.
This next step is important. On the Add button there is a little drop-down arrow. Click the drop-down arrow and click "Add As Link".
This will add the generated files to the implementation project using a symbolic link instead of a direct copy.
This gives the added benefit of not having to remove and re-add the parser files if you have to change your grammar later.
Intellisense should work now for your generated parser classes, and you don't
even have to disable ReSharper.
You are encountering a known bug with ReSharper. The ANTLR 3 and ANTLR 4 C# build integration is reliable, and uses long-established patterns that Microsoft uses with other languages and code generation tasks. Your options are:
Stop using ReSharper
Get the ReSharper authors to address the lack of support for this feature, or
Modify the ANTLR 4 target to work around the limitation in ReSharper, which will introduce other problems into the build which may or may not be acceptable for your use.
Option 1 is certainly the least expensive, and most likely to provide reliable long-term support for your projects.
We have a moderately sized solution, with about 20 projects. In one of them I have my business entities. On compiling any project, visual studio waits and hangs about one and a half minutes on this BusinessEntities project.
I tried our solution in SharpDevelop and it compiles our complete solution, in 18 seconds. Similar timing with MSBuild.
My guess is that VS is trying to find out if the project needs a compile, but this process is about 15 times slower than actually performing the compile!!
I can't switch to the great sharpdevelop, it lacks some small, but essential requirements for our debugging scenarios.
Can I prevent VS from checking this project, And have it compile the projects without such a check, just like sharpdevelop?
I already know about unchecking projects in configuration management to prevent building some projects, but my developers will forget they need to compile this project after updating to latest sources and they face problems that seem strange to them.
Edit: Interesting results of an investigation: The delay happens to one of the projects only. In configuration manager I unchecked all projects, then compiled each of them individually. All projects compile in a few seconds!! The point is this: if that special project is built directly, compiles in a few seconds, if it is being built (or skipped, because it is up-to-date) as a result of building another project that depends on it, VS hangs for about a minute and half, and then decides to compile it (or skip it). My conclusion: Visual studio is checking to know if any files are changed, but for some reasons, for this special project it is extremely inefficient!!
I'd go to Tools -> Options -> Projects and Solutions -> Build and Run and then change the "MSBuild project build [output|build log] verbosity" to Diagnostic. At that level it will include timings which should help you track down the issue.
We had the same problem with an ASP.NET MVC web project running in Visual Studio 2013. We build the project and nothing happens for about a minute or so and then the output window shows that we are compiling.
Here's what fixed it... open the .csproj file in a text editor and set MvcBuildViews to false:
<MvcBuildViews>false</MvcBuildViews>
I had to use sysinternals process monitor to figure this out but it's clearly the cause for my situation. The site compiles in less than 5 seconds now and previously took over a minute. During that minute the Asp.net compilation process was putting files and directories into the Temporary Asp.net Files folder.
Warning: If you set this, you'll no longer precompile your views so you will lose the ability to see syntax errors in your views at build time.
There is the possibility that you are suffering from VS inspecting other freshly built assemblies for the benefit of the currently compiling project.
When an assembly is built, VS will inspect the references of the target assembly, which if they are feshly built or new versions, may include actually loading them in a .Net domain, which bears all the burdens of loading an assembly as though you were going to run it. The build can get progressively slower as it rebuilds more and more projects. When one assembly becomes newer the others do a lot more work. This is one possible explanation for why building by itself, versus already built, versus building clean, all have seemingly relevantly differing results. Its really tht the others changed and not about the one being compiled.
VS will 'mark down' the last 'internal' build number of the referenced assembly and look to see if the referenced assembly actually changed as it rolls through its build process. If its not differnt, a ton of work gets skipped. And yes, there are internal assembly build numbers that you dont control. This is probalby not in any way due to the actual c# compiler or its work or anything post-compile, but pre-compile steps necessary for the most general cases.
There are several reference oriented settings you can play with, and depending on your dev, test, or deployments needs, the functional differences may be irrelevant, however may profoundly impact how VS behaves and how long it takes during build.
Go to the references of one of the projects in Solution Explorer:
1) click on a reference
2) open the properties pane if its not (not the Property Pages or the Property Manager)
3) look at 'Copy Local', 'Embed Interop Types', 'Reference Output Assembly'; those may be very applicable and probably something good to know about regardless. I strongly suggest looking up what they do on MSDN. 'Reference Output Assembly' may or may not show in the list.
4) unload the project, and edit the .proj file in VS as text. look for the assembly reference in the XML and look for 'Private'. This means whether the assembly referenced is to be treated as though its going to be a private assembly from the referencing assemblies perspective, vs a shared one. Which is sort of a wordy way of saying, will that assembly be deployed as a unit with the other assemblies together. This is very important toward unburdening things. Background: http://msdn.microsoft.com/en-us/magazine/cc164080.aspx
So the basic idea here is that you want to configure all of these to be the least expensive, both during build and after deployment. If you are building them together, then for example you probably really don't need 'Copy Local'. Id hate to say more about how you should configure them without knowing more about your needs, but its a very fine thing to go read a few good paragraphs about each. This gets very tricky however, because you also influence whether VS will use the the stale old one when resolving before the referenced one is rebuilt. As a further example explaiing that its good to go read about these, Copy Local can use the local copy, even though its stale, so having this set can be double bad. Just remember the goal at the moment is to lower the burden of VS loading newly built assemblies jsut to compile the others.
Lastly, for now, I can easily say that hanging for only 1.5 mins is getting off very lucky. There are people with much much worse build times due to things like this ;)
Some troubleshooting idea's that have not been mentioned:
Clean solution?
Delete Obj and Bin folders plus the .suo file? FYI, neither Clean nor Rebuild will delete non-build files, eg files copied during a pre-build command.
Turn off VS scanning outside files. Options > tools > environment > document > detect when file is changed outside the environment?
Rollback SVN history to confirm when it started to occur? What changed? If the project file on day 1 takes the same time, recreate the project, add all the files and build.
Otherwise could you please run Process Monitor and let us know what Visual Studio is doing in the prep-build stage?
Sounds silly, but remove all breakpoints first. It sped up my pre-build checks massively - still don't know why though.
Based on the (limited) information provided one possibility is that there could be a pre-build action specified in the project file that is slow to compile.
Try disabling platform verification task as described here.
If your individual projects are compiling correctly then all you can do is change order of compilation by setting dependent projects explicitly in configuration.
Try to visualize your project dependency hierarchy and set dependent projects. For example, if your business entities project is referenced in each project, then in configuration of each project, this project must be selected as dependent.
When an explicit build order is not set, visual studio is analyzing projects to create an order of building project. Setting explicit dependent projects wiki make visual studio skip this step and use the order provided by you.
With such an extreme delay on a single project and no other avenue seeming to provide a reason I would attempt to build that specific project while running procmon from sysinternals and filter out all the success messages. You could probably also narrow it down to just the file system actions as well. From your description I might guess that the files are being locked by an external source like the event collection or workflow management process services.
Other things to consider would be whether or not this is a totally clean build machine or if it has been used to perhaps test the builds as well? If so, is there a chance that someone mapped an IIS application path to the project directly or registered it as a service location?
If you run procmon and see no obvious locks or conflicts I would create a totally new solution and project and copy the files over to see if that project also has the same delay. If it does have the same delay I would create a sample project of the same type but generic data (essentially empty) and see if that too is slow. If the new project with the same files builds fine you can then diff the directories to see what the variance is that causes the problem (perhaps a config or project setting).
For me, thoroughly disabling code analyzers helped per instructions here:
https://learn.microsoft.com/en-us/visualstudio/code-quality/disable-code-analysis?view=vs-2019#net-framework-projects.
I thought my code analyzers were already off, but adding the extra xml helped.
Thanks Kaleb's for the suggestion to set "MSBuild project build [output|build log] verbosity" to Diagnostic. The first message took more than 10 seconds to display:
Property reassignment: $(Features)=";flow-analysis;flow-analysis" (previous value: ";flow-analysis") at C:\myProjectDirectory\packages\Microsoft.NetFramework.Analyzers.2.9.3\build\Microsoft.NetFramework.Analyzers.props (32,5)
Which led me to the code analyzers.
Just in case someone else trips into this issue:
In my case the delay was being caused by an invalid path entry in "additional include directories" that referred to a non accessible UNC location.
Once this was corrected, the delay disappeared.