Search code examples
linuxqtmakefilebuildrootuclinux

How to add my own software to a Buildroot Linux package?


I am trying to add my own program to a small linux, created with Buildroot. What I've done so far:

  • I've created a new directory inside my 'buildroot/package/' called 'HelloWorld'. Inside 'buildroot/package/HelloWorld' I have : a Config.in, HelloWorld.mk and HelloWorld directory. Config.in holds this:

         config BR2_PACKAGE_HELLOWORLD
         bool "helloworld"
         default y
         help
                 Hello world component.
    

HelloWorld.mk holds this:

HELLOWORLD_VERSION:= 1.0.0
HELLOWORLD_SITE:= /home/userpc/Downloads/helloworld/
HELLOWORLD_SITE_METHOD:=local
HELLOWORLD_INSTALL_TARGET:=YES

define HELLOWORLD_BUILD_CMDS
        $(MAKE) CC="$(TARGET_CC)" LD="$(TARGET_LD)" -C $(@D) all
endef

define HELLOWORLD_INSTALL_TARGET_CMDS
        $(INSTALL) -D -m 0755 $(@D)/helloworld $(TARGET_DIR)/bin
endef

define HELLOWORLD_PERMISSIONS
       /bin/helloworld f 4755 0 0 - - - - - 
endef

$(eval $(generic-package))

(inspiration source) The HelloWorld directory contains: main.c & Makefile:

main.c :

#include <stdio.h>

int main()
{
        printf("\nMain entry.\n");
        return 0;
}

Makefile:

CC=gcc
CFLAGS=-I.

all: *.c
        $(CC) -Os -Wall  *.c -o helloworld
#       $(STRIP) helloworld

clean:
        rm -f a.out helloworld
        rm -f *.o

Edit: And I have also added source "package/HelloWorld/Config.in" to 'package/Config.in' But when I mount my rootfs.ext2 partition I can't find my HelloWorld executable inside /usr/bin .., I am really new to this and don't have any prior knowledge, so could you please explain to me, what am I missing from this, because I'm sure I'm doing something wrong.

UPDATE: The program builds and install at the desired location but when I try to run it like so: ./helloworld, I get: bash: ./helloworld: No such file or directory It has execution rights. What is the matter with it? (I try to run it after I mount the rootfs.ext2 into a ubuntu directory, the target arch for buildroot is i386, so it should be ok, right?)

After building and installing the HelloWorld program, and eventually running it, I'd like to add to init.d so it starts after booting, and replace the HelloWorld with a Qt Window that doesn't need a X server, like this thing here.

The main source of inspiration here.


Solution

  • Minimal tested example on top of 2016.05

    GitHub upstream: https://github.com/cirosantilli/buildroot/tree/in-tree-package-2016.05

    This example adds the package source in-tree, which is simple for educational purposes and the way to go if you want to merge back (kudos!),

    If you do not intend on merging back (booooh!), it is more likely that you will want to use Buildroot as a git submodule and either:

    Files modified:

    package/Config.in

    menu "Misc"
        source "package/hello/Config.in"
    endmenu
    

    package/hello/Config.in

    config BR2_PACKAGE_HELLO
        bool "hello"
        help
            Hello world package.
    
            http://example.com
    

    package/hello/hello.mk

    ################################################################################
    #
    # hello
    #
    ################################################################################
    
    HELLO_VERSION = 1.0
    HELLO_SITE = ./package/hello/src
    HELLO_SITE_METHOD = local
    
    define HELLO_BUILD_CMDS
        $(MAKE) CC="$(TARGET_CC)" LD="$(TARGET_LD)" -C $(@D)
    endef
    
    define HELLO_INSTALL_TARGET_CMDS
        $(INSTALL) -D -m 0755 $(@D)/hello $(TARGET_DIR)/usr/bin
    endef
    
    $(eval $(generic-package))
    

    package/hello/src/.gitignore

    hello
    

    package/hello/src/Makefile

    CC = gcc
    
    .PHONY: clean
    
    hello: hello.c
        $(CC) -o '$@' '$<'
    
    clean:
        rm hello
    

    package/hello/src/hello.c

    #include <stdio.h>
    
    int main(void) {
        puts("hello");
    }
    

    Usage:

    make qemu_x86_64_defconfig
    echo 'BR2_PACKAGE_HELLO=y' >> .config
    make BR2_JLEVEL=2
    qemu-system-x86_64 -M pc -kernel output/images/bzImage -drive file=output/images/rootfs.ext2,if=virtio,format=raw -append root=/dev/vda -net nic,model=virtio -net user
    

    From inside qemu:

    hello
    

    Expected output:

    hello
    

    Tested in Ubuntu 16.04.