From 9501dba9c590180061859305309e84618163cdd1 Mon Sep 17 00:00:00 2001 From: Rick Guo Date: Thu, 10 Sep 2026 11:44:58 +0800 Subject: [PATCH 1/3] formula: add nayuki/QR-Code-generator --- nayuki/QR-Code-generator/CMakeLists.txt | 42 ++++ .../v1.4.0/qrcodegenerator_llar.gox | 211 ++++++++++++++++++ nayuki/QR-Code-generator/versions.json | 4 + 3 files changed, 257 insertions(+) create mode 100644 nayuki/QR-Code-generator/CMakeLists.txt create mode 100644 nayuki/QR-Code-generator/v1.4.0/qrcodegenerator_llar.gox create mode 100644 nayuki/QR-Code-generator/versions.json diff --git a/nayuki/QR-Code-generator/CMakeLists.txt b/nayuki/QR-Code-generator/CMakeLists.txt new file mode 100644 index 0000000..737efd3 --- /dev/null +++ b/nayuki/QR-Code-generator/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.15) +project(QR-Code-Generator) + +set(SRC_C "${CMAKE_SOURCE_DIR}/c/qrcodegen.c") +set(LIBRARY_NAME_C qrcodegenc) +set(HEADERS_C "${CMAKE_SOURCE_DIR}/c/qrcodegen.h") + +add_library(${LIBRARY_NAME_C} ${SRC_C}) +set_target_properties(${LIBRARY_NAME_C} PROPERTIES PUBLIC_HEADER "${HEADERS_C}") +install(TARGETS ${LIBRARY_NAME_C} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PUBLIC_HEADER DESTINATION include/qrcodegenc) + +if(EXISTS "${CMAKE_SOURCE_DIR}/cpp/qrcodegen.cpp") + set(SRC "${CMAKE_SOURCE_DIR}/cpp/qrcodegen.cpp") + set(HEADERS "${CMAKE_SOURCE_DIR}/cpp/qrcodegen.hpp") + set(LIBRARY_NAME qrcodegencpp) +elseif(EXISTS "${CMAKE_SOURCE_DIR}/cpp/BitBuffer.cpp") + set(SRC + "${CMAKE_SOURCE_DIR}/cpp/QrCode.cpp" + "${CMAKE_SOURCE_DIR}/cpp/QrSegment.cpp" + "${CMAKE_SOURCE_DIR}/cpp/BitBuffer.cpp") + set(HEADERS + "${CMAKE_SOURCE_DIR}/cpp/QrCode.hpp" + "${CMAKE_SOURCE_DIR}/cpp/QrSegment.hpp" + "${CMAKE_SOURCE_DIR}/cpp/BitBuffer.hpp") + set(LIBRARY_NAME qrcodegen) +else() + set(SRC "${CMAKE_SOURCE_DIR}/cpp/QrCode.cpp") + set(HEADERS "${CMAKE_SOURCE_DIR}/cpp/QrCode.hpp") + set(LIBRARY_NAME qrcodegen) +endif() + +add_library(${LIBRARY_NAME} ${SRC}) +set_target_properties(${LIBRARY_NAME} PROPERTIES PUBLIC_HEADER "${HEADERS}") +install(TARGETS ${LIBRARY_NAME} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PUBLIC_HEADER DESTINATION include/qrcodegen) diff --git a/nayuki/QR-Code-generator/v1.4.0/qrcodegenerator_llar.gox b/nayuki/QR-Code-generator/v1.4.0/qrcodegenerator_llar.gox new file mode 100644 index 0000000..a6e2b3f --- /dev/null +++ b/nayuki/QR-Code-generator/v1.4.0/qrcodegenerator_llar.gox @@ -0,0 +1,211 @@ +import ( + "os" + "path/filepath" + "strings" +) + +const consumerSource = `#if QR_USE_OLD_INCLUDE +#include "qrcodegen/QrCode.hpp" +#else +#include "qrcodegen/qrcodegen.hpp" +#endif + +#include +#include +#include +#include +#include + +namespace { + std::string toSvgString(const qrcodegen::QrCode &qr, int border) { + if (border < 0) + throw std::domain_error("Border must be non-negative"); + if (border > std::numeric_limits::max() / 2 || border * 2 > std::numeric_limits::max() - qr.getSize()) + throw std::overflow_error("Border too large"); + + std::ostringstream sb; + sb << "\n"; + sb << "\n"; + sb << "\n"; + sb << "\t\n"; + sb << "\t\n"; + sb << "\n"; + return sb.str(); + } +} + +int main() { + std::cout << toSvgString(qrcodegen::QrCode::encodeText("test", qrcodegen::QrCode::Ecc::MEDIUM), 0); + return 0; +} +` + +id "nayuki/QR-Code-generator" + +fromVer "v1.4.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 + osName := target.require["os"][0] + shared := target.options["shared"][0] == "ON" + fPIC := target.options["fPIC"][0] == "ON" + + cmakeLists := ctx.Proj.readFile("CMakeLists.txt")! + os.writeFile(filepath.join(ctx.SourceDir, "CMakeLists.txt"), cmakeLists, 0o644)! + + cppHeader := filepath.join(ctx.SourceDir, "cpp", "QrCode.hpp") + cppLibrary := "qrcodegen" + newHeader := filepath.join(ctx.SourceDir, "cpp", "qrcodegen.hpp") + if _, err := os.stat(newHeader); err == nil { + cppHeader = newHeader + cppLibrary = "qrcodegencpp" + } else if !os.isNotExist(err) { + panic err + } + + if cppLibrary == "qrcodegen" { + header := string(os.readFile(cppHeader)!) + if strings.index(header, "#include ") < 0 { + header = strings.replace(header, "#include \n", "#include \n#include \n", 1) + os.writeFile(cppHeader, []byte(header), 0o644)! + } + } + + c := cmake.new(ctx.SourceDir, filepath.join(ctx.SourceDir, "_build"), installDir) + c.define "CMAKE_INSTALL_LIBDIR", "lib" + c.defineBool "BUILD_SHARED_LIBS", shared + if osName == "windows" && shared { + c.defineBool "CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS", true + } + if osName != "windows" { + c.defineBool "CMAKE_POSITION_INDEPENDENT_CODE", fPIC + } + c.configure + c.build + c.install + + licenseHeader := string(os.readFile(cppHeader)!) + licenseEnd := strings.index(licenseHeader, "*/") + if licenseEnd < 0 { + panic "C++ header has no license comment" + } + license := strings.trimSpace(licenseHeader[:licenseEnd]) + license = strings.replace(license, "/*", "", 1) + license = strings.replace(license, "\n * ", "\n", -1) + licenseDir := filepath.join(installDir, "licenses") + os.mkdirAll(licenseDir, 0o755)! + os.writeFile(filepath.join(licenseDir, "LICENSE"), []byte(license), 0o644)! + + cppLibs := ["-L$${libdir}", "-l"+cppLibrary] + cLibs := ["-L$${libdir}", "-lqrcodegenc"] + if osName == "linux" || osName == "freebsd" { + cppLibs <- "-lm" + cLibs <- "-lm" + } + + pcDir := filepath.join(installDir, "lib", "pkgconfig") + os.mkdirAll(pcDir, 0o755)! + cppPC := pkgconfig.new( + name = "qrcodegencpp", + description = "High-quality QR Code generator library (C++)", + version = "v1.4.0", + libs = cppLibs, + cflags = ["-I$${includedir}"], + )! + cppOut := os.create(filepath.join(pcDir, "qrcodegencpp.pc"))! + cppPC.writeTo(cppOut)! + cppOut.close()! + + cPC := pkgconfig.new( + name = "qrcodegenc", + description = "High-quality QR Code generator library (C)", + version = "v1.4.0", + libs = cLibs, + cflags = ["-I$${includedir}"], + )! + cOut := os.create(filepath.join(pcDir, "qrcodegenc.pc"))! + cPC.writeTo(cOut)! + cOut.close()! + + pkgconfig.use installDir + ctx.setMetadata pkgconfig.lookup("qrcodegencpp")! +} + +onTest ctx => { + installDir := ctx.outputDir + osName := target.require["os"][0] + shared := target.options["shared"][0] == "ON" + testDir := filepath.join(ctx.SourceDir, "_llar_consumer") + os.mkdirAll(testDir, 0o755)! + + consumer := filepath.join(testDir, "consumer.cpp") + os.writeFile(consumer, []byte(consumerSource), 0o644)! + + pkgconfig.use installDir + flagsFile := filepath.join(testDir, "qrcodegencpp.flags") + os.writeFile(flagsFile, []byte(pkgconfig.lookup("qrcodegencpp")!), 0o644)! + + binary := filepath.join(testDir, "consumer") + args := ["-std=c++11", consumer, "-o", binary, "@"+flagsFile] + newHeader := filepath.join(installDir, "include", "qrcodegen", "qrcodegen.hpp") + if _, err := os.stat(newHeader); os.isNotExist(err) { + args <- "-DQR_USE_OLD_INCLUDE" + } else if err != nil { + panic err + } + exec! "c++", args... + + if shared { + libDir := filepath.join(installDir, "lib") + if osName == "windows" { + runtimeDir := filepath.join(installDir, "bin") + pathValue := runtimeDir + if current := os.getenv("PATH"); current != "" { + pathValue += ";" + current + } + os.setenv("PATH", pathValue)! + } else { + ldPath := libDir + if current := os.getenv("LD_LIBRARY_PATH"); current != "" { + ldPath += ":" + current + } + os.setenv("LD_LIBRARY_PATH", ldPath)! + dyldPath := libDir + if current := os.getenv("DYLD_LIBRARY_PATH"); current != "" { + dyldPath += ":" + current + } + os.setenv("DYLD_LIBRARY_PATH", dyldPath)! + } + } + exec! binary +} diff --git a/nayuki/QR-Code-generator/versions.json b/nayuki/QR-Code-generator/versions.json new file mode 100644 index 0000000..29442fd --- /dev/null +++ b/nayuki/QR-Code-generator/versions.json @@ -0,0 +1,4 @@ +{ + "path": "nayuki/QR-Code-generator", + "deps": {} +} From 8bedb3ebfa221fdf7e3573ef2522af423ea257a9 Mon Sep 17 00:00:00 2001 From: Rick Guo Date: Thu, 10 Sep 2026 13:52:26 +0800 Subject: [PATCH 2/3] audit(qr-code-generator): defer build adapter choice From 279d61ce774346217fae82b3aa6dc2508ebbc8ac Mon Sep 17 00:00:00 2001 From: Rick Guo Date: Thu, 10 Sep 2026 14:17:03 +0800 Subject: [PATCH 3/3] fix(qr-code-generator): isolate build inputs --- .../v1.4.0/qrcodegenerator_llar.gox | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/nayuki/QR-Code-generator/v1.4.0/qrcodegenerator_llar.gox b/nayuki/QR-Code-generator/v1.4.0/qrcodegenerator_llar.gox index a6e2b3f..5609096 100644 --- a/nayuki/QR-Code-generator/v1.4.0/qrcodegenerator_llar.gox +++ b/nayuki/QR-Code-generator/v1.4.0/qrcodegenerator_llar.gox @@ -79,13 +79,27 @@ onBuild ctx => { osName := target.require["os"][0] shared := target.options["shared"][0] == "ON" fPIC := target.options["fPIC"][0] == "ON" + inputDir := os.mkdirTemp("", "qrcode-generator-build-input-*")! + defer os.removeAll(inputDir) + for dirName in ["c", "cpp"] { + sourceDir := filepath.join(ctx.SourceDir, dirName) + destinationDir := filepath.join(inputDir, dirName) + os.mkdirAll(destinationDir, 0o755)! + for path in filepath.glob(filepath.join(sourceDir, "*"))! { + os.writeFile( + filepath.join(destinationDir, filepath.base(path)), + os.readFile(path)!, + 0o644, + )! + } + } cmakeLists := ctx.Proj.readFile("CMakeLists.txt")! - os.writeFile(filepath.join(ctx.SourceDir, "CMakeLists.txt"), cmakeLists, 0o644)! + os.writeFile(filepath.join(inputDir, "CMakeLists.txt"), cmakeLists, 0o644)! - cppHeader := filepath.join(ctx.SourceDir, "cpp", "QrCode.hpp") + cppHeader := filepath.join(inputDir, "cpp", "QrCode.hpp") cppLibrary := "qrcodegen" - newHeader := filepath.join(ctx.SourceDir, "cpp", "qrcodegen.hpp") + newHeader := filepath.join(inputDir, "cpp", "qrcodegen.hpp") if _, err := os.stat(newHeader); err == nil { cppHeader = newHeader cppLibrary = "qrcodegencpp" @@ -101,7 +115,7 @@ onBuild ctx => { } } - c := cmake.new(ctx.SourceDir, filepath.join(ctx.SourceDir, "_build"), installDir) + c := cmake.new(inputDir, filepath.join(inputDir, "_build"), installDir) c.define "CMAKE_INSTALL_LIBDIR", "lib" c.defineBool "BUILD_SHARED_LIBS", shared if osName == "windows" && shared { @@ -165,8 +179,8 @@ onTest ctx => { installDir := ctx.outputDir osName := target.require["os"][0] shared := target.options["shared"][0] == "ON" - testDir := filepath.join(ctx.SourceDir, "_llar_consumer") - os.mkdirAll(testDir, 0o755)! + testDir := os.mkdirTemp("", "qrcode-generator-consumer-*")! + defer os.removeAll(testDir) consumer := filepath.join(testDir, "consumer.cpp") os.writeFile(consumer, []byte(consumerSource), 0o644)!