microsoft / vscode-arduino

Visual Studio Code extension for Arduino
Other
1.15k stars 203 forks source link

multiple source files support #271

Open shizn opened 7 years ago

shizn commented 7 years ago

In the Arduino workspace folder, programmers might breakdown their main ino files into different header files and c/cpp/ino files. But currently, the extension is not working well in this situation. Since the build/verify part is based on the Arduino IDE, I assume this part is OK. We need to think about how to better integrate our scenario with the cpp extension.

yaohaizh commented 7 years ago

Not quite sure about what want to achieve for this feature.

Either for C/C++ or Arduino projects, it will always have a main entry file a the starting compilation unit: main/DllMain/setup,setup. etcs yet you can have multiple source files in the workspace.

shizn commented 7 years ago

Let me provide more details later. :) perhaps it's more about a get started doc.

rei-vilo commented 7 years ago

AFAIK, a project has one .ino file and all other files are either .h or .cpp.

The only notable exception is Energia Multi Tasking based on RTOS with as many .ino files as tasks.

svq98 commented 7 years ago

In arduino ide, you can have multiple tabs, each tab is an ino file. when you compile it will assemble all those into one large cpp file. I have a simple project with a main file and the the secondary file as a tab. When I verify, it does not pick up the the second file and fails to compile:

`C:\Users\mn\Documents\Arduino_gw\gateWayV2\gateWayV2.ino: In function 'void loop()':

gateWayV2:192: error: 'cmdProc' was not declared in this scope

     cmdProc(inChar); // int enabled after reading a char`

cmdProc is another ino file

This should be classified as a bug, since I am unable to compile the project. I would be happy for a workaround.

lollotek commented 7 years ago

@svq98 Try this as workaround:

I also needed to change the order of some functions to make theme 'reachable' before someone calls these

czgtest commented 6 years ago

@Sneezry , Can you help to investigate?

delasource commented 6 years ago

@lollotek ok this works. But file has to be named .h

riccoyudha commented 5 years ago

I haven't found a way yet to seamlessly use VS Code to compile my Arduino project with multiple .ino files in a single directory.

However, the best way that I have found out to increase my workflow and to avoid gibberish Arduino IDE UI/UX is actually using VSCode as a text editor and use Arduino IDE to upload.

What you need to do :

  1. In Arduino IDE, select File -> Preferences -> Check "Use External Editor"
  2. In VS Code, select the folder you are working on and just code as usual
  3. If you are ready to upload your code, go back to Arduino IDE and press the upload button

Eventually, Arduino IDE will reload the latest update on the .ino files before it uploads to your board.

Hope this helps.

IanBellomy commented 5 years ago

I can't get an existing project to verify or compile when using @lollotek's work-around.

Many peculiar issues where a function, const, or variable declared in a secondary file can't be found when used in that same file.

Are you just changing back the extensions when you go to build?

joaomcarlos commented 5 years ago

I have been using .h and .cpp external files but I reached a point where its just too confusing and I am dealing with a problem where I have errors for multiple included files when using a library and although I seem to have done all the steps correctly.

What I would like is not to have to deal with linkers, .h, .cpp and just use .ino files to split my code, I dont need the extra features of .h and .cpp just need a shared global file composed of several small ones just like Arduino editor.

How can I achieve this?

a7hybnj2 commented 4 years ago

I have tried several ways to get this to work but if I declare all my globals and #defines in the main.ino file and I #include the otherfiles.h that use the declares then they don't link correctly and I get a ton of errors.

From the arduino IDE all the files were .ino and they were I think compiled into one .c file so all the declares and globals worked in all the sub .ino files.

adamm commented 4 years ago

@a7hybnj2 I had the same issue. Pulling my hair out, I found that VSCode (1.31.9) was persistently passing the wrong file to /Applications/Arduino.app/Contents/Java/arduino-builder.

Check your "OUTPUT" tab, lines 7 and 8 for the arduino-builder string. Scroll to the end of the line.

Normally, this should be the .ino as the last argument of arduino-builder (yes, my .vscode/arduino.json sketch attribute was set to the correct INO) but for whatever reason VSCode kept trying to compile the first file alphabetically in my source tree. In my case, it was a config.h.

Simply renaming my INO to be the first file in my source tree solved the problem.

Obviously this seems like a unique bug but i only ended up finding this when i had multiple INOs in my source tree.

a7hybnj2 commented 4 years ago

@adamm I really wanted this to be the issue but it seems that they have fixed that since it appears that the compiled ino is always the one listed in the arduino.json file despite its order among the other .ino files.

githubDLG commented 4 years ago

@a7hybnj2 seems i had the same issue as you. the main.ino(which include setup() and loop, as the main ino file of the whole arduino project) #include config.h, then the declares and globals that defined in config.h could be correct recognised by main.ino, but for the other ino , these declares and globals are act as non-existent..... do you suffered the same issue?

TotallyInformation commented 4 years ago

This is still an issue. Along with the fact that none of the "standard" .h files are found without manually configuring them (I use a portable installation) and the fact that you cannot use the Windows Store version make this extension unusable I'm afraid. I really hoped it would work.

Some of us are not native C/C++ programmers. If we were, we would probably be using PlatformIO.

tomjuggler commented 4 years ago

I'm afraid that if you expect anyone used to the Arduino IDE to be able to use this plugin for anything non-trivial, sketches with multiple .ino files need to be supported. The Arduino:initialize even asked me to "select the main sketch file"! I have wasted valuable time working on the assumption that "main" means there is a recognition of "sub sketch files" as Arduino IDE has. All that's needed is to join the .ino files prior to compilation, starting with the main sketch. I'm sure that's all the Arduino IDE is doing.

alka79 commented 3 years ago

Same issue here. I want to migrate a multiple files ESP8266 project to VSCode with Arduino extension. PlatformIO is too complex for me. My project compiles and runs in VSCode, which is good but I face many issues with Intellisense. I finally found how to make it work. See edit below.

I would be happy if anyone knows an "official" tutorial on how to migrate a non-trivial Arduino IDE project to VSCode-arduino.

My goal is to be able to use either VSCode or Arduino IDE , so no disruptive change allowed in the code organization. I use windows 10, latest Arduino 1.8.13 and latest VSCode 1.5.1.1..

The project is split in multiple INO files. It uses Arduino managed librairies and project local libs, located in a /src subfolder. INO files in the folder are in alphabetic order : A.INO, B.INO, . . . . , Y_SETUP.INO has the setup() and Z_LOOP.INO has loop(). A.INO is the first loaded by Arduino IDE. It contains globals , defines, libs includes and functions declarations (prototypes). The actual code of the functions is in the other INO files. setup() and loop() are loaded last. This works fine in Arduino IDE.

Migration to VSCode required lots of search for me as I am new to VSCode. It appears that only some minimal changes are required in arduino.json and c_cpp_properties.json. I declare A.INO as main sketch. See files below. The project compiles, uploads and runs fine with VSCode-arduino :-)

Hower Intellisense gets lost ! Arduino specific keywords are recognized. The classes from libs included in A.INO are recognized, even my included local libs. The globals and functions defined in the currently opened file are recognized, but ....no global or function declared in another file are recognized by intellisense :-( This leads to a lot of false errors.

I have seen the work going on here #1107 . Not sure if it will help. Unfortunately install fails with latest VSCode.

edit: One more thing.... I finally found a "hack" solution : add "${workspaceFolder}/A.ino" to "forceInclude". There are still some errors that I need to investigate, but it works mostly OK now. 👍 Amazing that "${workspaceFolder}/**" in the includePath is not sufficient.

edit 2: added "defines" to c_cpp_properties.json

Al

My current source code organisation :

a_project/_functions.ino
         /_moreFunctions.ino
         /_evenMoreFunctions.ino
         /a_project.ino              <- Declared as sketch in VSCode arduino.json
                                        Same name as folder makes it the main file for Arduino IDE
         /b_setup.ino                <- Has the setup() function
         /c_loop.ino                 <- Has the loop() function
         /src/                       <- Folder with the local libs. Must be named src/ otherwise Arduino IDE complains

a_project.ino has all the #defines, #includes, globals definitions and all functions declarations (prototypes). The Arduino core libs and Arduino managed libs are in the default folders.

.VSCode files: (note that using \\ or / in the path works, even on windows)

c_cpp_properties.json
{
       "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:\\Users\\Al\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\**",
                "C:\\Users\\Al\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\**",
                "D:\\Al\\Documents\\Arduino\\libraries\\**"
            ],
            "browse": {
                "limitSymbolsToIncludedHeaders": false
            },
            "forcedInclude": [
                "C:/Users/Al/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/cores/esp8266/Arduino.h",
                "${workspaceFolder}/a_project.ino"
            ],
            "defines": [
                "ARDUINO=1000",
                "USBCON"
            ],
            "intelliSenseMode": "msvc-x64",
            "cStandard": "c17",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}
arduino.json
{
    "board": "esp8266:esp8266:nodemcuv2",
    "configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,led=2,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600",
    "port": "COM3",
    "sketch": "a_project.ino",
    "output": "D:/Temp/vscode_builds/a_project"
}
julesgilson commented 3 years ago

So this issue has been open for 3.5 years....

I have tried to make this extension work a few times - wasted a lot of time. I wanted to avoid PlatformIO as I used VSC all day for work and PlatformIO is bloated.

There are so many issues with this extension that I can't see it ever becoming a tool anyone can use for anything other than simple single file projects.

To be honest some of the issues relate to the mess that is the Arduino ecosystem - missing includes deep in libraries etc. However, the Arduino IDE works its way around these issues - this extension does not. What this means is that every project I have opened in it required hours of fixing issues/creating work arounds.

Given 3.5 years, if they can't even make it replicate core functionality of Arduino by concatenating all .ino files before compiling then there isn't much hope.

It is a shame - something like this (that works) is needed in VSC - this isn't it sadly.

alka79 commented 3 years ago

Not sure what your problems really are, but I consider my project being far from simple. It is an ESP8266 project with multiple .ino files, local libs and libs managed by Arduino IDE.

Even if not perfect yet, VSCode-arduino is a huge improvement over Arduino IDE for me. The benefits are worth the effort to restructure and clean the code if needed.

Maybe genuine arduino libs are not built as well as ESP8266 code. If that is the problem, there is not much IMHO the VSCode-arduino team can do. Hopefully the long awaited Arduino-Pro IDE will help with better Arduino legacy support.

The trick for me was a proper source file naming and structure to please both VSCode and Arduino IDE. I did not have to make any change in the source code itself, nor to any library.

The code loads perfectly in both Arduino IDE and VSCode-arduino with the above decribed c_cpp_properties.json and arduino.json. Intellisense, compile and upload work fine.

bigFin commented 3 years ago

The source code organization suggested by @alka79 works for me. I don't need to use any #includes referencing the other source code files in the A_PROJECT.ino file.

This is a BIG win. IMO.

julesgilson commented 3 years ago

I have many problems, best limit it to Arduino here 😄

When I said that such an extension was needed as this wasn't it, I wasn't very clear. What I meant was a direct alternative to the Arduino IDE. The Arduino IDE did away with header files and defining prototypes to keep things simple (I assume) - and handled all this by good use of the build commands. The editor, sadly is terrible, so it would be good to have the same functionality within a decent editor such as VSC.

I don't really agree that this should be closed. Yes, you can find work arounds if you know a bit about C++ architecture - but that leads to bad coding which is neither Arduino nor C++. And that's if you know how to do that - I would wager a lot of Arduino users do not.

Getting intellisense to work has nothing to do with the Arduino extension - that is all done by VSC and the C++ extension. The c_cpp_properties.json is a config for that not Arduino. I use the same extension for my work. What I would expect an Arduino extension to do is to build the right includes for it, and create the correct build instructions for the compiler - without the user having to intervene. This is what the Arduino IDE does well. In the case of multiple source files - it simply concats them together in an alpha order before compiling. (You can see this if you look at the temp files it creates).

I could not get that to work.

Even if I start putting a C++ structure into it with header files and definitions I still get problems: vsc_arduino_includes

As you can see, intellisense has no problem finding the include - but it is not being sent correctly to the compiler.

It is also not picking up the pin defs file for the hardware: Clipboard01

To fix that problem I need to add the correct include to the specific variant - even though I have told the extension which board to use.

I guess my point is, if you are going this far to make it work then it would be better to use PlatformIO which has many advantages. I was hoping this extension would be more of a drop in replacement for the Arduino IDE for those that cant (or cant be bothered) figuring out how to make it work.

alka79 commented 3 years ago

I agree that this issue should not be closed. At best, I consider I provided a suggestion for a work-around. VSCode-arduino could be much smarter. For example, force load includes in c_cpp_properties.json should not be required. Also, some documented non-trivial examples would be welcome.

@julesgilson : you changed your code quite a bit. IMHO, it is unecessary and creates new issues. PlatformIO requires this kind of changes to the code and that is precisely the reason why I did not want to move to that extension.

The Arduino IDE did away with header files and defining prototypes to keep things simple (I assume) - and handled all this by good use of the build commands.

Not in non-trivial projects. For example, if you dont name your files properly in a multifile project (multiple tabs) it won't compile. Also, not properly declare function prototypes leads to issues even in Arduino IDE. Beeing too permissive leads to hard to find issues. I lost hours on some ;)

My point here is , even if Arduino IDE is very permissive, there are some rules to follow with non-trivial projects. Except the fancy Arduion file name convention, the rules are mostly good practice in C/C++. I did not have to break these rules to use VSCode-arduino, nor to add new rules. Just put the right paths in c_cpp_properties.json and arduino.json.

Arduino Pro IDE is supposed to fill the gap with both legagy Arduino IDE support and state-of-the-art editor. Potentially a "drop-in" replacement. If it ever gets out of alpha stage!

alka79 commented 3 years ago

On another project, I found this piece code in a librairie:

#if ARDUINO >= 100
#include <Arduino.h> 
#else
#include <WProgram.h> 
#endif

This is to maintain code compatibility with older versions of Arduino, prior to 1.00 VSCode got completely confused with missing Wprogram.h. It seems ARDUINO is not defined.

Two options:

The above post https://github.com/microsoft/vscode-arduino/issues/271#issuecomment-727564776 with my suggested c_cpp_properties.json is updated.

julesgilson commented 3 years ago

After some experimenting I find (so far) that so long as the .ino file are named alphanumerically in the required order and no other files break that sequence - it will compile fine. You can check the output of the pre-processor in the preproc folder. You will need to add an output path for this to be found easily, which is another thing that should be documented clearly. Adding the following line to the arduino.json extension config file will achieve this (I set it to a directory in temp):

"output": "<path\\to\\output\\directory"

The problem I was having was that my header files were named to match up with the ino files like:

a_main.ino
a_main.h
b_next.ino
b_next.h

so the header files were "in the middle" of ino files when considered alphanumerically. Changing it to:

1_main.ino
2_next.ino
3_main.h,
4_next.h

fixed the issue.

The rest of the issues I have seen are related to intellisense, so don't effect the compiler but of course intellisense is the main reason to use VSC.

You can clear all these issues by adding the right include paths to the cpp properties file (if you can find them!) - but, in my opinion, for hardware includes that really should be done for you by this extension. You tell it which board, so it should then build the correct include paths for that board. It does add some, but not all needed.

Additionally, I believe that the intellisense mode should be gcc - as the Arduino/Atmel compiler is a gcc compiler. By default cpp will set the mode to MSVC on a Windows machine and the extension does not update that for you.

"intelliSenseMode": "gcc-x64"

The latest version of this extension automatically now inserts the USBCON define in cpp properties.

Jules.

marcio-pessoa commented 1 year ago

Hi dears.

The expected behavior using additional .ino files is described in the documentation:

All .ino and .pde files in the sketch folder (shown in the Arduino IDE as tabs with no extension) are concatenated together, starting with the file that matches the folder name followed by the others in alphabetical order. The .cpp filename extension is then added to the resulting file.

Reference: Sketch build process

This is not the traditional behavior of C and C++ compilers, but Arduino's proposal is to bring practicality for the makers. So please, the concatenation of .ino files needs to be considered.