Skip to content

Commit abb7971

Browse files
committed
Build asar as a static library too.
With these changes, building asar now also builds a static library version of it. The name of the library will be asar-static.lib/libasar-static.a . This behavior is enabled by default (as everything else) and can be disabled. To do this, add -DASAR_GEN_LIB=OFF to the cmake configuration command.
1 parent 9768f19 commit abb7971

File tree

4 files changed

+242
-5
lines changed

4 files changed

+242
-5
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ If you'd rather not build from source, check out the [Releases](https://github.c
1313
## Asar DLL
1414
Asar can also be built as a DLL. This makes it easier and faster to use in other programs (such as a sprite insertion tool). You can find documentation on the DLL API in the respective bindings (asardll.h, asar.cs, asar.py).
1515

16+
## Asar as a static library
17+
Asar can also be build as a static library. All "out-facing" functions are in interface-lib.h. This is useful for embedding Asar in other programs which don't want to use DLLs. The easiest way to add asar as a static library to your project, assuming you are using CMake (at least 3.11), is to use [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) to fetch the source code, then add the following to your CMakeLists.txt:
18+
```CMake
19+
target_include_directories(YourTarget PUBLIC ${asar_SOURCE_DIR}/src)
20+
```
21+
to be able to include the header files. It is also recommended to add `set(ASAR_TESTING_DISABLED TRUE)` to your CMakeLists.txt to disable building tests.
22+
1623
## Folder layout
1724
* `docs` contains the source of the manual and changelog.
1825
(You can view an online version of the manual [here](https://rpghacker.github.io/asar/manual/) and an online version of the changelog [here](https://rpghacker.github.io/asar/changelog/)).

src/asar/CMakeLists.txt

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,34 @@ cmake_minimum_required(VERSION 3.9.0)
55

66
option(ASAR_GEN_EXE "Build Asar standalone application" ON)
77
option(ASAR_GEN_DLL "Build Asar shared library" ON)
8+
option(ASAR_GEN_LIB "Build Asar static library" ON)
89
option(ASAR_COVERAGE "Build Asar with coverage tracking support" OFF)
10+
if (MSVC)
11+
message(STATUS "In MSVC you can override MSVC_LIB_TYPE, valid values are D for dynamic and T for static")
12+
endif()
913

1014
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address")
1115
set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=address")
1216

1317

14-
# This maro sets a number of properties required by both,
18+
# This macro sets a number of properties required by both,
1519
# stand-alone application and library interface
1620

17-
macro(set_asar_shared_properties target)
21+
macro(set_asar_shared_properties target msvc_lib_type_param enable_sanitizer)
22+
if (MSVC)
23+
if (MSVC_LIB_TYPE)
24+
set(msvc_lib_type_param ${MSVC_LIB_TYPE})
25+
endif()
26+
if (NOT (${msvc_lib_type_param} STREQUAL "D" OR ${msvc_lib_type_param} STREQUAL "T"))
27+
message(FATAL_ERROR "Invalid MSVC_LIB_TYPE, valid types are T and D")
28+
endif()
29+
endif()
30+
31+
if (enable_sanitizer)
32+
target_compile_options(${target} PRIVATE "$<$<CONFIG:Debug>:-fsanitize=address>")
33+
target_link_options(${target} PRIVATE "$<$<CONFIG:Debug>:-fsanitize=address>")
34+
endif()
35+
1836
target_include_directories(${target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
1937

2038
if(MSVC)
@@ -56,7 +74,7 @@ macro(set_asar_shared_properties target)
5674
# Enable maximum warning level
5775

5876
if(MSVC)
59-
target_compile_options(${target} PRIVATE /Wall /MT /EHa)
77+
target_compile_options(${target} PRIVATE /Wall "/M${msvc_lib_type_param}$<$<CONFIG:Debug>:d>" /EHa)
6078

6179
# These certainly aren't worth a warning, though
6280
target_compile_options(${target} PRIVATE
@@ -140,6 +158,7 @@ list(
140158
"${CMAKE_CURRENT_SOURCE_DIR}/arch-shared.h"
141159
"${CMAKE_CURRENT_SOURCE_DIR}/virtualfile.h"
142160
"${CMAKE_CURRENT_SOURCE_DIR}/dll_helper.h"
161+
"${CMAKE_CURRENT_SOURCE_DIR}/interface-lib.h"
143162

144163
"${CMAKE_CURRENT_SOURCE_DIR}/std-includes.h"
145164
"${CMAKE_CURRENT_SOURCE_DIR}/platform/file-helpers.h"
@@ -201,7 +220,7 @@ if(ASAR_GEN_EXE)
201220
${ASAR_RESOURCE_FILES}
202221
)
203222

204-
set_asar_shared_properties(asar-standalone)
223+
set_asar_shared_properties(asar-standalone "T" TRUE)
205224

206225
if(ASAR_COVERAGE)
207226
target_compile_options(asar-standalone PRIVATE -fprofile-arcs -ftest-coverage)
@@ -228,7 +247,27 @@ if(ASAR_GEN_DLL)
228247
${ASAR_LIB_RESOURCE_FILES}
229248
)
230249
target_compile_definitions(asar PRIVATE "ASAR_SHARED")
231-
set_asar_shared_properties(asar)
250+
set_asar_shared_properties(asar "T" TRUE)
232251

233252
set_target_properties(asar PROPERTIES PDB_NAME "asar.dll")
234253
endif(ASAR_GEN_DLL)
254+
255+
256+
257+
258+
259+
# Define static library
260+
261+
if (ASAR_GEN_LIB)
262+
add_library(
263+
asar-static STATIC
264+
"${CMAKE_CURRENT_SOURCE_DIR}/interface-lib.cpp"
265+
266+
${ASAR_SHARED_SOURCE_FILES}
267+
${ASAR_LIB_RESOURCE_FILES}
268+
)
269+
target_compile_definitions(asar-static PRIVATE "ASAR_STATIC")
270+
set_asar_shared_properties(asar-static "D" FALSE)
271+
272+
# there's no need to set the PDB name since static libraries don't produce PDBs
273+
endif()

src/asar/interface-lib.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
#if defined(CPPCLI)
1818
#define EXPORT extern "C"
1919
#elif defined(_WIN32)
20+
#ifdef ASAR_SHARED
2021
#define EXPORT extern "C" __declspec(dllexport)
22+
#elif ASAR_STATIC
23+
#define EXPORT extern "C"
24+
#endif
2125
#else
2226
#define EXPORT extern "C" __attribute__ ((visibility ("default")))
2327
#endif

src/asar/interface-lib.h

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#pragma once
2+
#ifndef ASAR_SHARED
3+
#define expectedapiversion 303
4+
5+
#include <stdbool.h>
6+
#include <stddef.h> // for size_t
7+
8+
//These structures are returned from various functions.
9+
struct errordata {
10+
const char* fullerrdata;
11+
const char* rawerrdata;
12+
const char* block;
13+
const char* filename;
14+
int line;
15+
const char* callerfilename;
16+
int callerline;
17+
int errid;
18+
};
19+
20+
struct labeldata {
21+
const char* name;
22+
int location;
23+
};
24+
25+
struct definedata {
26+
const char* name;
27+
const char* contents;
28+
};
29+
30+
struct writtenblockdata {
31+
int pcoffset;
32+
int snesoffset;
33+
int numbytes;
34+
};
35+
36+
enum mappertype {
37+
invalid_mapper,
38+
lorom,
39+
hirom,
40+
sa1rom,
41+
bigsa1rom,
42+
sfxrom,
43+
exlorom,
44+
exhirom,
45+
norom
46+
};
47+
48+
struct warnsetting {
49+
const char* warnid;
50+
bool enabled;
51+
};
52+
53+
struct memoryfile {
54+
const char* path;
55+
const void* buffer;
56+
size_t length;
57+
};
58+
59+
struct patchparams
60+
{
61+
// The size of this struct. Set to (int)sizeof(patchparams).
62+
int structsize;
63+
64+
// Same parameters as asar_patch()
65+
const char* patchloc;
66+
char* romdata;
67+
int buflen;
68+
int* romlen;
69+
70+
// Include paths to use when searching files.
71+
const char** includepaths;
72+
int numincludepaths;
73+
74+
// should everything be reset before patching? Setting it to false will make asar
75+
// act like the currently patched file was directly appended to the previous one.
76+
// note that you can't use the previous run's defines - you can use getalldefines()
77+
// and additional_defines for that.
78+
bool should_reset;
79+
80+
// A list of additional defines to make available to the patch.
81+
const struct definedata* additional_defines;
82+
int additional_define_count;
83+
84+
// Path to a text file to parse standard include search paths from.
85+
// Set to NULL to not use any standard includes search paths.
86+
const char* stdincludesfile;
87+
88+
// Path to a text file to parse standard defines from.
89+
// Set to NULL to not use any standard defines.
90+
const char* stddefinesfile;
91+
92+
// A list of warnings to enable or disable.
93+
// Specify warnings in the format "WXXXX" where XXXX = warning ID.
94+
const struct warnsetting* warning_settings;
95+
int warning_setting_count;
96+
97+
// List of memory files to create on the virtual filesystem.
98+
const struct memoryfile* memory_files;
99+
int memory_file_count;
100+
101+
// Set override_checksum_gen to true and generate_checksum to true/false
102+
// to force generating/not generating a checksum.
103+
bool override_checksum_gen;
104+
bool generate_checksum;
105+
};
106+
107+
#ifdef __cplusplus
108+
extern "C" {
109+
#endif
110+
//Returns the version, in the format major*10000+minor*100+bugfix*1. This means that 1.2.34 would be
111+
// returned as 10234.
112+
int asar_version(void);
113+
114+
//Returns the API version, format major*100+minor. Minor is incremented on backwards compatible
115+
// changes; major is incremented on incompatible changes. Does not have any correlation with the
116+
// Asar version.
117+
//It's not very useful directly, since asar_init() verifies this automatically.
118+
//Calling this one also sets a flag that makes asar_init not instantly return false; this is so
119+
// programs expecting an older API won't do anything unexpected.
120+
int asar_apiversion(void);
121+
122+
//Clears out all errors, warnings and printed statements, and clears the file cache. Not really
123+
// useful, since asar_patch() already does this.
124+
bool asar_reset(void);
125+
126+
//Applies a patch. The first argument is a filename (so Asar knows where to look for incsrc'd
127+
// stuff); however, the ROM is in memory.
128+
//This function assumes there are no headers anywhere, neither in romdata nor the sizes. romlen may
129+
// be altered by this function; if this is undesirable, set romlen equal to buflen.
130+
//The return value is whether any errors appeared (false=errors, call asar_geterrors for details).
131+
// If there is an error, romdata and romlen will be left unchanged.
132+
bool asar_patch(const char* patchloc, char* romdata, int buflen, int* romlen);
133+
134+
// An extended version of asar_patch() with a future-proof parameter format.
135+
bool asar_patch_ex(const struct patchparams* params);
136+
137+
//Returns the maximum possible size of the output ROM from asar_patch(). Giving this size to buflen
138+
// guarantees you will not get any buffer too small errors; however, it is safe to give smaller
139+
// buffers if you don't expect any ROMs larger than 4MB or something.
140+
int asar_maxromsize(void);
141+
142+
//Get a list of all errors.
143+
//All pointers from these functions are valid only until the same function is called again, or until
144+
// asar_patch, asar_reset or asar_close is called, whichever comes first. Copy the contents if you
145+
// need it for a longer time.
146+
const struct errordata* asar_geterrors(int* count);
147+
148+
//Get a list of all warnings.
149+
const struct errordata* asar_getwarnings(int* count);
150+
151+
//Get a list of all printed data.
152+
const char* const* asar_getprints(int* count);
153+
154+
//Get a list of all labels.
155+
const struct labeldata* asar_getalllabels(int* count);
156+
157+
//Get the ROM location of one label. -1 means "not found".
158+
int asar_getlabelval(const char* name);
159+
160+
//Gets the value of a define.
161+
const char* asar_getdefine(const char* name);
162+
163+
//Gets the values and names of all defines.
164+
const struct definedata* asar_getalldefines(int* count);
165+
166+
//Parses all defines in the parameter. The parameter controls whether it'll learn new defines in
167+
// this string if it finds any. Note that it may emit errors.
168+
const char* asar_resolvedefines(const char* data, bool learnnew);
169+
170+
//Parses a string containing math. It automatically assumes global scope (no namespaces), and has
171+
// access to all functions and labels from the last call to asar_patch. Remember to check error to
172+
// see if it's successful (NULL) or if it failed (non-NULL, contains a descriptive string). It does
173+
// not affect asar_geterrors.
174+
double asar_math(const char* math, const char** error);
175+
176+
//Get a list of all the blocks written to the ROM by calls such as asar_patch().
177+
const struct writtenblockdata* asar_getwrittenblocks(int* count);
178+
179+
//Get the mapper currently used by Asar
180+
enum mappertype asar_getmapper(void);
181+
182+
// Generates the contents of a symbols file for in a specific format.
183+
const char* asar_getsymbolsfile(const char* format);
184+
#ifdef __cplusplus
185+
}
186+
#endif
187+
#endif

0 commit comments

Comments
 (0)