Skip to content

Commit c72901f

Browse files
authored
Merge pull request #63 from QRPp/lib-dedupe-by-stricter-name
Bring back lib deduping/caching by name
2 parents 80cccce + 0d30de6 commit c72901f

File tree

57 files changed

+419
-63
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+419
-63
lines changed

cli/manifest_parser/libs_by_loc_map.go cli/manifest_parser/libs_by_name_map.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,31 @@ import (
2222
"github.com/mongoose-os/mos/cli/build"
2323
)
2424

25-
type libByLoc struct {
25+
type libByName struct {
2626
Lib *build.SWModule
2727
mtx sync.Mutex
2828
}
2929

30-
type libByLocMap struct {
31-
m map[string]*libByLoc
30+
type libByNameMap struct {
31+
m map[string]*libByName
3232
mtx sync.Mutex
3333
}
3434

35-
func newLibByLocMap() *libByLocMap {
36-
return &libByLocMap{m: map[string]*libByLoc{}}
35+
func newLibByNameMap() *libByNameMap {
36+
return &libByNameMap{m: map[string]*libByName{}}
3737
}
3838

39-
// AddOrFetchAndLock() tries to add a new location key to the set. If
40-
// successful, the new entry (Lib: nil) is locked and returned; otherwise (the
41-
// location key already exists) the pre-existing entry is locked and returned.
42-
func (lm *libByLocMap) AddOrFetchAndLock(loc string) *libByLoc {
39+
// AddOrFetchAndLock() tries to add a new name key to the set. If successful,
40+
// the new entry (Lib: nil) is locked and returned; otherwise (the name key
41+
// already exists) the pre-existing entry is locked and returned.
42+
func (lm *libByNameMap) AddOrFetchAndLock(name string) *libByName {
4343
lm.mtx.Lock()
4444
defer lm.mtx.Unlock()
4545

46-
ls, ok := lm.m[loc]
46+
ls, ok := lm.m[name]
4747
if !ok {
48-
ls = &libByLoc{}
49-
lm.m[loc] = ls
48+
ls = &libByName{}
49+
lm.m[name] = ls
5050
}
5151

5252
ls.mtx.Lock()

cli/manifest_parser/manifest_parser.go

+65-14
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,8 @@ type manifestParseContext struct {
528528

529529
prepareLibs []*prepareLibsEntry
530530

531-
mtx *sync.Mutex
532-
libsByLoc *libByLocMap
531+
mtx *sync.Mutex
532+
libsByName *libByNameMap
533533
}
534534

535535
// readManifestWithLibs reads manifest from the provided dir, "expands" all
@@ -568,8 +568,8 @@ func readManifestWithLibs(
568568

569569
cbs: cbs,
570570

571-
mtx: &sync.Mutex{},
572-
libsByLoc: newLibByLocMap(),
571+
mtx: &sync.Mutex{},
572+
libsByName: newLibByNameMap(),
573573
}
574574

575575
manifest, mtime, err := readManifestWithLibs2(dir, pc)
@@ -909,14 +909,14 @@ func prepareLib(
909909
return
910910
}
911911

912-
ls := pc.libsByLoc.AddOrFetchAndLock(m.Location)
912+
ls := pc.libsByName.AddOrFetchAndLock(m.Name)
913913
defer ls.mtx.Unlock()
914914
if ls.Lib != nil {
915915
prepareLibReencounter(parentNodeName, manifest, pc, ls.Lib, m)
916916
return
917917
}
918918

919-
ourutil.Freportf(pc.logWriter, "Reading lib at %q...", m.Location)
919+
ourutil.Freportf(pc.logWriter, "Reading lib %q at %q...", m.Name, m.Location)
920920

921921
libLocalDir, err := pc.cbs.ComponentProvider.GetLibLocalPath(
922922
m, pc.rootAppDir, pc.appManifest.LibsVersion, manifest.Platform,
@@ -947,22 +947,73 @@ func prepareLib(
947947
return
948948
}
949949

950-
// The library can explicitly set its name in its manifest. Also its
951-
// name can be explicitly set in the referring manifest. Either
952-
// separately is fine. None is fine too (the name defaults to the
953-
// location basename). However if both are used, treat a mismatch as an
954-
// error (building without one of the two names in place is guaranteed
955-
// to fail, and is likely with both too).
950+
// The name of a library can be explicitly set in its manifest and/or in the
951+
// referring manifest. Barring that, the name defaults to the location
952+
// basename.
953+
//
954+
// The library code is hardwired to the right name via at least its
955+
// mgos_*_init() symbol. The code using the library may also be via, e.g.,
956+
// HAVE_* variables.
957+
//
958+
// The building process uses the library name for library deduplication and
959+
// overriding.
960+
//
961+
// The location being `.../foo', the library name in use is:
962+
//
963+
// (#) lib mos.yml ref mos.yml name in use
964+
// --------------------------------------
965+
// (1) (none) (none) foo
966+
// (2) (none) foo foo
967+
// (3) (none) bar bar
968+
// (4) foo (none) foo
969+
// (5) foo foo foo
970+
// (6) foo bar (ERROR)
971+
// (7) bar (none) (ERROR)
972+
// (8) bar foo (ERROR)
973+
// (9) bar bar bar
974+
//
975+
// Rationales per (#) case:
976+
// - (1) The most typical use case.
977+
// - (2, 4, 5) Effectively no new information atop the location basename.
978+
// - (3) The handy use case of, e.g., .../foo-test1, .../foo-test2 copies
979+
// adjacent to one another and/or the original .../foo.
980+
// - (6) If `foo' were correct here, the same problem as in (7) would apply.
981+
// If `bar' were correct, then `foo' in lib mos.yml would produce erroneous
982+
// results via any automation/content generation applied to individual
983+
// libraries outside their usages.
984+
// - (7) The name set via the library manifest must be replicated in the
985+
// referring manifest. Otherwise, if this library is overridden while this
986+
// particular location isn't accessible from the building environment,
987+
// library deduplication/overriding by name can't obviate the need to read
988+
// the inaccessible manifest.
989+
// - (8) This is (6) with the names swapped around.
990+
// - (9) A location-independently named library. E.g., Github repositories
991+
// .../mgos-foo, .../mgos-bar with libraries next to repositories unrelated
992+
// to Mongoose OS.
993+
//
994+
// At this point, libRefName == `ref mos.yml' name above; libManifest.name ==
995+
// `lib mos.yml' name; m.Name == libRefName || library location basename.
996+
// After validation, m.Name will be the library `name to use' above.
956997
if libManifest.Name != "" {
957-
if libRefName != "" && libRefName != libManifest.Name {
998+
if libRefName != "" && libRefName != libManifest.Name { // (6, 8) above
958999
lpres <- libPrepareResult{
9591000
err: fmt.Errorf("Library %q at %q is referred to as %q from %q",
9601001
libManifest.Name, m.Location,
9611002
libRefName, manifest.Origin),
9621003
}
9631004
return
9641005
}
965-
m.Name = libManifest.Name
1006+
if libRefName == "" && m.Name != libManifest.Name { // (7) above
1007+
lpres <- libPrepareResult{
1008+
err: fmt.Errorf("Library %q at %q must be referred to as %q from %q",
1009+
libManifest.Name, m.Location,
1010+
libManifest.Name, manifest.Origin),
1011+
}
1012+
return
1013+
}
1014+
}
1015+
if libRefName != "" && m.Name != libRefName { // (3, 9) above
1016+
m.Name = libRefName
9661017
}
9671018
name, err := m.GetName()
9681019
if err != nil {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
type: lib
2+
name: mylib1
3+
sources: [src]
4+
manifest_version: 2020-08-02
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../lib-blank/src

cli/manifest_parser/test_manifests/testset_10_lib_name_settings/test_01_mft_name/app/mos.yml

-8
This file was deleted.

cli/manifest_parser/test_manifests/testset_10_lib_name_settings/test_01_mft_name/libs/mylib1

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
manifest_version: 2020-08-02
2+
3+
libs:
4+
- location: libs/mylib1
5+
6+
# prepareLib() commentary case (1): a library in use has no explicit `name'
7+
# settings. Check that the generated MGOS_HAVE_* and mgos_*_init() identifiers
8+
# are proper.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/* This file is auto-generated by mos build, do not edit! */
2+
3+
#include <stdbool.h>
4+
#include <stdio.h>
5+
6+
#include "common/cs_dbg.h"
7+
8+
#include "mgos_app.h"
9+
10+
extern bool mgos_core_init(void);
11+
extern bool mgos_mylib1_init(void);
12+
13+
14+
#ifndef MGOS_LIB_INFO_VERSION
15+
struct mgos_lib_info {
16+
const char *name;
17+
const char *version;
18+
const char *repo_version;
19+
const char *binary_libs;
20+
bool (*init)(void);
21+
};
22+
#define MGOS_LIB_INFO_VERSION 2
23+
#endif
24+
25+
#ifndef MGOS_MODULE_INFO_VERSION
26+
struct mgos_module_info {
27+
const char *name;
28+
const char *repo_version;
29+
};
30+
#define MGOS_MODULE_INFO_VERSION 1
31+
#endif
32+
33+
const struct mgos_lib_info mgos_libs_info[] = {
34+
35+
// "core". deps: [ ]
36+
#if MGOS_LIB_INFO_VERSION == 1
37+
{.name = "core", .version = NULL, .init = mgos_core_init},
38+
#else
39+
{.name = "core", .version = NULL, .repo_version = NULL, .binary_libs = NULL, .init = mgos_core_init},
40+
#endif
41+
42+
// "mylib1". deps: [ "core" ]
43+
#if MGOS_LIB_INFO_VERSION == 1
44+
{.name = "mylib1", .version = NULL, .init = mgos_mylib1_init},
45+
#else
46+
{.name = "mylib1", .version = NULL, .repo_version = NULL, .binary_libs = NULL, .init = mgos_mylib1_init},
47+
#endif
48+
49+
// Last entry.
50+
{.name = NULL},
51+
};
52+
53+
const struct mgos_module_info mgos_modules_info[] = {
54+
55+
{.name = "mongoose-os", .repo_version = NULL},
56+
57+
// Last entry.
58+
{.name = NULL},
59+
};
60+
61+
bool mgos_deps_init(void) {
62+
for (const struct mgos_lib_info *l = mgos_libs_info; l->name != NULL; l++) {
63+
#if MGOS_LIB_INFO_VERSION == 1
64+
LOG(LL_DEBUG, ("Init %s %s...", l->name, (l->version ? l->version : "")));
65+
#else
66+
LOG(LL_DEBUG, ("Init %s %s (%s)...",
67+
l->name,
68+
(l->version ? l->version : ""),
69+
(l->repo_version ? l->repo_version : "")));
70+
#endif
71+
if (l->init != NULL && !l->init()) {
72+
LOG(LL_ERROR, ("%s init failed", l->name));
73+
return false;
74+
}
75+
}
76+
for (const struct mgos_module_info *m = mgos_modules_info; m->name != NULL; m++) {
77+
LOG(LL_DEBUG, ("Module %s %s", m->name, (m->repo_version ? m->repo_version : "")));
78+
}
79+
return true;
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
app_name: app
2+
libs:
3+
- name: core
4+
location: https://github.com/mongoose-os-libs/core
5+
version: "0.01"
6+
- name: mylib1
7+
location: libs/mylib1
8+
version: "0.01"
9+
modules:
10+
- name: mongoose-os
11+
location: https://github.com/cesanta/mongoose-os
12+
version: "0.01"
13+
manifest_version: "2021-03-26"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: app
2+
type: app
3+
platform: esp32
4+
platforms:
5+
__ALL_PLATFORMS__
6+
sources:
7+
- __APP_ROOT__/libs/core/src/lib.c
8+
- __APP_ROOT__/libs/mylib1/src/lib.c
9+
- __APP_ROOT__/app/build/gen/mgos_deps_init.c
10+
modules:
11+
- name: mongoose-os
12+
location: https://github.com/cesanta/mongoose-os
13+
version: "0.01"
14+
build_vars:
15+
BOARD: ""
16+
ESP_IDF_EXTRA_COMPONENTS: ""
17+
ESP_IDF_SDKCONFIG_OPTS: ""
18+
MGOS: "1"
19+
MGOS_HAVE_CORE: "1"
20+
MGOS_HAVE_MYLIB1: "1"
21+
cdefs:
22+
MGOS: "1"
23+
MGOS_HAVE_CORE: "1"
24+
MGOS_HAVE_MYLIB1: "1"
25+
libs_version: "0.01"
26+
modules_version: "0.01"
27+
mongoose_os_version: "0.01"
28+
manifest_version: "2020-08-02"
29+
libs_handled:
30+
- lib:
31+
name: core
32+
location: https://github.com/mongoose-os-libs/core
33+
path: __APP_ROOT__/libs/core
34+
sources:
35+
- __APP_ROOT__/libs/core/src/lib.c
36+
version: "0.01"
37+
- lib:
38+
name: mylib1
39+
location: libs/mylib1
40+
path: __APP_ROOT__/libs/mylib1
41+
init_deps:
42+
- core
43+
sources:
44+
- __APP_ROOT__/libs/mylib1/src/lib.c
45+
version: "0.01"
46+
init_deps:
47+
- core
48+
- mylib1

cli/manifest_parser/test_manifests/testset_10_lib_name_settings/test_02_ref_name/app/mos.yml

-9
This file was deleted.

cli/manifest_parser/test_manifests/testset_10_lib_name_settings/test_02_ref_name/expected

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
manifest_version: 2020-08-02
2+
3+
libs:
4+
- location: libs/mylib1
5+
name: mylib1
6+
7+
# prepareLib() commentary case (2): a library in use has `name' set in referring
8+
# manifest that corresponds to the basename of its location. Check that the
9+
# generated MGOS_HAVE_* and mgos_*_init() identifiers are unaffected.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../test_01_no_name/expected
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../test_01_no_name/libs

cli/manifest_parser/test_manifests/testset_10_lib_name_settings/test_03_mft_ref_name_mismatch/app/mos.yml

-10
This file was deleted.

cli/manifest_parser/test_manifests/testset_10_lib_name_settings/test_03_mft_ref_name_mismatch/expected/esp32/error.txt

-1
This file was deleted.

cli/manifest_parser/test_manifests/testset_10_lib_name_settings/test_03_mft_ref_name_mismatch/libs

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
manifest_version: 2020-08-02
2+
3+
libs:
4+
- location: libs/mylib1
5+
name: lib1
6+
7+
# prepareLib() commentary case (3): a library in use has `name' set in referring
8+
# manifest that is distinct from its location basename. Check that the
9+
# generated MGOS_HAVE_* and mgos_*_init() identifiers are properly altered.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../test_01_no_name/libs

0 commit comments

Comments
 (0)