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
156 changes: 156 additions & 0 deletions bdwgc/libatomic_ops/v7.8.0/libatomic_llar.gox
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import (
"os"
"path/filepath"
"strings"
)

const consumerSource = `#include "atomic_ops_stack.h"

#include <stdio.h>
#include <stdlib.h>

AO_t globalElement;

AO_stack_t globalStack = AO_STACK_INITIALIZER;

typedef struct {
AO_t head;
unsigned val;
} my_stack_t;

int main(void)
{
AO_store_full(&globalElement, 1337);
{
AO_t val = AO_load_full(&globalElement);
if (val != 1337) {
fprintf(stderr, "Unexpected element after store/load: %u\n", (unsigned) val);
return EXIT_FAILURE;
}
}

{
my_stack_t *newElem = (my_stack_t *) malloc(sizeof(my_stack_t));
newElem->val = 4242;
AO_stack_push_release(&globalStack, &newElem->head);
}
{
my_stack_t *newElem = (my_stack_t *) malloc(sizeof(my_stack_t));
newElem->val = 8484;
AO_stack_push_release(&globalStack, &newElem->head);
}

{
my_stack_t *fetchElement = (my_stack_t *) AO_stack_pop_acquire(&globalStack);
if (fetchElement->val != 8484) {
fprintf(stderr, "Unexpected element from stack: %u\n", (unsigned) fetchElement->val);
return EXIT_FAILURE;
}
free(fetchElement);
}
{
my_stack_t *fetchElement = (my_stack_t *) AO_stack_pop_acquire(&globalStack);
if (fetchElement->val != 4242) {
fprintf(stderr, "Unexpected element from stack: %u\n", (unsigned) fetchElement->val);
return EXIT_FAILURE;
}
free(fetchElement);
}
return EXIT_SUCCESS;
}
`

id "bdwgc/libatomic_ops"

fromVer "v7.8.0"

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

filter => {
for name, values in target.options {
if name != "shared" && name != "fPIC" && name != "assertions" && name != "atomic_intrinsics" {
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.

onBuild/onTest index target.options["..."][0] unconditionally (lines 90-93, 150), but filter (74-86) only rejects unknown option names and non-ON/OFF values — it doesn't require each recognized option to carry a value. If a target supplies a recognized option with an empty value list, filter still returns true and this [0] indexes into an empty slice. defaults covers the common case, but filter is what guards non-default targets. Consider validating a single non-empty value per option in filter, or use membership like cglm's slices.contains(target.options["shared"], "ON") instead of positional [0].

fPIC := target.options["fPIC"][0] == "ON"
assertions := target.options["assertions"][0] == "ON"
atomicIntrinsics := target.options["atomic_intrinsics"][0] == "ON"

c := cmake.new(ctx.SourceDir, filepath.join(ctx.SourceDir, "_build"), installDir)
c.define "CMAKE_INSTALL_LIBDIR", "lib"
c.define "CMAKE_POLICY_VERSION_MINIMUM", "3.5"
c.defineBool "BUILD_SHARED_LIBS", shared
c.defineBool "AO_BUILD_SHARED_LIBS", shared
c.defineBool "CMAKE_POSITION_INDEPENDENT_CODE", fPIC
c.defineBool "enable_assertions", assertions
c.defineBool "enable_atomic_intrinsics", atomicIntrinsics
c.defineBool "BUILD_TESTING", false
c.defineBool "enable_gpl", true
c.defineBool "install_headers", true
c.configure
c.build
c.install

licenseDir := filepath.join(installDir, "licenses")
os.mkdirAll(licenseDir, 0o755)!
for name in []string{"LICENSE", "COPYING"} {
license := os.readFile(filepath.join(ctx.SourceDir, name))!
os.writeFile(filepath.join(licenseDir, name), license, 0o644)!
}

// CMake writes the upstream pkg-config file with the build prefix. Keep
// its verified flags while making the installed package relocatable.
pcPath := filepath.join(installDir, "lib", "pkgconfig", "atomic_ops.pc")
pc := string(os.readFile(pcPath)!)
pc = strings.replace(pc, "prefix="+installDir, "prefix=$${pcfiledir}/../..", 1)

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.

Please verify the $$ in the installed atomic_ops.pc. XGo performs $NAME/${...} interpolation in strings (via Gop_Env), and $$ is the escape for a literal $ — so this is very likely intentional and correct, emitting prefix=${pcfiledir}/../... Since interpolation applies to string literals, dropping to a single $ here would break the file. Worth a quick cat of the installed .pc after build to confirm it contains a single ${pcfiledir} (not a literal $${pcfiledir} and not an eagerly-resolved absolute path). The path math itself — installDir/lib/pkgconfig + /../..installDir — is correct.

os.writeFile(pcPath, []byte(pc), 0o644)!

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

onTest ctx => {
installDir := ctx.outputDir
testDir := filepath.join(ctx.SourceDir, "_llar_consumer")
testBuild := filepath.join(testDir, "_build")
os.mkdirAll(testDir, 0o755)!
os.writeFile(filepath.join(testDir, "consumer.c"), []byte(consumerSource), 0o644)!

cmakeLists := `cmake_minimum_required(VERSION 3.15)
project(libatomic_ops_consumer C)

find_package(Atomic_ops CONFIG REQUIRED)

add_executable(consumer consumer.c)
target_link_libraries(consumer PRIVATE Atomic_ops::atomic_ops Atomic_ops::atomic_ops_gpl)
`
os.writeFile(filepath.join(testDir, "CMakeLists.txt"), []byte(cmakeLists), 0o644)!

c := cmake.new(testDir, testBuild, "")
c.use installDir
c.configure
c.build

if target.options["shared"][0] == "ON" {
os.setenv("LD_LIBRARY_PATH", filepath.join(installDir, "lib"))!

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.

These overwrite LD_LIBRARY_PATH/DYLD_LIBRARY_PATH wholesale rather than prepending to any existing value. Harmless for the current single-dependency test (and shrinking the path is safe, not a hijack risk), but prepending (installDir/lib + separator + the existing value) is the more robust idiom if this test ever needs additional runtime library paths.

os.setenv("DYLD_LIBRARY_PATH", filepath.join(installDir, "lib"))!
}
exec filepath.join(testBuild, "consumer")
lastErr!
}
4 changes: 4 additions & 0 deletions bdwgc/libatomic_ops/versions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"path": "bdwgc/libatomic_ops",
"deps": {}
}
Loading