Compare commits

...

2 Commits

Author SHA1 Message Date
4d04b38d52 feat: continue improving BMapSharp.
- add BMFileWriter in BMapSharp.
2024-10-27 11:41:49 +08:00
623334f863 feat: update BMapSharp.
- update the function calling in BMapSharp.BMFileReader. (hope JIT can optimize my bad code served for beauty)
- remove outdated content in COMPILE.md
2024-10-24 16:39:11 +08:00
3 changed files with 118 additions and 117 deletions

View File

@ -58,11 +58,11 @@ namespace BMapSharp {
// the native memory we created is a simple array and each item is a pointer to a NULL-terminated UTF8 string. // the native memory we created is a simple array and each item is a pointer to a NULL-terminated UTF8 string.
// Please note the array self is also NULL-terminated otherwise we don't know its length. // Please note the array self is also NULL-terminated otherwise we don't know its length.
public nint MarshalManagedToNative(object ManagedObj) { public IntPtr MarshalManagedToNative(object ManagedObj) {
// Check marshaler type // Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return nint.Zero; if (!m_MarshalerType.HasFlag(MarshalerType.In)) return IntPtr.Zero;
// Check nullptr object. // Check nullptr object.
if (ManagedObj is null) return nint.Zero; if (ManagedObj is null) return IntPtr.Zero;
// Check argument type. // Check argument type.
string[] castManagedObj = ManagedObj as string[]; string[] castManagedObj = ManagedObj as string[];
if (castManagedObj is null) if (castManagedObj is null)
@ -70,45 +70,45 @@ namespace BMapSharp {
// Allocate string items first // Allocate string items first
int szArrayItemCount = castManagedObj.Length; int szArrayItemCount = castManagedObj.Length;
int szArrayItemSize = Marshal.SizeOf<nint>(); int szArrayItemSize = Marshal.SizeOf<IntPtr>();
nint[] apString = new nint[szArrayItemCount]; IntPtr[] apString = new IntPtr[szArrayItemCount];
for (int i = 0; i < szArrayItemCount; ++i) { for (int i = 0; i < szArrayItemCount; ++i) {
// Check null string // Check null string
string stringObj = castManagedObj[i]; string stringObj = castManagedObj[i];
if (stringObj is null) apString[i] = nint.Zero; if (stringObj is null) apString[i] = IntPtr.Zero;
else apString[i] = BMStringMarshaler.ToNative(stringObj); else apString[i] = BMStringMarshaler.ToNative(stringObj);
} }
// Allocate array pointer now. // Allocate array pointer now.
nint pArray = Marshal.AllocHGlobal(szArrayItemSize * (szArrayItemCount + 1)); IntPtr pArray = Marshal.AllocHGlobal(szArrayItemSize * (szArrayItemCount + 1));
// Copy string pointer data // Copy string pointer data
Marshal.Copy(apString, 0, pArray, szArrayItemCount); Marshal.Copy(apString, 0, pArray, szArrayItemCount);
// Setup NULL ternimal // Setup NULL ternimal
Marshal.WriteIntPtr(pArray + (szArrayItemSize * szArrayItemCount), nint.Zero); Marshal.WriteIntPtr(pArray + (szArrayItemSize * szArrayItemCount), IntPtr.Zero);
// Return value // Return value
return pArray; return pArray;
} }
public object MarshalNativeToManaged(nint pNativeData) { public object MarshalNativeToManaged(IntPtr pNativeData) {
// Check marshaler type // Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null; if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
// Check nullptr // Check nullptr
if (pNativeData == nint.Zero) return null; if (pNativeData == IntPtr.Zero) return null;
// Get the length of array // Get the length of array
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData); int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
int szArrayItemSize = Marshal.SizeOf<nint>(); int szArrayItemSize = Marshal.SizeOf<IntPtr>();
// Prepare array cache and read it. // Prepare array cache and read it.
nint[] apString = new nint[szArrayItemCount]; IntPtr[] apString = new IntPtr[szArrayItemCount];
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount); Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
// Iterate the array and process each string one by one. // Iterate the array and process each string one by one.
string[] ret = new string[szArrayItemCount]; string[] ret = new string[szArrayItemCount];
for (int i = 0; i < szArrayItemCount; ++i) { for (int i = 0; i < szArrayItemCount; ++i) {
// Get string pointer // Get string pointer
nint pString = apString[i]; IntPtr pString = apString[i];
if (pString == nint.Zero) { if (pString == IntPtr.Zero) {
ret[i] = null; ret[i] = null;
continue; continue;
} }
@ -120,25 +120,25 @@ namespace BMapSharp {
return ret; return ret;
} }
public void CleanUpNativeData(nint pNativeData) { public void CleanUpNativeData(IntPtr pNativeData) {
// Check marshaler type // Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return; if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
// Check nullptr // Check nullptr
if (pNativeData == nint.Zero) return; if (pNativeData == IntPtr.Zero) return;
// Get the length of array // Get the length of array
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData); int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
int szArrayItemSize = Marshal.SizeOf<nint>(); int szArrayItemSize = Marshal.SizeOf<IntPtr>();
// Prepare array cache and read it. // Prepare array cache and read it.
nint[] apString = new nint[szArrayItemCount]; IntPtr[] apString = new IntPtr[szArrayItemCount];
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount); Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
// Free array self // Free array self
Marshal.FreeHGlobal(pNativeData); Marshal.FreeHGlobal(pNativeData);
// Iterate the string pointer array and free them one by one. // Iterate the string pointer array and free them one by one.
foreach (nint pString in apString) { foreach (IntPtr pString in apString) {
// Free string pointer // Free string pointer
if (pString == nint.Zero) continue; if (pString == IntPtr.Zero) continue;
Marshal.FreeHGlobal(pString); Marshal.FreeHGlobal(pString);
} }
} }
@ -157,9 +157,9 @@ namespace BMapSharp {
/// </summary> /// </summary>
/// <param name="ptr">The pointer to array for checking.</param> /// <param name="ptr">The pointer to array for checking.</param>
/// <returns>The length of array (NULL terminal exclusive).</returns> /// <returns>The length of array (NULL terminal exclusive).</returns>
internal static int GetArrayLength(nint ptr) { internal static int GetArrayLength(IntPtr ptr) {
int count = 0, unit = Marshal.SizeOf<nint>(); int count = 0, unit = Marshal.SizeOf<IntPtr>();
while (Marshal.ReadIntPtr(ptr) != nint.Zero) { while (Marshal.ReadIntPtr(ptr) != IntPtr.Zero) {
ptr += unit; ptr += unit;
++count; ++count;
} }
@ -181,11 +181,11 @@ namespace BMapSharp {
m_MarshalerType = marshaler_type; m_MarshalerType = marshaler_type;
} }
public nint MarshalManagedToNative(object ManagedObj) { public IntPtr MarshalManagedToNative(object ManagedObj) {
// Check marshaler type // Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return nint.Zero; if (!m_MarshalerType.HasFlag(MarshalerType.In)) return IntPtr.Zero;
// Check requirements. // Check requirements.
if (ManagedObj is null) return nint.Zero; if (ManagedObj is null) return IntPtr.Zero;
string castManagedObj = ManagedObj as string; string castManagedObj = ManagedObj as string;
if (castManagedObj is null) if (castManagedObj is null)
throw new MarshalDirectiveException("BMStringMarshaler must be used on a string."); throw new MarshalDirectiveException("BMStringMarshaler must be used on a string.");
@ -193,20 +193,20 @@ namespace BMapSharp {
return BMStringMarshaler.ToNative(castManagedObj); return BMStringMarshaler.ToNative(castManagedObj);
} }
public object MarshalNativeToManaged(nint pNativeData) { public object MarshalNativeToManaged(IntPtr pNativeData) {
// Check marshaler type // Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null; if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
// Check nullptr // Check nullptr
if (pNativeData == nint.Zero) return null; if (pNativeData == IntPtr.Zero) return null;
// Call self // Call self
return BMStringMarshaler.ToManaged(pNativeData); return BMStringMarshaler.ToManaged(pNativeData);
} }
public void CleanUpNativeData(nint pNativeData) { public void CleanUpNativeData(IntPtr pNativeData) {
// Check marshaler type // Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return; if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
// Check nullptr // Check nullptr
if (pNativeData == nint.Zero) return; if (pNativeData == IntPtr.Zero) return;
// Free native pointer // Free native pointer
Marshal.FreeHGlobal(pNativeData); Marshal.FreeHGlobal(pNativeData);
} }
@ -225,7 +225,7 @@ namespace BMapSharp {
/// </summary> /// </summary>
/// <param name="ptr">The pointer for checking.</param> /// <param name="ptr">The pointer for checking.</param>
/// <returns>The length of C style string (NUL exclusive).</returns> /// <returns>The length of C style string (NUL exclusive).</returns>
internal static int GetCStringLength(nint ptr) { internal static int GetCStringLength(IntPtr ptr) {
int count = 0, unit = Marshal.SizeOf<byte>(); int count = 0, unit = Marshal.SizeOf<byte>();
while (Marshal.ReadByte(ptr) != (byte)0) { while (Marshal.ReadByte(ptr) != (byte)0) {
ptr += unit; ptr += unit;
@ -240,13 +240,13 @@ namespace BMapSharp {
/// </summary> /// </summary>
/// <param name="obj">String object. Caller must make sure this object is not null.</param> /// <param name="obj">String object. Caller must make sure this object is not null.</param>
/// <returns>The created native data pointer.</returns> /// <returns>The created native data pointer.</returns>
internal static nint ToNative(string obj) { internal static IntPtr ToNative(string obj) {
// Encode string first // Encode string first
byte[] encString = Encoding.UTF8.GetBytes(obj); byte[] encString = Encoding.UTF8.GetBytes(obj);
// Allocate string memory with extra NUL. // Allocate string memory with extra NUL.
int szStringItemCount = encString.Length; int szStringItemCount = encString.Length;
int szStringItemSize = Marshal.SizeOf<byte>(); int szStringItemSize = Marshal.SizeOf<byte>();
nint pString = Marshal.AllocHGlobal(szStringItemSize * (szStringItemCount + 1)); IntPtr pString = Marshal.AllocHGlobal(szStringItemSize * (szStringItemCount + 1));
// Copy encoded string data // Copy encoded string data
Marshal.Copy(encString, 0, pString, szStringItemCount); Marshal.Copy(encString, 0, pString, szStringItemCount);
// Setup NUL // Setup NUL
@ -260,7 +260,7 @@ namespace BMapSharp {
/// </summary> /// </summary>
/// <param name="ptr">Native pointer holding string data. Caller must make sure this pointer is not nullptr.</param> /// <param name="ptr">Native pointer holding string data. Caller must make sure this pointer is not nullptr.</param>
/// <returns>The extracted managed string data.</returns> /// <returns>The extracted managed string data.</returns>
internal static string ToManaged(nint ptr) { internal static string ToManaged(IntPtr ptr) {
// Get the length of given string. // Get the length of given string.
int szStringItemCount = BMStringMarshaler.GetCStringLength(ptr); int szStringItemCount = BMStringMarshaler.GetCStringLength(ptr);
int szStringItemSize = Marshal.SizeOf<byte>(); int szStringItemSize = Marshal.SizeOf<byte>();

View File

@ -94,16 +94,19 @@ namespace BMapSharp.BMapWrapper {
#endregion #endregion
} }
public abstract class AbstractCKObject { public abstract class AbstractCKObject : SafeHandle {
internal AbstractCKObject(IntPtr raw_pointer, uint ckid) { // Same as AbstractPointer, but not own this handle.
m_RawPointer = raw_pointer; internal AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(Utils.INVALID_PTR, false) {
this.handle = raw_pointer;
m_CKID = ckid; m_CKID = ckid;
} }
private readonly IntPtr m_RawPointer; public override bool IsInvalid => this.handle == Utils.INVALID_PTR;
protected override bool ReleaseHandle() => throw new NotImplementedException();
private readonly uint m_CKID; private readonly uint m_CKID;
protected bool isValid() => m_RawPointer != Utils.INVALID_PTR && m_RawPointer != Utils.INVALID_CKID; protected bool isValid() => this.handle != Utils.INVALID_PTR && m_CKID != Utils.INVALID_CKID;
protected IntPtr getPointer() => m_RawPointer; protected IntPtr getPointer() => this.handle;
protected uint getCKID() => m_CKID; protected uint getCKID() => m_CKID;
// private uint m_CKID; // private uint m_CKID;
@ -143,14 +146,14 @@ namespace BMapSharp.BMapWrapper {
#region Misc #region Misc
public override int GetHashCode() => HashCode.Combine(m_RawPointer, m_CKID); public override int GetHashCode() => HashCode.Combine(this.handle, m_CKID);
public override string ToString() => $"{m_RawPointer}, {m_CKID}"; public override string ToString() => $"{this.handle}, {m_CKID}";
#endregion #endregion
} }
public class BMObject : AbstractCKObject { public class BMObject : AbstractCKObject {
internal BMObject(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public string GetName() { public string GetName() {
BMapException.ThrowIfFailed(BMap.BMObject_GetName( BMapException.ThrowIfFailed(BMap.BMObject_GetName(
@ -166,27 +169,27 @@ namespace BMapSharp.BMapWrapper {
} }
public class BMTexture : BMObject { public class BMTexture : BMObject {
internal BMTexture(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMTexture(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
} }
public class BMMaterial : BMObject { public class BMMaterial : BMObject {
internal BMMaterial(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMMaterial(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
} }
public class BMMesh : BMObject { public class BMMesh : BMObject {
internal BMMesh(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMMesh(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
} }
public class BM3dObject : BMObject { public class BM3dObject : BMObject {
internal BM3dObject(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BM3dObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
} }
public class BMGroup : BMObject { public class BMGroup : BMObject {
internal BMGroup(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMGroup(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
} }
public sealed class BMFileReader : AbstractPointer { public sealed class BMFileReader : AbstractPointer {
private static IntPtr AllocateHandle(string file_name, string temp_folder, string texture_folder, string[] encodings) { private static IntPtr allocateHandle(string file_name, string temp_folder, string texture_folder, string[] encodings) {
BMapException.ThrowIfFailed(BMap.BMFile_Load( BMapException.ThrowIfFailed(BMap.BMFile_Load(
file_name, temp_folder, texture_folder, file_name, temp_folder, texture_folder,
Utils.BMapSharpCallback, Utils.BMapSharpCallback,
@ -196,71 +199,77 @@ namespace BMapSharp.BMapWrapper {
return out_file; return out_file;
} }
protected override bool ReleaseHandle() { protected override bool ReleaseHandle() {
return BMap.BMFile_Free(this.handle); return BMap.BMFile_Free(this.getPointer());
} }
public BMFileReader(string file_name, string temp_folder, string texture_folder, string[] encodings) public BMFileReader(string file_name, string temp_folder, string texture_folder, string[] encodings)
: base(AllocateHandle(file_name, temp_folder, texture_folder, encodings)) {} : base(allocateHandle(file_name, temp_folder, texture_folder, encodings)) { }
public uint GetTextureCount() { private delegate bool FctProtoGetCount(IntPtr bmf, out uint cnt);
BMapException.ThrowIfFailed(BMap.BMFile_GetTextureCount(this.getPointer(), out uint out_count)); private delegate bool FctProtoGetObject(IntPtr bmf, uint idx, out uint id);
private delegate T FctProtoCreateInstance<T>(IntPtr bmf, uint id);
private uint getCKObjectCount(FctProtoGetCount fct_cnt) {
BMapException.ThrowIfFailed(fct_cnt(this.getPointer(), out uint out_count));
return out_count; return out_count;
} }
public IEnumerable<BMTexture> GetTextures() { private IEnumerable<T> getCKObjects<T>(FctProtoGetCount fct_cnt, FctProtoGetObject fct_obj, FctProtoCreateInstance<T> fct_crt) {
uint count = GetTextureCount(); uint count = getCKObjectCount(fct_cnt);
for (uint i = 0; i < count; ++i) { for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_GetTexture(this.getPointer(), i, out uint out_id)); BMapException.ThrowIfFailed(fct_obj(this.getPointer(), i, out uint out_id));
yield return new BMTexture(this.getPointer(), out_id); yield return fct_crt(this.getPointer(), out_id);
} }
} }
public uint GetMaterialCount() { public uint GetTextureCount() =>
BMapException.ThrowIfFailed(BMap.BMFile_GetMaterialCount(this.getPointer(), out uint out_count)); getCKObjectCount(BMap.BMFile_GetTextureCount);
return out_count; public IEnumerable<BMTexture> GetTextures() =>
} getCKObjects<BMTexture>(BMap.BMFile_GetTextureCount, BMap.BMFile_GetTexture, (bmf, id) => new BMTexture(bmf, id));
public IEnumerable<BMMaterial> GetMaterials() { public uint GetMaterialCount() =>
uint count = GetMaterialCount(); getCKObjectCount(BMap.BMFile_GetMaterialCount);
for (uint i = 0; i < count; ++i) { public IEnumerable<BMMaterial> GetMaterials() =>
BMapException.ThrowIfFailed(BMap.BMFile_GetMaterial(this.getPointer(), i, out uint out_id)); getCKObjects<BMMaterial>(BMap.BMFile_GetMaterialCount, BMap.BMFile_GetMaterial, (bmf, id) => new BMMaterial(bmf, id));
yield return new BMMaterial(this.getPointer(), out_id); public uint GetMeshCount() =>
} getCKObjectCount(BMap.BMFile_GetMeshCount);
public IEnumerable<BMMesh> GetMeshes() =>
getCKObjects<BMMesh>(BMap.BMFile_GetMeshCount, BMap.BMFile_GetMesh, (bmf, id) => new BMMesh(bmf, id));
public uint Get3dObjectCount() =>
getCKObjectCount(BMap.BMFile_Get3dObjectCount);
public IEnumerable<BM3dObject> Get3dObjects() =>
getCKObjects<BM3dObject>(BMap.BMFile_Get3dObjectCount, BMap.BMFile_Get3dObject, (bmf, id) => new BM3dObject(bmf, id));
public uint GetGroupCount() =>
getCKObjectCount(BMap.BMFile_GetGroupCount);
public IEnumerable<BMGroup> GetGroups() =>
getCKObjects<BMGroup>(BMap.BMFile_GetGroupCount, BMap.BMFile_GetGroup, (bmf, id) => new BMGroup(bmf, id));
} }
public uint GetMeshCount() { public sealed class BMFileWriter : AbstractPointer {
BMapException.ThrowIfFailed(BMap.BMFile_GetMeshCount(this.getPointer(), out uint out_count)); private static IntPtr allocateHandle(string temp_folder, string texture_folder, string[] encodings) {
return out_count; BMapException.ThrowIfFailed(BMap.BMFile_Create(
temp_folder, texture_folder,
Utils.BMapSharpCallback,
(uint)encodings.Length, encodings,
out IntPtr out_file
));
return out_file;
} }
public IEnumerable<BMMesh> GetMeshes() { protected override bool ReleaseHandle() {
uint count = GetMeshCount(); return BMap.BMFile_Free(this.getPointer());
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_GetMesh(this.getPointer(), i, out uint out_id));
yield return new BMMesh(this.getPointer(), out_id);
}
}
public uint Get3dObjectCount() {
BMapException.ThrowIfFailed(BMap.BMFile_Get3dObjectCount(this.getPointer(), out uint out_count));
return out_count;
}
public IEnumerable<BM3dObject> Get3dObjects() {
uint count = Get3dObjectCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_Get3dObject(this.getPointer(), i, out uint out_id));
yield return new BM3dObject(this.getPointer(), out_id);
}
}
public uint GetGroupCount() {
BMapException.ThrowIfFailed(BMap.BMFile_GetGroupCount(this.getPointer(), out uint out_count));
return out_count;
}
public IEnumerable<BMGroup> GetGroups() {
uint count = GetGroupCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_GetGroup(this.getPointer(), i, out uint out_id));
yield return new BMGroup(this.getPointer(), out_id);
} }
public BMFileWriter(string temp_folder, string texture_folder, string[] encodings)
: base(allocateHandle(temp_folder, texture_folder, encodings)) { }
private delegate bool FctProtoCreateObject(IntPtr bmf, out uint id);
private delegate T FctProtoCreateInstance<T>(IntPtr bmf, uint id);
private T createCKObject<T>(FctProtoCreateObject fct_crt, FctProtoCreateInstance<T> fct_inst) {
BMapException.ThrowIfFailed(fct_crt(this.getPointer(), out uint out_id));
return fct_inst(this.getPointer(), out_id);
} }
public BMTexture CreateTexture() => createCKObject<BMTexture>(BMap.BMFile_CreateTexture, (bmf, id) => new BMTexture(bmf, id));
public BMMaterial CreateMaterial() => createCKObject<BMMaterial>(BMap.BMFile_CreateMaterial, (bmf, id) => new BMMaterial(bmf, id));
public BMMesh CreateMesh() => createCKObject<BMMesh>(BMap.BMFile_CreateMesh, (bmf, id) => new BMMesh(bmf, id));
public BM3dObject Create3dObject() => createCKObject<BM3dObject>(BMap.BMFile_Create3dObject, (bmf, id) => new BM3dObject(bmf, id));
public BMGroup CreateGroup() => createCKObject<BMGroup>(BMap.BMFile_CreateGroup, (bmf, id) => new BMGroup(bmf, id));
} }
} }

View File

@ -42,7 +42,7 @@ First, create subdirectory `Bin/build` and `Bin/install`.
Then enter subdirectory `Bin/build` and use following command to configure CMake: Then enter subdirectory `Bin/build` and use following command to configure CMake:
- Windows: `cmake -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=OFF -DSTB_IMAGE_PATH=<path-to-stb> -DYYCC_PATH=<path-to-yycc-install> -DZLIB_HEADER_PATH=<path-to-zlib-hdr> -DZLIB_BINARY_PATH=<path-to-zlib-bin> ../..` - Windows (MSVC): `cmake -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=OFF -DSTB_IMAGE_PATH=<path-to-stb> -DYYCC_PATH=<path-to-yycc-install> -DZLIB_HEADER_PATH=<path-to-zlib-hdr> -DZLIB_BINARY_PATH=<path-to-zlib-bin> ../..`
- non-Windows: `cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=OFF -DSTB_IMAGE_PATH=<path-to-stb> -DYYCC_PATH=<path-to-yycc-install> ../..` - non-Windows: `cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=OFF -DSTB_IMAGE_PATH=<path-to-stb> -DYYCC_PATH=<path-to-yycc-install> ../..`
The arguments in command should be replaced by: The arguments in command should be replaced by:
@ -62,8 +62,8 @@ The switches in command can be switched as you wish:
Execute following command to build libcmo21. Execute following command to build libcmo21.
* Windows`cmake --build . --config RelWithDebInfo` * Windows: `cmake --build . --config RelWithDebInfo`
* non-Windows`cmake --build .` * non-Windows: `cmake --build .`
### Build Type ### Build Type
@ -76,11 +76,3 @@ Currently the CMake install script still has some bugs and can not work as expec
## Note ## Note
You may face issue when compiling this program on Linux or macOS because I develop this project on Windows frequently. The compatibility with Linux will only be checked just before releasing. And I don't have any Apple device to check the compatibility with macOS. So, for Linux issue, please report it directly and I will try to fix. For macOS bug, PR is welcomed. You may face issue when compiling this program on Linux or macOS because I develop this project on Windows frequently. The compatibility with Linux will only be checked just before releasing. And I don't have any Apple device to check the compatibility with macOS. So, for Linux issue, please report it directly and I will try to fix. For macOS bug, PR is welcomed.
It can be compiled on Windows via sln file. You should set up `LibRef.props` when using sln file to build this project on Windows.
You also can use CMake file to compile this project on Linux or anything else platform. However CMake may not be updated in time because I develop this project on Windows frequently.
You may need use this command to configure CMake: `cmake .. -DSTB_IMAGE_PATH="/path/to/stb-image" -DCMAKE_BUILD_TYPE=Release`