Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions msgpack/msgpack-c/c-6.1.0/msgpackc_llar.gox
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import (
"os"
"path/filepath"
"strings"
)

const consumerSource = `#include <msgpack.h>

int main(void) {
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);

msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
if (msgpack_pack_array(&pk, 3) != 0) {
return 1;
}
if (msgpack_pack_int(&pk, 1) != 0) {
return 1;
}
if (msgpack_pack_int(&pk, 2) != 0) {
return 1;
}
if (msgpack_pack_int(&pk, 3) != 0) {
return 1;
}

msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
size_t off = 0;
if (msgpack_unpack_next(&unpacked, sbuf.data, sbuf.size, &off) != MSGPACK_UNPACK_SUCCESS) {
return 1;
}
if (unpacked.data.type != MSGPACK_OBJECT_ARRAY || unpacked.data.via.array.size != 3) {
return 1;
}

msgpack_unpacked_destroy(&unpacked);
msgpack_sbuffer_destroy(&sbuf);
return 0;
}
`

id "msgpack/msgpack-c"

fromVer "c-6.1.0"

defaults {
"shared": "OFF",
"fPIC": "ON",
}

filter => {
for name, values in target.options {
if name != "shared" && name != "fPIC" {
return false
}
for value in values {
if value != "ON" && value != "OFF" {
return false
}
}
}
return true
}

onBuild ctx => {
installDir := ctx.outputDir
shared := target.options["shared"][0] == "ON"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Prefer slices.contains over direct [0] indexing for options

target.options["shared"][0] / target.options["fPIC"][0] (also at line 118) use direct index access. The sibling doubleconversion_llar.gox uses slices.contains(target.options["shared"], "ON"), which is the established convention here and is empty/order-safe. This is safe today only because defaults always seeds both keys. The absence of a slices import (present in the sibling) is a tell that this diverged from the pattern. Recommend matching the convention for consistency and safety.

fPIC := target.options["fPIC"][0] == "ON"

c := cmake.new(ctx.SourceDir, filepath.join(ctx.SourceDir, "_build"), installDir)
c.define "CMAKE_INSTALL_LIBDIR", "lib"
c.defineBool "MSGPACK_ENABLE_SHARED", shared
c.defineBool "MSGPACK_ENABLE_STATIC", !shared
c.defineBool "MSGPACK_BUILD_EXAMPLES", false
c.defineBool "MSGPACK_BUILD_TESTS", false
c.defineBool "CMAKE_POSITION_INDEPENDENT_CODE", fPIC
c.configure
c.build
c.install

licenseDir := filepath.join(installDir, "licenses")
os.mkdirAll(licenseDir, 0o755)!
os.writeFile(filepath.join(licenseDir, "LICENSE_1_0.txt"), os.readFile(filepath.join(ctx.SourceDir, "LICENSE_1_0.txt"))!, 0o644)!

// Upstream writes prefix from CMAKE_INSTALL_PREFIX. Keep its flags and
// publish relocatable pkg-config metadata under Conan's msgpack name.
pcDir := filepath.join(installDir, "lib", "pkgconfig")
pcPath := filepath.join(pcDir, "msgpack-c.pc")
pc := string(os.readFile(pcPath)!)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Unconditional .pc read can hard-fail the build

The upstream-generated msgpack-c.pc is read unconditionally with os.readFile(pcPath)!. The closest sibling recipe (google/double-conversion/v3.3.0/doubleconversion_llar.gox) deliberately guards this path with os.stat/os.isNotExist and synthesizes a relocatable .pc when upstream does not install one. If msgpack-c's CMake does not emit lib/pkgconfig/msgpack-c.pc (different name/case, or a different libdir), this recipe panics instead of degrading gracefully. Consider mirroring the double-conversion pattern: stat first, synthesize the .pc if missing, otherwise rewrite the generated one.

pc = strings.replace(pc, "prefix="+installDir, "prefix=$${pcfiledir}/../..", 1)
pc = strings.replace(pc, "exec_prefix="+installDir, "exec_prefix=$${prefix}", 1)
pc = strings.replace(pc, "libdir="+filepath.join(installDir, "lib"), "libdir=$${prefix}/lib", 1)
pc = strings.replace(pc, "includedir="+filepath.join(installDir, "include"), "includedir=$${prefix}/include", 1)
os.writeFile(pcPath, []byte(pc), 0o644)!
os.writeFile(filepath.join(pcDir, "msgpack.pc"), []byte(pc), 0o644)!

pkgconfig.use installDir
ctx.setMetadata pkgconfig.lookup("msgpack")!
}

onTest ctx => {
installDir := ctx.outputDir
testDir := filepath.join(ctx.SourceDir, "_llar_consumer")
os.mkdirAll(testDir, 0o755)!

sourcePath := filepath.join(testDir, "consumer.c")
os.writeFile(sourcePath, []byte(consumerSource), 0o644)!

pkgconfig.use installDir
flagsFile := filepath.join(testDir, "msgpack.flags")
os.writeFile(flagsFile, []byte(pkgconfig.lookup("msgpack")!), 0o644)!

binary := filepath.join(testDir, "consumer")
cc! sourcePath, "-o", binary, "@"+flagsFile

if target.options["shared"][0] == "ON" {
os.setenv("LD_LIBRARY_PATH", filepath.join(installDir, "lib"))!
os.setenv("DYLD_LIBRARY_PATH", filepath.join(installDir, "lib"))!
}
exec! binary
}
17 changes: 17 additions & 0 deletions msgpack/msgpack-c/msgpackc_cmp.gox
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import "strings"

// The repository publishes both C tags (`c-X.Y.Z`) and C++ tags (`cpp-*`),
// plus a few unprefixed historical tags. GNU version comparison ranks

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Comparator comment cites GNU version rules, but code uses semver

The comment justifies the design via GNU version comparison ("letters above digits, so cpp-* would outrank c-*"), but the comparator actually uses semver.Compare on normalized strings. The guarantee that non-c- tags sort below c- releases comes purely from the "v0.0.0-" + version prerelease mapping under semver, not from any GNU letter-vs-digit rule. The functional behavior is correct for the real tag set, but the stated rationale describes a comparator the code does not use and could mislead a future reader. Also worth a one-line note that ordering among non-c- tags is undefined-by-design (they all collapse to v0.0.0-<tag> and sort by raw prerelease string).

// letters above digits, so `cpp-*` would outrank `c-*`. Keep every visible
// tag in the comparator domain, but order C releases by the numeric part
// after `c-` and map everything else below that line.
func normalize(version string) string {
if strings.hasPrefix(version, "c-") {
return "v" + strings.trimPrefix(version, "c-")
}
return "v0.0.0-" + version
}

Comment on lines +8 to +14

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This library distinguishes between C and C++ based on version numbers. This scenario has not yet been considered by llar and requires discussion — do not merge.

compareVer (a, b) => {
return semver.Compare(normalize(a.Version), normalize(b.Version))
}
4 changes: 4 additions & 0 deletions msgpack/msgpack-c/versions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"path": "msgpack/msgpack-c",
"deps": {}
}