Executing make command on this Makefile compiles as expected:
#SHELL = /bin/sh
APP:= basic-tutorial-2
APP_INSTALL_DIR?= $(HOME)/Projects/test-gstreamer-2/build/bin
CC:=/usr/bin/aarch64-linux-gnu-gcc
SRCS:= $(wildcard *.c)
INCS:= $(wildcard *.h)
PKGS:= gstreamer-1.0
OBJS:= $(SRCS:.c=.o)
CFLAGS:= $(shell pkg-config --cflags $(PKGS))
LIBS:= $(shell pkg-config --libs $(PKGS))
#$(info $$CFLAGS is [${CFLAGS}]) <-- Print variable
all: $(APP)
%.o: %.c $(INCS)
$(CC) -ggdb -O0 -c -o $@ $(CFLAGS) $<
$(APP): $(OBJS)
$(CC) -ggdb -O0 -o $(APP) $(OBJS) $(LIBS)
install: $(APP)
cp -rv $(APP) $(APP_INSTALL_DIR)
clean:
rm -rf $(OBJS) $(APP)
rm $(APP_INSTALL_DIR)/$(APP)
steven@development-orin:~/Projects/test-gstreamer-2/build$ ls -al
-rw-rw-r-- 1 steven steven 2291 Apr 3 17:15 basic-tutorial-2.c
drwxrwxr-x 2 steven steven 4096 Apr 4 16:07 bin
-rw-rw-r-- 1 steven steven 613 Apr 3 19:17 Makefile
steven@development-orin:~/Projects/test-gstreamer-2/build$ make
/usr/bin/aarch64-linux-gnu-gcc -ggdb -O0 -c -o basic-tutorial-2.o -pthread -I/usr/include/gstreamer-1.0 -I/usr/include/aarch64-linux-gnu -I/usr/i nclude/glib-2.0 -I/usr/lib/aarch64-linux-gnu/glib-2.0/include basic-tutorial-2.c
/usr/bin/aarch64-linux-gnu-gcc -ggdb -O0 -o basic-tutorial-2 basic-tutorial-2.o -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0
steven@development-orin:~/Projects/test-gstreamer-2/build$ ls -al
-rwxrwxr-x 1 steven steven 21992 Apr 4 16:21 basic-tutorial-2
-rw-rw-r-- 1 steven steven 2291 Apr 3 17:15 basic-tutorial-2.c
-rw-rw-r-- 1 steven steven 19992 Apr 4 16:21 basic-tutorial-2.o
drwxrwxr-x 2 steven steven 4096 Apr 4 16:07 bin
-rw-rw-r-- 1 steven steven 613 Apr 3 19:17 Makefile
Application basic-tutorial-2 is created as expected.
However, when I attempt to compile in Visual studio code:
I get this
* Executing task: '/usr/bin/make' '-f' '/home/steven/Projects/test-gstreamer-2/build/Makefile'
/usr/bin/aarch64-linux-gnu-gcc -ggdb -O0 -o basic-tutorial-2 -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0
/usr/bin/ld: /usr/lib/gcc/aarch64-linux-gnu/11/../../../aarch64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x1c): undefined reference to `main'
/usr/bin/ld: (.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [/home/steven/Projects/test-gstreamer-2/build/Makefile:24: basic-tutorial-2] Error 1
* The terminal process "/bin/bash '-c', ''/usr/bin/make' '-f' '/home/steven/Projects/test-gstreamer-2/build/Makefile''" failed to launch (exit code: 2).
* Terminal will be reused by tasks, press any key to close it.
I’m hoping the answer is NOT to change the Makefile, but to configure VSC differently. Any ideas?
#1 Source file contents:
// basic-tutorial-2.c
#include <gst/gst.h>
int
main (int argc, char *argv[])
{
GstElement *pipeline, *source, *sink;
GstBus *bus;
GstMessage *msg;
GstStateChangeReturn ret;
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Create the elements */
source = gst_element_factory_make ("videotestsrc", "source");
sink = gst_element_factory_make ("autovideosink", "sink");
/* Create the empty pipeline */
pipeline = gst_pipeline_new ("test-pipeline");
if (!pipeline || !source || !sink) {
g_printerr ("Not all elements could be created.n");
return -1;
}
/* Build the pipeline */
gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
if (gst_element_link (source, sink) != TRUE) {
g_printerr ("Elements could not be linked.n");
gst_object_unref (pipeline);
return -1;
}
/* Modify the source's properties */
g_object_set (source, "pattern", 0, NULL);
/* Start playing */
ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr ("Unable to set the pipeline to the playing state.n");
gst_object_unref (pipeline);
return -1;
}
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg =
gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* Parse message */
if (msg != NULL) {
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error (msg, &err, &debug_info);
g_printerr ("Error received from element %s: %sn",
GST_OBJECT_NAME (msg->src), err->message);
g_printerr ("Debugging information: %sn",
debug_info ? debug_info : "none");
g_clear_error (&err);
g_free (debug_info);
break;
case GST_MESSAGE_EOS:
g_print ("End-Of-Stream reached.n");
break;
default:
/* We should not reach here because we only asked for ERRORs and EOS */
g_printerr ("Unexpected message received.n");
break;
}
gst_message_unref (msg);
}
/* Free resources */
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}
#2 When I run make from command line
$(info $$SRCS is [${SRCS}]) ---> $SRCS is [basic-tutorial-2.c]
$(info $$OBJS is [${OBJS}]) ---> $OBJS is [basic-tutorial-2.o]
When I run from Visual Studio Code
$(info $$SRCS is [${SRCS}]) ---> $SRCS is []
$(info $$OBJS is [${OBJS}]) ---> $OBJS is []
2
Answers
See this response from another question.
It seems that your link command has no objects:
This means that either
OBJS
orSRCS
(or both) are empty.The linker is (correctly) complaining it has no entry point main.