Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How To: Set Project-Wide #pragma Directives with JavaScript

Discussion in 'Scripting' started by MatthewW, Dec 21, 2010.

Thread Status:
Not open for further replies.
  1. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    Create a text file in the root of your project's Assets folder:

    Code (csharp):
    1. Your Project/Assets/us.rsp
    With the following:

    Code (csharp):
    1. -pragmas:strict,downcast
    Voila! No more implicit variable declaration bugs without needing to #pragma every script.

    Note that this includes the Editor/ compilation pass; if you play fast and loose with dynamic typing in editor scripts this may create more hassle than it resolves.

    Thanks to Rodrigo for the tip!
     
  2. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    Any idea if there is some way to get #defines globally like this for C#?
     
    Lohoris2 likes this.
  3. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    Why would you want it for C#?

    That's a nice trick Matthew. As a joke, I was thinking of coming in here and saying, "Yup, that's easy to do: switch to C# :p"
     
  4. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    I would love a global #define Debug rather than having to add it to every single script.
     
  5. kjems

    kjems

    Joined:
    Oct 25, 2008
    Posts:
    14
    You can add a file called smcs.rsp to the Assets/ folder. The content of the file will be added as arguments to the compiler.
    Do a 'smcs -help' to get all the options. Compiler bat location: <InstallDir>\Unity\Editor\Data\Mono\bin\smcs.bat

    If you add '-define:MyDefine' to smcs.rsp, MyDefine will be a global define for all C# scripts.
     
    Powzone likes this.
  6. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @kjems, that is awesome. I never knew about that. It appears that once you set something in the smcs.rsp file then remove it the define is still present. Do you know if there is some way to clear the cache or wherever it is storing the define?
     
  7. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    Disregard. It appears to clear itself after a few runs. Awesome tip!
     
  8. kjems

    kjems

    Joined:
    Oct 25, 2008
    Posts:
    14
    Changes to the smcs.rsp will not trigger the automatic refresh of the AssetDatabase as scripts and other assets do.
     
  9. zark2a

    zark2a

    Joined:
    Jun 28, 2011
    Posts:
    1
    JFYI - I just tried this in Unity 3.3 and smcs.rsp did not seem to work. However, I changed to gmcs.rsp (gmcs being the newer compiler, I think) and it works great! =D
     
  10. Gigiwoo

    Gigiwoo

    Joined:
    Mar 16, 2011
    Posts:
    2,981
    What does the pragma downcast do? I use the #pragma strict in every javascript, so was curious if I should use downcast too.

    Gigiwoo
     
  11. Cyrus

    Cyrus

    Joined:
    May 10, 2011
    Posts:
    4
    Any thoughts on Unity 3.4? I've tried with smcs.rsp and gmcs.rsp (and even mcs.rsp) but no luck.
     
  12. Cyrus

    Cyrus

    Joined:
    May 10, 2011
    Posts:
    4
    Sorry for double-posting; just realised that my last post was entirely unclear.

    I am also trying to set project-wide #defines for C#. I am on Unity 3.4 and have tried creating gmcs.rsp, smcs.rsp, and even mcs.rsp under the Assets folder of a project, but none of these seem to be read. I've tried "-define:TEST_DEFINE" and "/define:TEST_DEFINE". Just wondering whether anybody else had come across this since upgrading to 3.4 or if I'm just doing it wrong...

    TIA.
     
  13. Derell Nar

    Derell Nar

    Joined:
    Jan 25, 2011
    Posts:
    10
    I tried the smcs.rsp on Unity 3.4 and it works fine.
    The one thing to remember is that you should make sure to save your affected files even if there are no changes to the file.
    This is because Unity will not re-compile your code unless the Saved Date is different.

    Examle:
    if I write "-define:TEST_DEFINE" in smcs.rsp and I add

    #if TEST_DEFINE
    ....Some Code....
    #endif

    in code and save, it will work.

    if then I change the smcs.rsp file to say "-define:TEST_DEFINE_2" and run Unity it will still run the "....Some Code...." because the code in the define was previously compiled and Unity did not detect a change in the code file, so it did not bother to re-compile it.

    Once you re-save your code file (just press the save button or CTRL-S), Unity will re-compile the code correctly according to the new Defines in smcs.rsp.

    I hope this helps.
    :)
     
  14. Cyrus

    Cyrus

    Joined:
    May 10, 2011
    Posts:
    4
    Thanks, I hadn't realised that re-importing the .rcs wouldn't cause a recompile. All sorted.
     
  15. Gernot

    Gernot

    Joined:
    Aug 12, 2011
    Posts:
    1
    I got global defines running for C# using gmcs.rsp and Unity 3.4, thanks for the tip!

    Is there also a way to pass a define argument to the Boo compiler?
     
  16. Col. Phil Bilko

    Col. Phil Bilko

    Joined:
    Mar 10, 2011
    Posts:
    8
    I can not get this to work, and I am not a coder, but I am trying to get this sorted myself.... I am using Unity 3.4. In my Assets folder I have the file: smcs.rsp with the following code inside:
    Code (csharp):
    1. -pragmas:strict,downcast
    However when I quit and restart unity to get the scripts to recompile I get this errors: Internal compiler error. See the console log for more information. output was:error CS2007: Unrecognized command-line option: `-pragmas:strict,downcast'

    Basically what I am trying to do is open an old project in 3.4 and I learn't that I need to disable Dynamic typing? So I found this solution which I can not get to work for the life of me.

    Also I tried the other solution where I put #pragma strict after the vars but before the function start () example below:

    Code (csharp):
    1. private var noOfZaps : int;
    2.  
    3. #pragma strict
    4.  
    5. function Start()
    6. {
    7.     gibbing = false;
    When I do that I get these errors:

    Assets/02Scripts/GameManager.js(57,27): BCE0043: Unexpected token: ;.

    and

    Assets/02Scripts/GameManager.js(59,7): UCE0001: ';' expected. Insert a semicolon at the end.

    It is annoying when I an not a coder but I am trying to get this working all help would be very greatful!

    Thanks
     
    Last edited: Aug 13, 2011
  17. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Only if you're doing iOS/Android. Otherwise switch to web/Mac/PC publishing. (And you needed to do that for iOS/Android before Unity 3.4 anyway, the difference is that now it applies when scripts are compiled, instead of when you build the project.)

    --Eric
     
  18. Col. Phil Bilko

    Col. Phil Bilko

    Joined:
    Mar 10, 2011
    Posts:
    8
    Sorry I should of been more clear, it is an iOS game. I added "var" in front of each of the errors and it seemed to fix them. Again this is all guess work as I am not a coder hahaha

    So what would I need to do to incorporate that anyway for the iOS game to fix the old project? I read somewhere that iOS games in 3.4 automatically use #pragma strict is this true? and if so then those errors I had before need to be fixed another way? It is kinda annoying since the game worked perfect before but I needed to do an updated build to support OF 2.xx

    I have the OLD Xcode project which worked like a dream and now with xCode 4.xx it does not even load it crashes after the splash screen. So this is why I am trying to update the actual project.

    Thanks.
     
  19. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    iOS always used pragma strict automatically, now its just written there.
     
  20. mbysky

    mbysky

    Joined:
    Jul 27, 2011
    Posts:
    2
    Thanks
     
  21. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Just as a warning: This no longer works in Unity 3.5
    While it works in the editor, the builds will simply lose the defines
     
  22. jorgenpt

    jorgenpt

    Joined:
    Apr 21, 2012
    Posts:
    9
    I think dreamora might've hit some kind of caching issue - it works fine for me.

    I'm on Unity Free 3.5.2f on Mac OS X Lion. I created a simple test project, with the following script:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent (typeof (Renderer))]
    5. public class PreprocessorTest : MonoBehaviour
    6. {
    7.     void Start ()
    8.     {
    9.         Color color = Color.red;
    10. #if MAKE_PURPLE
    11.         color.b = 1f;
    12. #endif
    13.         renderer.material.color = color;
    14.     }
    15. }
    I put the following in smcs.rsp (note: I'm on Mac, and I could not get gmcs.rsp to work):
    Code (csharp):
    1. -define:MAKE_PURPLE
    I attached that script to a Cube in the scene, and started the editor. It worked fine. I then did a "PC and Mac Standalone" build for Mac OS X, "Development Build" disabled, and ran it - it turned purple as expected.

    dreamora: Maybe you need to delete Library/ScriptAssemblies or just re-save the files that you use your defines it. I'm guessing it probably had cached the compilation?
     
    Last edited: May 31, 2012
  23. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,061
    Note that it will gmcs.rsp or smcs.rsp based on wether you selected .Net 2.0 or .Net 2.0 Subset in the player settings:

    .Net 2.0 Subset: smcs.rsp
    .Net 2.0: gmcs.rsp

    Also, changing these files will not trigger a recompile. You will have to change one of your script files after editing the rsp to make the changes apply.
     
  24. iRetrograde

    iRetrograde

    Joined:
    Oct 13, 2011
    Posts:
    93
    I found this useful so I figured I'd share this here.

    http://buchhofer.com/2011/11/unity-per-project-compiler-options-unsafe/

    It goes into a bit more detail about the discussions between smcs.rsp and gmcs.rsp. More specifically:

    "More info: different compilers are used based on the language and chosen .NET profile. The subset and web profiles use smcs, the full profile uses gmcs, unityscript uses us, and boo uses booc."
     
  25. Fehr

    Fehr

    Joined:
    Mar 3, 2011
    Posts:
    23
  26. KJIB

    KJIB

    Joined:
    Jul 17, 2012
    Posts:
    7
    With the very handy "Global Define Wizard" script provided by Prime[31], I found that if (in the wizard) I disabled a define that I'd previously added it would not be picked up until something else caused a re-load of the script using the define.

    To solve this I moved these two lines in the save() routine:

    Code (csharp):
    1.         AssetDatabase.Refresh();
    2.         reimportSomethingToForceRecompile();
    3.  
    to the end of the save() routine.

    If you know you changed something, hit save. Job done.
     
    Last edited: Jul 24, 2012
  27. Esa

    Esa

    Joined:
    Mar 18, 2010
    Posts:
    39
    Can anyone confirm if this works on builds from Unity 4.0?
     
  28. Vorlex

    Vorlex

    Joined:
    Jan 10, 2013
    Posts:
    2
    Yes, it is. I've just added smcs.rsp to project containing one #define and it works.
     
  29. FWCorey

    FWCorey

    Joined:
    Feb 2, 2011
    Posts:
    42
    What about EditorUserBuildSettings.activeScriptCompilationDefines ? Can it not be added / removed from there?
     
  30. chsu

    chsu

    Joined:
    Sep 26, 2012
    Posts:
    4
    If anyone is still looking at this, seems like Unity4 has a fix.

    http://docs.unity3d.com/Documentati...ttings.SetScriptingDefineSymbolsForGroup.html


    Also changes can be done via the PlayerSettings inspector.

    *EDIT* The format is DEFINE1;DEFINE2. Make sure you don't repeat a define multiple times because the Unity build process will throw a duplicate key exception.

    And as ToxicBakery said below, you do have to hit enter if you're using the player inspector.
     
    Last edited: Feb 14, 2013
  31. ToxicBakery

    ToxicBakery

    Joined:
    Feb 14, 2013
    Posts:
    1
    Big thankyou to kjems and chsu for these tips! This used to be one of my biggest headaches with Unity.

    Just fyi in C# kjems' tip still works in 4.0
    "-define:CUSTOM_DEFINE" in smcs.rsp

    Even better though, it's great to finally see official support as chsu mentioned. Here's how you get to it in the IDE:
    Edit > Project Settings > Player > Other Settings (It's a text field labeled "Scripting Define Symbols")...

    One very minor nuance to that text field, (in this version) simply clicking away does not apply your define, you have to actually press enter after typing.
     
  32. unimechanic

    unimechanic

    Joined:
    Jan 9, 2013
    Posts:
    155
    We are improving the documentation on Custom Defines, and it's important to update these threads with the correct way of using them in the current versions of Unity. If you want to modify only global defines, you should use Scripting Define Symbols in Player Settings, because this will cover all the compilers. If you choose the .rsp files instead, you'll have to provide one file for every compiler Unity uses, and you won't know when one or another compiler is used. To do this you must add a text file with the extra directives to the "Assets/" folder:

    [table="width: 500"]
    [tr]
    [td]C#[/td]
    [td]<Project Path>/Assets/smcs.rsp[/td]
    [/tr]
    [tr]
    [td]C# - Editor Scripts[/td]
    [td]<Project Path>/Assets/gmcs.rsp[/td]
    [/tr]
    [tr]
    [td]UnityScript[/td]
    [td]<Project Path>/Assets/us.rsp[/td]
    [/tr]
    [tr]
    [td]Boo[/td]
    [td]<Project Path>/Assets/boo.rsp[/td]
    [/tr]
    [/table]

    As an example, if you include the single line "-define:UNITY_DEBUG" in your smcs.rsp file the define UNITY_DEBUG will exist as a global define for C# scripts, except for Editor scripts. Every time you make changes to .rsp files you will need to recompile for them to be effective. You can do this by updating or reimporting a single script (.js, .cs or .boo) file. All this information is being added to our documentation.
     
  33. jimmay

    jimmay

    Joined:
    Sep 23, 2010
    Posts:
    28
    Will this also allow me to override the reference to an assembly? I have an assembly that I want to include, but I want it to use an alias so I need to define -r:<Alias>=<my assembly>.
     
  34. jimmay

    jimmay

    Joined:
    Sep 23, 2010
    Posts:
    28
    It appears this doesn't work with assembly references. That's too bad.
     
  35. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    476
    Hey guys, in Unity FOUR,

    is there a way to add a disable directive:

    #pragma warning disable 414

    project wide?

    Truly appreciated .. Fattie !
     
  36. _methotec_

    _methotec_

    Joined:
    Jun 5, 2013
    Posts:
    4
    Hey is it possible to "bundle" defines in the smcp.rsp?
    I'd like to have something like
    -define:MOBILE (UNITY_ANDROID || UNITY_IPHONE ) ! UNITY_EDITOR
    But that's not working...
    I get an Unhandled Exception: System.ArgumentException: Illegal characters in path.
    This would be a great help for e.g. if we want to add more mobile platforms later on like UNITY_METRO etc.
    Has anyone figured out how to do this?
     
    Last edited: Oct 1, 2013
  37. PAHeartBeat

    PAHeartBeat

    Joined:
    Jul 11, 2012
    Posts:
    76
    Hi Any one knows how to add comments in rsp file...
     
  38. Lohoris2

    Lohoris2

    Joined:
    Aug 20, 2013
    Posts:
    85
    You could instead add platform-dependent defines, as explained in the docs now (search for "Platform Custom Defines").
     
  39. NlaakStudios

    NlaakStudios

    Joined:
    May 19, 2016
    Posts:
    12
    Ok So I am 7 year late on chipping in but I to would like #define {Whatever}.
    But anyway, for debugging I use the Development Build Tick from the Build settings box plus each class I write I add a VerboseLogging bool that defaults to false. This way in the editor DEBUG is always true, so each script will now check and see if it is supposed to Log Messages and do so if enabled. Once I have a script done and feel comfortable with it I just disable its VerboseLogging.

    See this post:
    http://answers.unity3d.com/questions/236387/is-there-any-way-to-detect-if-this-is-a-developmen.html
     
Thread Status:
Not open for further replies.