So, VSCode was working happily for writing code for my STM microcontroller (STM32WB). I would write the code in VSCode and compile and run in STM32CubeIDE.
Lately, however, VSCode's IntelliSense is acting up. It detects problems such as
identifier "uint8_t" is undefined. Furthermore, the 'Output' tab of VSCode gives the following error:
Unable to resolve configuration with compilerPath: "C:/ST/STM32CubeIDE_1.8.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.0.202111181127/tools/bin/arm-none-eabi-gcc.exe"
The path itself appears to be fine. If I issue that command from command prompt, I get
arm-none-eabi-gcc.exe: fatal error: no input files
compilation terminated.
which is the expected response.
Any suggestions on what I can try next? I feel like I'm missing something small!
More info:
I've tried extensively playing around in the c_cpp_properties.json
file.
I've tried downloading another toolchain through STM32CubeIDE and using that path instead.
I've tried adding the path to the Windows environment path.
Here is my c_cpp_properties.json file (most of the settings are copy/paste from what STM32CubeIDE sets up by default:
{
"configurations": [
{
"name": "STM32",
"includePath": [
"${workspaceFolder}/**",
"C:\\ST\\STM32CubeIDE_1.8.0\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.0.202111181127\\tools\\**",
"${workspaceFolder}/Drivers/STM32WBxx_HAL_Driver/Inc",
"${workspaceFolder}/Drivers/CMSIS/Device/ST/STM32WBxx/Include",
"${workspaceFolder}/Drivers/CMSIS/Include",
"${workspaceFolder}/Core/Inc",
"${workspaceFolder}/STM32CubeIDE/Application/Core",
"${workspaceFolder}/STM32CubeIDE/Drivers/STM32WBxx_HAL_Driver",
"${workspaceFolder}/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread",
"${workspaceFolder}/Middlewares/ST/STM32_WPAN/ble/core",
"${workspaceFolder}/Middlewares/ST/STM32_WPAN/utilities",
"${workspaceFolder}/Middlewares/ST/STM32_WPAN/ble",
"${workspaceFolder}/STM32_WPAN/App",
"${workspaceFolder}/Middlewares/ST/STM32_WPAN/ble/core/template",
"${workspaceFolder}/Middlewares/ST/STM32_WPAN",
"${workspaceFolder}/Utilities/sequencer"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"USE_HAL_DRIVER",
"DEBUG",
"STM32WB55xx"
],
"compilerPath": "C:/ST/STM32CubeIDE_1.8.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.0.202111181127/tools/bin/arm-none-eabi-gcc.exe",
"compilerArgs": [
"-mcpu=cortex-m4 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DUSE_STM32WBXX_NUCLEO -DCORE_CM4 -DSTM32WB55xx -c -I../../Core/Inc -I../../Utilities/lpm/tiny_lpm -I../../Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci -I../../Utilities/sequencer -I../../Drivers/CMSIS/Device/ST/STM32WBxx/Include -I../../Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread -I../../Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl -I../../STM32_WPAN/App -I../../Middlewares/ST/STM32_WPAN/ble/core -I../../Middlewares/ST/STM32_WPAN -I../../Middlewares/ST/STM32_WPAN/ble/core/template -I../../Drivers/BSP/P-NUCLEO-WB55.Nucleo -I../../Drivers/STM32WBxx_HAL_Driver/Inc -I../../Middlewares/ST/STM32_WPAN/ble/core/auto -I../../Middlewares/ST/STM32_WPAN/utilities -I../../Middlewares/ST/STM32_WPAN/ble -I../../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb"
],
"cStandard": "gnu11",
"cppStandard": "gnu++11",
"intelliSenseMode": "windows-gcc-arm",
}
],
"version": 4
}
The c_cpp_properties.json reference indicates that some fields are optional. Indeed, simply commenting out the optional compilerArgs parameter resolves the issue. At least to a point that IntelliSense is working correctly again. Note that some of the -DXXXX parameters had to be moved to defines (e.g. -DUSE_STM32WBXX_NUCLEO).
It does make some sense, since you are already defining a lot of the compilerArgs elsewhere in the .json file (like defines and includePath).
Related
I'd like to have some clarifications about compiling and running programs in C. Until now I have mostly used single .c files so now I'm trying to run programs with multiple .c files. I'm on Windows with gcc (mingw).
Let's say that inside the same program folder there are:
file.c (functions' definitions)
header.h (function's prototypes)
main.c
Inside both .c files I have included the header with #include "header.h" .
In the terminal I tried to compile some programs made of multiple .c files like stated above with something like:
gcc file.c main.c -o main
and it created the main.exe file and the program ran correctly but then I tried with another program with the same "structure" and I got error messages that indicated the header file couldn't be found. So I added the header path with the -I command at the end of the command line and again it worked fine. But I don't know why in this case I needed to specific the header path.
Inside VS code I modified the task.json file to compile all the .c files in my workspace (${workspaceFolder}\\*.c) and also added the header path (-I${workspaceFolder}) and it works fine. So the task.json looks like this: (there are some italian phrases and I'm using gcc installed inside CodeBlocks's folder btw).
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc.exe compila il file attivo",
"command": "D:\\CodeBlocks\\MinGW\\bin\\gcc.exe",
"args": [
"-g",
"${workspaceFolder}\\*.c",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe",
"-I${workspaceFolder}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "compilatore: D:\\CodeBlocks\\MinGW\\bin\\gcc.exe"
}
]
}
Basically I'd like to know if I am doing this correctly or if there are other/easier ways to do it.
Yes actually, if you have a lot of file, instead manually type them with gcc, you can do a Makefile.
https://github.com/kayofeld/makefile-gen : this is a plugin to generate automatically your Makefile with all the rules and your files in your directory.
But, if you want to learn how to do one by yourself, you can check this site: https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_makefiles.html
I got a few codes from https://computing.llnl.gov/tutorials/pthreads/ and I was trying to use the VSCode debugger to try to step through them but it doesnt seem to work.
Using tasks (ctrl+shift+B) I can build it just fine (I've added the -pthread flag) but when I try to debug it (F5) I get this error:
> Executing task: C/C++: gcc build active file <
Starting build...
Build finished with error:
/usr/bin/ld: /tmp/cc5vG56K.o: in function `main':
/home/xristosp59/Documents/Programming/condvar.c:98: undefined reference to `pthread_create'
/usr/bin/ld: /home/xristosp59/Documents/Programming/condvar.c:99: undefined reference to `pthread_create'
/usr/bin/ld: /home/xristosp59/Documents/Programming/condvar.c:100: undefined reference to `pthread_create'
/usr/bin/ld: /home/xristosp59/Documents/Programming/condvar.c:104: undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
The terminal process failed to launch (exit code: -1).
I've tried both -pthread and -lpthread flags in various places in my tasks.json but none seem to work, I always get this error.
Here is my current tasks.json: (this builds fine with tasks)
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-g",
"-pthread",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "/usr/bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Generated task by Debugger"
}
],
"version": "2.0.0"
}
I'm on pop_os 20.10 if that matters.
Ok so apparently vscode, when you first try to debug a c program, it creates a launch.json and tasks.json, the launch.json has a "preLaunchTask": "C/C++: gcc build active file" option and tasks.json has a "label": "C/C++: gcc build active file" option, which match, but I guess because C/C++: gcc build active file is already a task in vscode, it doesn't use the one in tasks (please correct me if I'm wrong). I changed the labels in both and now it works.
This is my tasks.json, why is build failing when I try to execute with GCC?
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "C/C++: g++.exe build active file",
"command": "C:\\MinGW\\bin\\g++.exe",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "C:\\MinGW\\bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
This is the output when I type "gcc helloworld.exe" in terminal
> C:\Users\Administrator\projects\helloworld>gcc helloworld.exe
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: DWARF error: could not find abbrev number 3874
helloworld.exe:cygming-crtbegin.c:(.text+0x290): multiple definition of `_mingw32_init_mainargs'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../crt2.o:(.text+0x290): first defined here
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: helloworld.exe:cygming-crtbegin.c:(.text+0x2d0): multiple definition of `mainCRTStartup'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../crt2.o:(.text+0x2d0): first defined here
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: helloworld.exe:cygming-crtbegin.c:(.text+0x2f0): multiple definition of `WinMainCRTStartup'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../crt2.o:(.text+0x2f0): first defined here
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: helloworld.exe:cygming-crtbegin.c:(.text+0x310): multiple definition of `atexit'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../crt2.o:(.text+0x310): first defined here
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: helloworld.exe:cygming-crtbegin.c:(.text+0x320): multiple definition of `_onexit'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../crt2.o:(.text+0x320): first defined here
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: helloworld.exe:cygming-crtbegin.c:(.text+0x330): multiple definition of `__gcc_register_frame'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/crtbegin.o:cygming-crtbegin.c:(.text+0x0): first defined here
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: helloworld.exe:cygming-crtbegin.c:(.text+0x3e0): multiple definition of `__gcc_deregister_frame'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/crtbegin.o:cygming-crtbegin.c:(.text+0xb0): first defined here
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: helloworld.exe:cygming-crtbegin.c:(.bss+0x4): multiple definition of `_argc'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../crt2.o:(.bss+0x4): first defined here
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: helloworld.exe:cygming-crtbegin.c:(.bss+0x0): multiple definition of `_argv'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../crt2.o:(.bss+0x0): first defined here
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: helloworld.exe:cygming-crtbegin.c:(.eh_frame+0xc8): multiple definition of `__EH_FRAME_BEGIN__'; c:/mingw/bin/../lib/gcc/mingw32/9.2.0/crtbegin.o:cygming-crtbegin.c:(.eh_frame+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
Solution is in the comments, thank you everyone for your help!
To compile a C program, the command is
gcc -g -o helloworld.exe -Wall helloworld.c
-g Enable debugging
-o helloworld.exe Put the executable in helloworld.exe
-Wall Enable all warnings
helloworld.c Look for the source code in helloworld.c
Your command is attempting to "compile" the file which you expect the compiler to produce. I don't know if that is producing the errors you see, but it certainly is not correct.
Okay I found somewhat of a solution.
I believe I was trying to compile again after already compiling it, when my intentions were to execute the file.
So I switched the code to c and compiled in the terminal with this:
gcc -g -o helloworld.exe -Wall hiworld.c
Then to execute the new exe I used this:
.\helloworld.exe
thanks for the help!
I am unable to run my c program in visual studio code! I compiles correctly since the executable is in the same directory as the main.c file I am trying to run. My code is:
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
and my tasks.json that did not generate automatically but I had to manually add it via cmd + shift + p and search for tasks
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "/usr/bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
It is the same output from building the program with gcc and clang
> Executing task: /usr/bin/gcc -g '/Users/usrname/Documents/C Programming/main.c' -o '/Users/usrname/Documents/C Programming/main' <
Terminal will be reused by tasks, press any key to close it.
I have installed xcode, both the IDE and the other thingy people recommend installing from terminal "xcode --install" or something like that. I can compile code easily in CLion and from terminal as well as run it, so compiling is obviously not an issue.
The output is blank.
Again this is on mac Mojave latest version running latest version of visual studio code. And yes I have installed the c/c++ extension from the addons page inside the app.
I have a Rust project which I am currently compiling and linking by hand:
rustc --target=avr-atmel-none src/main.rs --emit=obj -o _build/main.rs.o -C opt-level=3
avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p -o _build/image.elf _build/main.rs.o
avr-objcopy -Oihex -R.eeprom _build/image.elf _build/image.hex
I would like to automate this with Cargo, so I started by setting avr-gcc as the linker, by adding the following to .cargo/config:
[build]
target = "avr-atmel-none"
[target.avr-atmel-none]
linker = "avr-gcc"
However, it seems cargo passes some extra arguments to the linker that avr-gcc cannot handle:
11:47:10 [cactus#galaxy interrupt-bug]$ cargo build --release
Compiling hello-avr v0.1.0 (file:///home/cactus/prog/rust/avr/interrupt-bug)
error: linking with `avr-gcc` failed: exit code: 1
|
= note: "avr-gcc" "-Wl,--as-needed" "-L" "/home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmel-none/lib" "/home/cactus/prog/rust/avr/interrupt-bug/target/avr-atmel-none/release/deps/hello_avr-8bce8eb24807f5a8.0.o" "-o" "/home/cactus/prog/rust/avr/interrupt-bug/target/avr-atmel-none/release/deps/hello_avr-8bce8eb24807f5a8" "-Wl,--gc-sections" "-pie" "-Wl,-O1" "-nodefaultlibs" "-L" "/home/cactus/prog/rust/avr/interrupt-bug/target/avr-atmel-none/release/deps" "-L" "/home/cactus/prog/rust/avr/interrupt-bug/target/release/deps" "-L" "/home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmel-none/lib"
= note: /usr/lib/gcc/avr/4.8.2/../../../avr/bin/ld: -pie not supported
collect2: error: ld returned 1 exit status
How do I remove these extra arguments from the avr-gcc invocation? Moreover, is there a way to integrate the third step, i.e. the avr-objcopy call, into the Cargo workflow?
A word of warning: development on avr-rust can politely be said to be cutting edge. It's very likely something that works one day may not the next, so answers like this are likely to go out of date quickly. We welcome all contributors to the project to help make it more usable.
You need to specify a target JSON file and the full set of linker arguments. Here's an example from an older project of mine (some of the exact values may now be incorrect):
{
"llvm-target": "avr-atmel-none",
"target-endian": "little",
"target-pointer-width": "16",
"os": "none",
"target-env": "gnu",
"target-vendor": "unknown",
"arch": "avr",
"data-layout": "e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-n8",
"executables": true,
"linker": "avr-gcc",
"linker-flavor": "gcc",
"pre-link-args": {
"gcc": ["-mmcu=atmega328p", "-nostartfiles", "../interrupt_vector.S"]
},
"exe-suffix": ".elf",
"post-link-args": {
"gcc": ["-Wl,--no-gc-sections"]
},
"no-compiler-rt": true
}
For a full example see my example repository. This project used to work (see my blog series). I have recently updated it so it compiles against the master branch of avr-rust, but haven't tested the compiled code on a real device.
There's an open RFC for having Cargo post build scripts, but it doesn't seem likely to be merged. I continue to use a Makefile. xargo might be an alternative. There were also rumbles about a cargo subcommand that could be created.