Project

General

Profile

Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code

Added by Sean Warner almost 2 years ago

I run TVHeadend on a Pi 4 running Ubuntu Server 22.04.1 arm 64-bit.
I want to use an IDE to edit, debug and compile TVHeadend source code on the Pi 4. But Ubuntu Server has no desktop environment.
Here is a solution where I run the IDE (Visual Studio Code) on a separate machine (Laptop) for remote development of TVHeadend source code on the Pi 4.
Target Audience is beginners/hobbyists with an interest in coding.

Instructions

Re-requisites

• A Pi 4 running Ubuntu Server 22.04.1 arm 64-bit.
• A second machine running Visual Studio Code (VSC)

Set up TVHeadend build environment on Pi 4

• Here is a tutorial on how to build TVHeadend on a Pi 4 using the TVHeadend Autobuild script https://tvheadend.org/boards/4/topics/48584
• If this is successful then you should have the TVHeadend sources in somewhere like: /home/ubuntu/buildir/tvheadend
• In ../buildir/tvheadend will also be the Makefile, configure script, the .config.mk file etc... needed to build TVHeadend.
• Successfully built TVHeadend binary will appear in ../buildir/tvheadend/build.linux

Install Visual Studio Code on another machine

• In my case I installed visual-studio-code-bin from “Add/Remove Software” in Manjaro but it could be installed on other Linux Distros, Windows or Mac.
• I installed these plugins: Remote-SSH plugin, C/C++ Extension Pack, C/C++ Themes, Remote Explorer, Remote - SSH: Editing Configuration Files, C/C++, CMake, CMake Tools, Makefile Tools

Configure Visual Studio Code to SSH to the Pi 4

• I followed these instructions https://www.digitalocean.com/community/tutorials/how-to-use-visual-studio-code-for-remote-development-via-the-remote-ssh-plugin
• The link explains how to Configure the Remote-SSH Plugin to connect to the Pi 4 so you can navigate to the TVHeadend source code directory that is on the Pi 4 but from within VSC.

Tell VSC what compiler to use

• I confirmed the location of the binary of the cc compiler I am using on Ubuntu
ubuntu@ubuntu:~/buildir/tvheadend$ which cc
/usr/bin/cc

• Connect to the Pi from VSC using the SSH-Plugin.
• From VSC type... CTRL + Left SHIFT + P then type in “C/C++: Edit configurations (UI)”
• I filled in the details below...
• When you save this a file is created: ../buildir/tvheadend/.vscode/c_cpp_properties.json

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**" 
            ],
            "defines": [],
            "compilerPath": "/usr/bin/cc",
            "cStandard": "c17",
            "cppStandard": "c++14",
            "intelliSenseMode": "linux-gcc-arm64",
            "configurationProvider": "ms-vscode.makefile-tools" 
        }
    ],
    "version": 4
}

Tell VSC to build TVHeadend

• Click on the "Explorer" icon in the VSC left menu and in the “src” dir I clicked on “main.c”
• Type CTRL + Shift + P then type “Build” in to the search box then select Makefile: Build the current Target makefile.buildTarget
• This immediately starts building tvheadend.

Simplify the build process with VSC Tasks

• Visual Studio Code Tasks https://code.visualstudio.com/docs/editor/tasks
• A "Task" simplifies the build process in VSC so for instance you can build tvheadend by selecting... File Menu > Terminal > Run Build Task (or Ctrl+Shift+B)
• After the above step when VSC builds TVHeadend it should automatically create a tasks.json file in...
• ../buildir/tvheadend/.vscode/tasks.json
• This is the contents of my tasks.json

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build",
            "type": "shell",
            "command": "make",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

• The “isDefault”: true means that you can now get VSC to build tvheadend by selecting... File Menu > Terminal > Run Build Task (or Ctrl+Shift+B)
• "command": "make" basically means that this process causes VSC to execute the make command!
• To create a new task from scratch type: [Ctrl + Shift + p] then type “tasks” > select “Tasks: Configure Tasks” > Create Tasks.json file from template > Others

A compound task

• Visual Studio Code Compound Tasks https://code.visualstudio.com/docs/editor/tasks#_compound-tasks
• This is not essential but basically a compound tasks automates execution of several steps that may need to occur prior to building TVHeadend for instance:

make distclean
./configure
make -j$(nproc)

• This is the tasks.json file to execute the above three steps one after another...
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Run Make distclean command",
            "type": "shell",
            "command": "make distclean",
            "problemMatcher": [],
            "group": "build" 
        },
        {
            "label": "Run Config script",
            "type": "shell",
            "command": "./configure",
            "args": [
                "--enable-hdhomerun_client",
                "--disable-hdhomerun_static",
                "--disable-dvbscan",
                "--enable-libav",
                "--disable-ffmpeg_static",
                "--enable-libx264",
                "--disable-libx264_static",
                "--enable-libx265",
                "--disable-libx265_static",
                "--enable-libvpx",
                "--disable-libvpx_static",
                "--enable-libtheora",
                "--disable-libtheora_static",
                "--enable-libvorbis",
                "--disable-libvorbis_static",
                "--enable-libfdkaac",
                "--disable-libfdkaac_static",
                "--enable-libopus",
                "--disable-libopus_static",
                "--enable-vaapi",
                "--enable-omx",
                "--enable-dvbcsa",
                "--enable-dvben50221",
                "--enable-libsystemd_daemon",
                "--enable-pcre2",
                "--enable-pngquant",
                "--python=/usr/bin/python3" 
            ],
            "problemMatcher": [],
            "group": "build" 
        },
        {
            "label": "Run Make command",
            "type": "shell",
            "command": "make",
            "args": [
                "-j$(nproc)" 
            ],
            "problemMatcher": [],
            "group": "build" 
        },
        {
            "label": "Build TVH",
            "dependsOrder": "sequence",
            "dependsOn": [
                "Run Make distclean command",
                "Run Config script",
                "Run Make command" 
            ],
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

• To make this Task the Default Build Task...
• File Menu > Terminal > Configure Default Build Task > Then choose the task with the label: “Build TVH”.
• To run this task... Ctrl + Shift + P > tasks: Run Task > Select the task label: “Build TVH”.
• Or simply Ctrl +Shift + B

Debugging TVHeadend from Visual Studio Code

• Remote Debugging with gdb in Visual Studio Code https://code.visualstudio.com/docs/editor/debugging
• Install gdb in Ubuntu, check if it is installed already, if not then install it...

which gdb
sudo apt update
sudo apt install gdb

• In VSC click the Debugger icon on the left most menu (fourth one down, looks a bit like a Play icon) OR by typing Ctrl + Shift + D.
• I got to a window where I clicked on “Create a launch.json file".
• Here I chose: node.js debugger. That created the file: launch.json in ../buildir/tvheadend/.vscode/launch.json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [    
    {
        // for Linux
        "name": "(gdb) Launch TVH",
        "type": "cppdbg",
        "request": "launch",
        "program": "${workspaceRoot}/build.linux/tvheadend",
        "args": [],
        "stopAtEntry": false,
        "cwd": "${workspaceRoot}/build.linux",
        "environment": [],
        "externalConsole": false,
        "MIMode": "gdb",
        "preLaunchTask": "Build TVH",
        "setupCommands": [
          {
            "description": "Enable pretty-printing for gdb",
            "text": "-enable-pretty-printing",
            "ignoreFailures": true
          }
        ]
     }
  ]
}

• A key point is that it must have the line: "preLaunchTask": "Build TVH",
• This makes it refer back to the Task you use to build TVHeadend using the correct label of that task: “Build TVH”.
• To test the remote debugging...
• Go to main.c in the “src” dir of tvheadend in VSC, find a line of code anywhere in the "main" method and make a breakpoint by clicking on a faint RED DOT to the left of the line number.
• Click on the Run Menu > Start Debugging in VSC.
• After recompiling the code (the preLaunchTask in launch.json refers back to the name of the build task in tasks.json), Tvheadend is launched and execution stops at that breakpoint.
• Now you can do things like variable inspection.

In Conclusion

• Many thanks to @Adrian Smith for this idea and explanations!
• I hope this helps someone and saves them time.
• Comments, feedback or corrections very welcome.

Useful Links

• Remote Development with Visual Studio Code https://code.visualstudio.com/docs/remote/remote-overview
• More on Remote Development with Visual Studio Code https://www.digitalocean.com/community/tutorials/how-to-use-visual-studio-code-for-remote-development-via-the-remote-ssh-plugin
• Compile and test tvheadend from an IDE? https://tvheadend.org/boards/4/topics/48330


Replies (9)

RE: Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code - Added by saen acro almost 2 years ago

Sean Warner wrote:

--enable-nvenc
--enable-ddci

Is this useful for RPI ?

RE: Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code - Added by Sean Warner almost 2 years ago

@saen acro
Thanks for the feedback!
Nvidia NVENC (short for Nvidia Encoder) is a feature in Nvidia graphics cards. So I have removed this.
DDCI (Digital Devices CI interfaces) I don't understand this enough to know if it could work with a Pi or not? If a Pi can see Tuners via TVHeadend from a remote receiver then could the Pi also see the Common Interface on the same remote receiver via TVHeadend? Anyway for now I have removed this also. More Info here: https://tvheadend.org/boards/13/topics/29639

RE: Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code - Added by Alin Gherghescu almost 2 years ago

This tutorial is not limited to RPI4 ... is it? My point is: This is true also if I replace RPI4 with amd64 system with Ubuntu 22.04?
Also, can you confirm you can perform debugging Step by Step in the code? With break points and all the goodies?
I am using VSC for writing the code and I am missing the Debug capability :( a lot.

RE: Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code - Added by Sean Warner almost 2 years ago

Hello Alin,

I haven't tried any other setup and I'm not very knowledgeable about this I just got it working as described above.
It should definitely work with Ubuntu on an amd64 system as long as you set up and can connect from Visual Studio Code (VSC) to the system where the tvheadend code is using the VSC SSH-plugin.
Yes I got step by step debugging working following the instructions explained above.

Cheers,

Flex

RE: Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code - Added by Alin Gherghescu almost 2 years ago

Sean, I have some progress. Is really impressive how VSC can handle Linux development.
Your tutorial is very helpful.
Some comments:
1. is very good that you provide the source of info (for details)
2. plugin --> extensions: I was starting to look for plugins in VSC ... :) and actually are named extensions.
3. missing how to connect SSH to remove with the SSH extension. --> this give me a lot of trouble with ssh key :( .
4. I had to install "C/C++ Intellisense, debugger and code browsing" on the remote computer.
5. Is very time consuming to use distclean everytime :( .

What I had to change:
I prefer /.Autobuild.sh

tasks.json:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Run Autobuild",
            "type": "shell",
            "command": "./Autobuild.sh",
            "problemMatcher": [],
            "group": "build" 
        },
        {
            "label": "Build TVH",
            "dependsOrder": "sequence",
            "dependsOn": [
                "Run Autobuild" 
            ],
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

What I still have problems with:
- I can't make the debug session run as the 'installed version'. Because I cannot setup the initial user I am unable to enter web interface. I always get: 403 Forbidden

Let me show you what args I used for debug:

launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [    
    {
        // for Linux
        "name": "(gdb) Launch TVH",
        "type": "cppdbg",
        "request": "launch",
        "program": "${workspaceRoot}/build.linux/tvheadend",
        "args": [-u hts -g hts -c '/home/hts/.hts/tvheadend'],
        "stopAtEntry": false,
        "cwd": "${workspaceRoot}/build.linux",
        "environment": [],
        "externalConsole": false,
        "MIMode": "gdb",
        "preLaunchTask": "Build TVH",
        "setupCommands": [
          {
            "description": "Enable pretty-printing for gdb",
            "text": "-enable-pretty-printing",
            "ignoreFailures": true
          }
        ]
     }
  ]
}

Do you know if the args from ""args": [-u hts -g hts -c '/home/hts/.hts/tvheadend']," will be sent to tvheadend?
Can someone tell me what args are used by default if I install tvheadend with dpkg?
Great job with tutorial.
Thanks.

RE: Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code - Added by saen acro almost 2 years ago

Alin Gherghescu wrote:

Can someone tell me what args are used by default if I install tvheadend with dpkg?

 ps aux | grep tvheadend
hts      1032313  0.0  0.0 1310680 3660 ?        SNsl jan10  13:01 /usr/bin/tvheadend -f -p /run/tvheadend.pid -u hts -g video

RE: Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code - Added by Alin Gherghescu almost 2 years ago

thank you all for help ... is working now.
You should know that the way VSC is passing parameters to tvheadend ... for some reason are not picked up properly.
The way I fixed the problem: I override the 'opt_firstrun = 1' in main() and started one time to be able to connect to webpage. After I finished the setup I reverted back 'opt_firstrun = 0' and now works.

launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [    
    {
        // for Linux
        "name": "(gdb) Launch TVH",
        "type": "cppdbg",
        "request": "launch",
        "program": "${workspaceRoot}/build.linux/tvheadend",
        "args": [],
        "stopAtEntry": false,
        "cwd": "${workspaceRoot}/build.linux",
        "environment": [],
        "externalConsole": false,
        "MIMode": "gdb",
        "preLaunchTask": "Build TVH",
        "setupCommands": [
          {
            "description": "Enable pretty-printing for gdb",
            "text": "-enable-pretty-printing",
            "ignoreFailures": true
          }
        ]
     }
  ]
}

RE: Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code - Added by Adrian Smith almost 2 years ago

Alin Gherghescu wrote:

launch.json:
...
"args": [-u hts -g hts -c '/home/hts/.hts/tvheadend'],

For reference, I don't believe that this is the way to specify command line arguments in launch.json. I believe that this must be a quoted, comma separated list of command line arguments. So it should have been:

"args": ["-u", "hts", "-g", "hts", "-c", "/home/hts/.hts/tvheadend"],

Note that although "-u hts" might be considered as a single argument, it should be split at the space character into separate list items in launch.json.

RE: Remote build and debug TVHeadend on a Pi 4 from Visual Studio Code - Added by Alin Gherghescu almost 2 years ago

Adrian you nail it ... all params have to be comma separated.
Thank you.

    (1-9/9)