diff options
author | Damien Zammit <damien@zamaudio.com> | 2019-12-22 15:06:47 +1100 |
---|---|---|
committer | Damien Zammit <damien@zamaudio.com> | 2019-12-22 15:06:47 +1100 |
commit | c7c085f57f7a65d411d755c1e180d6efa91f51b1 (patch) | |
tree | ff2b74e374e3f0ac3d6df39aa63c68d2c0a4c5f4 | |
parent | 96cbf6c89dd2c132ccf2a32f619ce887c706cc19 (diff) |
utils/aurez: Add AuRez for cross-compiling AUs
-rw-r--r-- | utils/aurez/AuRez.cc | 223 | ||||
-rw-r--r-- | utils/aurez/AuRsrc.cc | 62 | ||||
-rw-r--r-- | utils/aurez/AuRsrc.h | 60 | ||||
-rw-r--r-- | utils/aurez/LICENSE | 23 | ||||
-rw-r--r-- | utils/aurez/MacRsrc.cc | 260 | ||||
-rw-r--r-- | utils/aurez/MacRsrc.h | 55 | ||||
-rw-r--r-- | utils/aurez/Makefile | 26 | ||||
-rw-r--r-- | utils/aurez/README.md | 5 |
8 files changed, 714 insertions, 0 deletions
diff --git a/utils/aurez/AuRez.cc b/utils/aurez/AuRez.cc new file mode 100644 index 00000000..f4ef0f95 --- /dev/null +++ b/utils/aurez/AuRez.cc @@ -0,0 +1,223 @@ +// Copyright Jean Pierre Cimalando 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "MacRsrc.h" +#include "AuRsrc.h" +#include <getopt.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +void show_help() +{ + fprintf(stderr, + "Usage: AuRez <type-id> <subtype-id> <manufacturer-id>\n" + " [-o|--output <file.rsrc>]\n" + " [-A|--arch <arch>]* [-M|--manufacturer <name>] [-P|--product <name>] [-V|--version <x.y.z>]\n" + " [-e|--entry <function>] [-v|--view-entry <function>]\n" + " [-n|--no-view]" + "\n" + "Acceptable values for <type-id>:\n" + " `auou` Output `aumu` MusicDevice `aumf` MusicEffect\n" + " `aufc` FormatConverter `aufx` Effect `aumx` Mixer\n" + " `aupn` Panner `auol` OfflineEffect `augn` Generator\n"); +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + show_help(); + return 0; + } + + unsigned archs = 0; + const char *manufacturer = nullptr; + const char *product = nullptr; + const char *version_string = nullptr; + const char *plugin_entry = nullptr; + const char *view_entry = nullptr; + const char *output_file = nullptr; + bool view_enabled = true; + + static const option cmd_opts[] = { + {"output", 1, nullptr, 'o'}, + {"arch", 1, nullptr, 'A'}, + {"manufacturer", 1, nullptr, 'M'}, + {"product", 1, nullptr, 'P'}, + {"version", 1, nullptr, 'V'}, + {"entry", 1, nullptr, 'e'}, + {"view-entry", 1, nullptr, 'v'}, + {"no-view", 0, nullptr, 'n'}, + {} + }; + + for (int c; (c = getopt_long(argc, argv, "o:A:M:P:V:e:v:n", cmd_opts, nullptr)) != -1;) { + switch (c) { + case 'o': + output_file = optarg; + break; + case 'A': { + const char *arch = optarg; + if (!strcmp(arch, "i386")) + archs |= (1 << ArchIA32NativeEntryPoint); + else if (!strcmp(arch, "x86_64")) + archs |= (1 << ArchX86_64NativeEntryPoint); + else if (!strcmp(arch, "ppc")) + archs |= (1 << ArchPowerPCNativeEntryPoint); + else if (!strcmp(arch, "ppc64")) + archs |= (1 << ArchPowerPC64NativeEntryPoint); + else { + fprintf(stderr, "Unrecognized architecture `%s`\n", arch); + return 1; + } + break; + } + case 'M': { + manufacturer = optarg; + break; + } + case 'P': { + product = optarg; + break; + } + case 'V': { + version_string = optarg; + break; + } + case 'e': { + plugin_entry = optarg; + break; + } + case 'v': { + view_entry = optarg; + break; + } + case 'n': { + view_enabled = false; + break; + } + default: + show_help(); + return 1; + } + } + + if (optind != argc - 3) { + fprintf(stderr, "AuRez requires 3 positional arguments.\n"); + show_help(); + return 1; + } + + const char *arg_type = argv[optind]; + const char *arg_subtype = argv[optind + 1]; + const char *arg_manuf = argv[optind + 2]; + + if (strlen(arg_type) > 4) { + fprintf(stderr, "The type-id cannot be longer than 4 characters.\n"); + return 1; + } + if (strlen(arg_subtype) > 4) { + fprintf(stderr, "The subtype-id cannot be longer than 4 characters.\n"); + return 1; + } + if (strlen(arg_manuf) > 4) { + fprintf(stderr, "The manufacturer-id cannot be longer than 4 characters.\n"); + return 1; + } + + char type[4] = {' ', ' ', ' ', ' '}; + char subtype[4] = {' ', ' ', ' ', ' '}; + char manuf[4] = {' ', ' ', ' ', ' '}; + memcpy(type, arg_type, strlen(arg_type)); + memcpy(subtype, arg_subtype, strlen(arg_subtype)); + memcpy(manuf, arg_manuf, strlen(arg_manuf)); + + if (archs == 0) { + archs = (1 << ArchIA32NativeEntryPoint) | (1 << ArchX86_64NativeEntryPoint); + fprintf(stderr, "Architectures not set, defaulting to i386 and x86_64\n"); + } + if (!manufacturer) { + manufacturer = "ACME"; + fprintf(stderr, "Manufacturer not set, defaulting to `%s`\n", manufacturer); + } + if (!product) { + product = "Biniou"; + fprintf(stderr, "Product not set, defaulting to `%s`\n", product); + } + if (!version_string) { + version_string = "1.0.0"; + fprintf(stderr, "Version not set, defaulting to `%s`\n", version_string); + } + if (!plugin_entry) { + plugin_entry = "AUEntry"; + fprintf(stderr, "Plugin entry not set, defaulting to `%s`\n", plugin_entry); + } + if (view_enabled && !view_entry) { + view_entry = "AUViewEntry"; + fprintf(stderr, "View entry not set, defaulting to `%s`\n", view_entry); + } + + uint16_t id_plugin = 1000; + uint16_t id_plugin_info = id_plugin + 1; + uint16_t id_view = 2000; + uint16_t id_view_info = id_view + 1; + + unsigned versionX, versionY, versionZ; + if (sscanf(version_string, "%u.%u.%u", &versionX, &versionY, &versionZ) != 3) { + fprintf(stderr, "The version string is not in `x.y.z` format.\n"); + return 1; + } + + if (versionX > 255 || versionY > 255 || versionZ > 255) { + fprintf(stderr, "The version components cannot be greater than 255.\n"); + return 1; + } + + uint32_t version = (versionX << 16) | (versionY << 8) | versionZ; + + MacRsrc rsrc; + + rsrc.AddResource( + id_plugin, ResPurgeable, "STR", "", MakeSTR(std::string(manufacturer) + ": " + product)); + rsrc.AddResource( + id_plugin_info, ResPurgeable, "STR", "", MakeSTR(product)); + rsrc.AddResource( + id_plugin, 0, "dlle", "", MakeCSTR(plugin_entry)); + rsrc.AddResource( + id_plugin, 0, "thng", std::string(manufacturer) + ": " + product, + MakeThng(archs, id_plugin, id_plugin_info, version, type, subtype, manuf)); + + if (view_enabled) { + rsrc.AddResource( + id_view, ResPurgeable, "STR", "", MakeSTR(std::string(manufacturer) + ": " + product + " View")); + rsrc.AddResource( + id_view_info, ResPurgeable, "STR", "", MakeSTR(std::string(manufacturer) + ": " + product + " View")); + rsrc.AddResource( + id_view, 0, "dlle", "", MakeCSTR(view_entry)); + rsrc.AddResource( + id_view, 0, "thng", std::string(manufacturer) + ": " + product + " View", + MakeThng(archs, id_view, id_view_info, version, "auvw", subtype, manuf)); + } + + FILE *fh = output_file ? fopen(output_file, "wb") : stdout; + if (!fh) { + fprintf(stderr, "Cannot open output file."); + return 1; + } + + if (isatty(fileno(fh))) + rsrc.DisplayAsText(fh); + else { + if (rsrc.Write(fh) == -1) { + fprintf(stderr, "Cannot write resource output."); + return 1; + } + } + + if (fh != stdout) + fclose(fh); + + return 0; +} diff --git a/utils/aurez/AuRsrc.cc b/utils/aurez/AuRsrc.cc new file mode 100644 index 00000000..ab7933e8 --- /dev/null +++ b/utils/aurez/AuRsrc.cc @@ -0,0 +1,62 @@ +// Copyright Jean Pierre Cimalando 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "AuRsrc.h" +#include <string.h> +#include <arpa/inet.h> + +std::vector<uint8_t> MakeSTR(const std::string &string) +{ + size_t size = string.size(); + if (size > 255) + size = 255; + + std::vector<uint8_t> pstr; + pstr.reserve(size + 1); + pstr.push_back((uint8_t)size); + pstr.insert(pstr.end(), &string[0], &string[size]); + + return pstr; +} + +std::vector<uint8_t> MakeCSTR(const std::string &string) +{ + const char *cstr = string.c_str(); + return std::vector<uint8_t>(cstr, cstr + string.size() + 1); +} + +std::vector<uint8_t> MakeThng( + unsigned archs, uint16_t id_plugin, uint16_t id_info, uint32_t version, + const char type[4], const char subtype[4], const char manuf[4]) +{ + unsigned num_archs = 0; + for (unsigned a = ArchsBegin; a < ArchsEnd; ++a) + num_archs += (archs & (1 << a)) != 0; + + std::vector<uint8_t> thng_buf(sizeof(CarbonThng) + num_archs * sizeof(CarbonThng::PlatformInfo)); + CarbonThng *thng = (CarbonThng *)thng_buf.data(); + memcpy(thng->Type, type, 4); + memcpy(thng->Subtype, subtype, 4); + memcpy(thng->Manufacturer, manuf, 4); + memcpy(thng->NameType, "STR ", 4); + thng->NameId = htons(id_plugin); + memcpy(thng->InfoType, "STR ", 4); + thng->InfoId = htons(id_info); + thng->ComponentVersion = htonl(version); + thng->RegistrationFlags = htonl(9); // componentHasMultiplePlatforms | componentDoAutoVersion + thng->PlatformInfoCount = htonl(num_archs); + + for (unsigned a = ArchsBegin, i = 0; a < ArchsEnd; ++a) { + if ((archs & (1 << a)) == 0) continue; + CarbonThng::PlatformInfo &pl = thng->PlatformInfos[i]; + pl.ComponentFlags = htonl(0x10000000); // cmpThreadSafeOnMac + memcpy(pl.CodeType, "dlle", 4); + pl.CodeId = htons(id_plugin); + pl.PlatformType = htons(a); + ++i; + } + + return thng_buf; +} diff --git a/utils/aurez/AuRsrc.h b/utils/aurez/AuRsrc.h new file mode 100644 index 00000000..d55c8b9f --- /dev/null +++ b/utils/aurez/AuRsrc.h @@ -0,0 +1,60 @@ +// Copyright Jean Pierre Cimalando 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#pragma once +#include <string> +#include <vector> +#include <stdint.h> + +std::vector<uint8_t> MakeSTR(const std::string &string); +std::vector<uint8_t> MakeCSTR(const std::string &string); + +enum CarbonArchitecture +{ + ArchsBegin = 1, + Arch68k = ArchsBegin, + ArchPowerPC, + ArchInterpreted, + ArchWin32, + ArchPowerPCNativeEntryPoint, + ArchIA32NativeEntryPoint, + ArchPowerPC64NativeEntryPoint, + ArchX86_64NativeEntryPoint, + ArchsEnd +}; + +#pragma pack(push, 1) +struct CarbonThng +{ + char Type[4]; + char Subtype[4]; + char Manufacturer[4]; + uint32_t ComponentFlags; + uint32_t ComponentFlagsMask; + char CodeType[4]; + uint16_t CodeId; + char NameType[4]; + uint16_t NameId; + char InfoType[4]; + uint16_t InfoId; + char IconType[4]; + uint16_t IconId; + uint32_t ComponentVersion; + uint32_t RegistrationFlags; + uint16_t IconFamilyId; + struct PlatformInfo { + uint32_t ComponentFlags; + char CodeType[4]; + uint16_t CodeId; + uint16_t PlatformType; + }; + uint32_t PlatformInfoCount; + PlatformInfo PlatformInfos[]; +}; +#pragma pack(pop) + +std::vector<uint8_t> MakeThng( + unsigned archs, uint16_t id_plugin, uint16_t id_info, uint32_t version, + const char type[4], const char subtype[4], const char manuf[4]); diff --git a/utils/aurez/LICENSE b/utils/aurez/LICENSE new file mode 100644 index 00000000..36b7cd93 --- /dev/null +++ b/utils/aurez/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utils/aurez/MacRsrc.cc b/utils/aurez/MacRsrc.cc new file mode 100644 index 00000000..4d4fc858 --- /dev/null +++ b/utils/aurez/MacRsrc.cc @@ -0,0 +1,260 @@ +// Copyright Jean Pierre Cimalando 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "MacRsrc.h" +#include <algorithm> +#include <stdio.h> +#include <string.h> + +MacRsrc::MacRsrc() +{ +} + +MacRsrc::~MacRsrc() +{ +} + +size_t MacRsrc::GetResourceCount() const +{ + return fResources.size(); +} + +const MacRsrc::Resource &MacRsrc::GetResource(size_t index) +{ + return fResources[index]; +} + +uint16_t MacRsrc::FileAttributes() const +{ + return fFileAttributes; +} + +void MacRsrc::SetFileAttributes(uint16_t attr) +{ + fFileAttributes = attr; +} + +int MacRsrc::AddResource(uint32_t id, uint8_t attr, const char *type, std::string name, const std::vector<uint8_t> &data) +{ + Resource res; + res.Id = id; + res.Attr = attr; + + size_t TypeLen = strlen(type); + if (TypeLen > 4) + return -1; + + for (size_t i = 0; i < TypeLen; ++i) + res.Type[i] = type[i]; + for (size_t i = TypeLen; i < 4; ++i) + res.Type[i] = ' '; + + res.Name = std::move(name); + res.DataOffset = fData.size(); + res.DataSize = data.size(); + fData.insert(fData.end(), data.begin(), data.end()); + + fResources.push_back(std::move(res)); + return 0; +} + +static int WriteU16(uint32_t value, FILE *stream) +{ + for (unsigned i = 0; i < 2; ++i) { + if (fputc((value >> (8 * (1 - i))) & 0xff, stream) == EOF) + return -1; + } + return 0; +} + +static int WriteU24(uint32_t value, FILE *stream) +{ + for (unsigned i = 0; i < 3; ++i) { + if (fputc((value >> (8 * (2 - i))) & 0xff, stream) == EOF) + return -1; + } + return 0; +} + +static int WriteU32(uint32_t value, FILE *stream) +{ + for (unsigned i = 0; i < 4; ++i) { + if (fputc((value >> (8 * (3 - i))) & 0xff, stream) == EOF) + return -1; + } + return 0; +} + +int MacRsrc::Write(FILE *stream) const +{ + const std::vector<Resource> &Resources = fResources; + size_t NumResources = Resources.size(); + + // Header (fill later) + off_t HeaderPos = ftell(stream); + for (unsigned i = 0; i < 256; ++i) + fputc(0, stream); + + // Resource data + off_t ResourceDataPos = ftell(stream); + for (size_t i = 0; i < NumResources; ++i) { + const Resource &Res = Resources[i]; + WriteU32(Res.DataSize, stream); + fwrite(&fData[Res.DataOffset], 1, Res.DataSize, stream); + } + + // Resource map (fill later) + off_t ResourceMapPos = ftell(stream); + for (unsigned i = 0; i < 22; ++i) + fputc(0, stream); + WriteU16(fFileAttributes, stream); + off_t ResourceMapOffsetsPos = ftell(stream); + WriteU16(0, stream); // fill later + WriteU16(0, stream); // fill later + + // Type list (fill later) + struct TypeInfo + { + std::array<char, 4> Type; + std::vector<size_t> Resources; + off_t ReferenceListOffsetPos = 0; + }; + + std::vector<TypeInfo> TypeList; + for (size_t R_i = 0; R_i < NumResources; ++R_i) { + std::array<char, 4> Type = Resources[R_i].Type; + auto Position = std::find_if( + TypeList.begin(), TypeList.end(), + [Type](const TypeInfo &x) -> bool { return x.Type == Type; }); + if (Position == TypeList.end()) { + TypeInfo Info; + Info.Type = Type; + TypeList.push_back(Info); + Position = TypeList.end() - 1; + } + Position->Resources.push_back(R_i); + } + + off_t TypeListPos = ftell(stream); + size_t NumTypes = TypeList.size(); + + WriteU16((uint16_t)NumTypes - 1, stream); + for (size_t i = 0; i < NumTypes; ++i) { + fwrite(TypeList[i].Type.data(), 1, 4, stream); + WriteU16((uint16_t)TypeList[i].Resources.size() - 1, stream); + TypeList[i].ReferenceListOffsetPos = ftell(stream); + WriteU16(0, stream); // fill later + } + + // Reference list (fill later) + std::vector<off_t> ReferenceNamePos(NumResources, -1); + std::vector<size_t> ReferenceListOffset(NumTypes); + for (size_t T_i = 0; T_i < NumTypes; ++T_i) { + const TypeInfo &Type = TypeList[T_i]; + ReferenceListOffset[T_i] = ftell(stream) - TypeListPos; + for (size_t R_i : Type.Resources) { + const Resource &Res = Resources[R_i]; + WriteU16(Res.Id, stream); + ReferenceNamePos[R_i] = ftell(stream); + WriteU16((uint16_t)-1, stream); // fill later + fputc(Res.Attr, stream); + WriteU24(Res.DataOffset + R_i * sizeof(uint32_t), stream); + WriteU32(0, stream); + } + } + + // Resource name list + off_t NameListPos = ftell(stream); + std::vector<size_t> NameOffset(NumResources); + for (size_t R_i = 0; R_i < NumResources; ++R_i) { + const Resource &Res = Resources[R_i]; + if (Res.Name.empty()) + NameOffset[R_i] = (size_t)-1; + else { + NameOffset[R_i] = ftell(stream) - NameListPos; + fputc(Res.Name.size(), stream); + fwrite(Res.Name.data(), 1, Res.Name.size(), stream); + } + } + + off_t EndFilePos = ftell(stream); + + // Fill reference list offsets + for (size_t R_i = 0; R_i < NumResources; ++R_i) { + fseek(stream, ReferenceNamePos[R_i], SEEK_SET); + WriteU16((uint16_t)NameOffset[R_i], stream); + } + + // Fill type list offsets + for (size_t T_i = 0; T_i < NumTypes; ++T_i) { + fseek(stream, TypeList[T_i].ReferenceListOffsetPos, SEEK_SET); + WriteU16(ReferenceListOffset[T_i], stream); + } + + // Fill resource map offsets + fseek(stream, ResourceMapOffsetsPos, SEEK_SET); + WriteU16(TypeListPos - ResourceMapPos, stream); + WriteU16(NameListPos - ResourceMapPos, stream); + + // Fill header + fseek(stream, HeaderPos, SEEK_SET); + WriteU32(ResourceDataPos - HeaderPos, stream); + WriteU32(ResourceMapPos - HeaderPos, stream); + WriteU32(ResourceMapPos - ResourceDataPos, stream); + WriteU32(EndFilePos - ResourceMapPos, stream); + + if (fflush(stream) != 0) + return -1; + + return 0; +} + +static void HexDump(FILE *stream, const uint8_t *data, size_t size) +{ + size_t addr = 0; + + while (addr < size) { + fprintf(stream, "%08lx|", addr); + + for (size_t a = addr; a < addr + 16; ++a) { + if (a < size) + fprintf(stream, " %02X", data[a]); + else + fprintf(stream, " "); + } + + fprintf(stream, " | "); + + for (size_t a = addr; a < addr + 16; ++a) { + if (a < size) { + uint8_t ch = data[a]; + bool printable = ch >= 0x20 && ch < 0x7f; + fprintf(stream, "%c", printable ? ch : '.'); + } + else + fprintf(stream, " "); + } + + fprintf(stream, "\n"); + addr += 16; + } +} + +void MacRsrc::DisplayAsText(FILE *stream) const +{ + const std::vector<Resource> &Resources = fResources; + size_t NumResources = Resources.size(); + + for (size_t i = 0; i < NumResources; ++i) { + const Resource &Res = Resources[i]; + + if (i > 0) + fprintf(stream, "\n"); + + fprintf(stream, "Resource %u `%.4s` Attributes:$%02x Name:`%s`\n", + Res.Id, Res.Type.data(), Res.Attr, Res.Name.c_str()); + HexDump(stream, &fData[Res.DataOffset], Res.DataSize); + } +} diff --git a/utils/aurez/MacRsrc.h b/utils/aurez/MacRsrc.h new file mode 100644 index 00000000..3a947524 --- /dev/null +++ b/utils/aurez/MacRsrc.h @@ -0,0 +1,55 @@ +// Copyright Jean Pierre Cimalando 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#pragma once +#include <string> +#include <vector> +#include <array> +#include <stdint.h> + +class MacRsrc +{ +public: + MacRsrc(); + ~MacRsrc(); + + struct Resource; + + size_t GetResourceCount() const; + const Resource &GetResource(size_t index); + + uint16_t FileAttributes() const; + void SetFileAttributes(uint16_t attr); + + int AddResource(uint32_t id, uint8_t attr, const char *type, std::string name, const std::vector<uint8_t> &data); + + int Write(FILE *stream) const; + void DisplayAsText(FILE *stream) const; + + struct Resource + { + uint32_t Id = 0; + uint8_t Attr = 0; + std::array<char, 4> Type; + std::string Name; + size_t DataOffset = 0; + size_t DataSize = 0; + }; + +private: + uint16_t fFileAttributes = 0; + std::vector<Resource> fResources; + std::vector<uint8_t> fData; +}; + +enum MacResourceAttribute +{ + ResSysHeap = 64, + ResPurgeable = 32, + ResLocked = 16, + ResProtected = 8, + ResPreload = 4, + ResChanged = 2 +}; diff --git a/utils/aurez/Makefile b/utils/aurez/Makefile new file mode 100644 index 00000000..122a2615 --- /dev/null +++ b/utils/aurez/Makefile @@ -0,0 +1,26 @@ +PREFIX ?= /usr/local +CXX ?= g++ +CXXFLAGS ?= -O2 -g -Wall -std=c++11 +LDFLAGS ?= + +all: bin/AuRez + +clean: + rm -rf bin obj + +install: all + install -D -m 755 bin/AuRez $(DESTDIR)$(PREFIX)/bin/AuRez + +.PHONY: all clean install + +obj/%.o: %.cc + @mkdir -p obj + $(CXX) $(CXXFLAGS) -c -o $@ $< + +bin/AuRez: obj/AuRez.o obj/AuRsrc.o obj/MacRsrc.o + @mkdir -p bin + $(CXX) $(LDFLAGS) -o $@ $^ + +AuRez.cc: AuRsrc.h MacRsrc.h +AuRsrc.cc: AuRsrc.h +MacRsrc.cc: MacRsrc.h diff --git a/utils/aurez/README.md b/utils/aurez/README.md new file mode 100644 index 00000000..4f7ea048 --- /dev/null +++ b/utils/aurez/README.md @@ -0,0 +1,5 @@ +# AuRez +Portable compiler of AudioUnit resource forks + +This creates the `rsrc` file required by AudioUnit, without depending on the `Rez` utility from Xcode. +It facilitates cross-compilation of AudioUnits. |