diff --git a/doc/man/ade-debug.1 b/doc/man/ade-debug.1
index 0a425b2d8c1d6d445d970e213bfbd68a014532d1..177b622697bb5532c4e7b8c05a69c649deda27d2 100644
--- a/doc/man/ade-debug.1
+++ b/doc/man/ade-debug.1
@@ -27,7 +27,8 @@ the debug symbols are available\&.
 .PP
 \fI\-\-app\fR
 .RS 4
-Absolute path to application to start\&.
+Absolute path to application to start\&. If not specified, the main entry
+point is used when found\&.
 .sp
 .RE
 .PP
diff --git a/doc/man/ade-run.1 b/doc/man/ade-run.1
index 27f43985c078908b394f8dbd8459d727b953fcb8..69b224236e42b2c1510d53e5ecff1d7fff4011d6 100644
--- a/doc/man/ade-run.1
+++ b/doc/man/ade-run.1
@@ -12,8 +12,8 @@ ade-run \- Start an application
 .SH SYNOPSIS
 .sp
 .nf
-\fIade run\fR --app=<app> --simulator
-\fIade run\fR --app=<app> --device [<user>[:<pass>]@]<hostname>[:<port>]
+\fIade run\fR [--app=<app>] --simulator
+\fIade run\fR [--app=<app>] --device [<user>[:<pass>]@]<hostname>[:<port>]
 .fi
 .sp
 .SH DESCRIPTION
@@ -25,7 +25,8 @@ Start an application in simulator or on given device\&.
 .PP
 \fI\-\-app\fR
 .RS 4
-Absolute path to application to start\&.
+Absolute path to application to start\&. If not specified, the main entry
+point is used when found\&.
 .sp
 .RE
 .PP
diff --git a/tools/ade b/tools/ade
index 90481c6a9b0096eea314ab3fbeeb55d708c692df..6c5c6beb1db6972817eb2485bc08b7710d920cd7 100755
--- a/tools/ade
+++ b/tools/ade
@@ -751,6 +751,23 @@ class SysrootManager:
         return f
 
 
+class EntryPoint:
+
+    def __init__(self, filename, name, icon, executable):
+        self.name = name
+        self.icon = icon
+        self.executable = executable
+
+    def from_file(path):
+        parser = configparser.ConfigParser()
+        parser.read(path)
+        filename = os.path.basename(path)
+        name = parser['Desktop Entry']['Name']
+        icon = parser['Desktop Entry']['Icon']
+        executable = parser['Desktop Entry']['Exec']
+        return EntryPoint(filename, name, icon, executable)
+
+
 class Project:
 
     def __init__(self, path=None, bundle_id=None):
@@ -798,6 +815,30 @@ class Project:
             except:
                 pass
 
+    def get_entry_points(self):
+        if not self.is_configured():
+            return []
+
+        entry_points = []
+        with tempfile.TemporaryDirectory() as tmpdir:
+            self.install(tmpdir, quiet=True)
+            apps = os.path.join(tmpdir, 'Applications', self.bundle_id, 'share', 'applications')
+            for app in os.listdir(apps):
+                path = os.path.join(apps, app)
+                if os.path.isdir(path) or not app.endswith('.desktop'):
+                    continue
+                entry_points.append(EntryPoint.from_file(path))
+        return entry_points
+
+    def get_main_executable(self):
+        entry_points = self.get_entry_points()
+        if len(entry_points) == 1:
+            return entry_points[0].executable
+        for entry_point in entry_points:
+            if entry_point.filename == "{}.desktop".format(self.bundle_id):
+                return entry_point.executable
+        return None
+
     def is_configured(self):
         return os.path.exists(os.path.join(self.root, "config.status"))
 
@@ -839,10 +880,14 @@ class Project:
         p = subprocess.Popen(args, cwd=self.root, env=env)
         p.wait()
 
-    def make(self, target='all', env=dict()):
+    def make(self, target='all', env=dict(), quiet=False):
         if not self.is_configured():
             raise NotConfiguredError
-        p = subprocess.Popen(['make', target], cwd=self.root, env=env)
+        stdout = None
+        if quiet:
+            stdout = subprocess.PIPE
+        p = subprocess.Popen(['make', target], cwd=self.root, env=env,
+                             stdout=stdout, stderr=stdout)
         p.wait()
 
     def build(self, verbose=False):
@@ -854,11 +899,11 @@ class Project:
         p = subprocess.Popen(args, cwd=self.root)
         p.wait()
 
-    def install(self, path=None):
+    def install(self, path=None, quiet=False):
         env = os.environ.copy()
         if path:
             env['DESTDIR'] = path
-        self.make('install', env)
+        self.make('install', env, quiet=quiet)
 
     def set_pkg_config_vars(self, env, sysroot):
         def join_paths(paths):
@@ -1296,9 +1341,12 @@ class Ade:
             if self.format == 'parseable':
                 print("ImageVersion:{0}".format(obj.version.get_tag()))
         elif isinstance(obj, Project):
+            entry_points = obj.get_entry_points()
             self.info("* Project: {0}{1}{2}".format(Colors.WARNING, obj.name, Colors.ENDC))
             self.info("* BundleId: {0}".format(obj.bundle_id))
             self.info("* Version: {0}".format(obj.version))
+            for entry_point in entry_points:
+                self.info("* Entry Point: {0}".format(entry_point.name))
             if self.format == 'parseable':
                 print("ProjectName:{0}".format(obj.name))
                 print("BundleId:{0}".format(obj.bundle_id))
@@ -1366,12 +1414,18 @@ class Ade:
 
     def do_run(self):
         target = self.get_target()
+        if not self.app:
+            project = Project()
+            self.app = project.get_main_executable()
         target.run(self.app, *self.args)
 
     def do_debug(self):
         target = self.get_target()
         project = Project()
 
+        if not self.app:
+            self.app = project.get_main_executable()
+
         with DebuggerServer(target, self.app, *self.args) as server:
             gdb = Debugger(self.unpack_sysroot(target), project)
             gdb.connect(server)