Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add CMake support + build on Clang/Windows + build on C++20 + build on Windows ARM64 #28

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
33a924a
fix: ON_Material::MaxShine is not a function
aminya Nov 16, 2021
d7554c7
feat: add CMake support for OpenNURBS
aminya Nov 16, 2021
dccb934
fix: add ON_COMPILER_CLANG for clang compiler
aminya Nov 16, 2021
8bf554b
feat: add cross_dirent
aminya Nov 16, 2021
1a14cc0
fix: add uuid.h requirement for the clang compiler on windows
aminya Nov 16, 2021
190aab0
fix: fix building opennurbs_lock.h
aminya Nov 16, 2021
1845712
fix: handle opengl dependency
aminya Nov 16, 2021
8d68223
fix: fix default constructor issue on linux gcc
aminya Nov 16, 2021
7876620
fix: exclude opennurbs_unicode_cp932 and 949 on non-windows
aminya Nov 16, 2021
e0a1f33
fix: fix zlib build in the shared mode
aminya Nov 16, 2021
3e35580
fix: use unsigned int so that 0xFFFFFFFF can be stored
aminya Nov 18, 2021
39f967a
fix: fix building with clang on Windows
aminya Nov 18, 2021
3122683
fix: specify the output directory for zlib
aminya Nov 18, 2021
10757b5
fix: use lower case opennurbs and upper case for options
aminya Nov 18, 2021
126f16f
fix: fix opennurbs_INCLUDE_DIR
aminya Nov 18, 2021
ba97388
fix: fix building as a shared library with MSVC
aminya Nov 18, 2021
cb2a1e5
fix: fix building on macos by finding uuid
aminya Nov 19, 2021
cd6d4c7
fix: fix building on C++20 - fix removal of shared_ptr.unique
aminya Nov 19, 2021
d8437bf
fix: add the C++ standard if not already specified
aminya Nov 19, 2021
2d873d3
fix: download dirent for windows on demand
aminya Nov 19, 2021
a7e95fc
fix: only include android_uuid on linux and android
aminya Nov 19, 2021
dc9ccbb
docs: add -DCMAKE_FIND_FRAMEWORK=LAST for macos
aminya Nov 19, 2021
fe1747a
fix: fix build for windows arm64
aminya Nov 20, 2021
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
216 changes: 216 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
cmake_minimum_required(VERSION 3.15)

project(opennurbs CXX C)

if(NOT "${CMAKE_CXX_STANDARD}")
# setting the C++ standard if not specified
if(DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION
OR DEFINED CMAKE_CXX20_EXTENSION_COMPILE_OPTION)
set(CXX_LATEST_STANDARD 20)
elseif(DEFINED CMAKE_CXX17_STANDARD_COMPILE_OPTION
OR DEFINED CMAKE_CXX17_EXTENSION_COMPILE_OPTION)
set(CXX_LATEST_STANDARD 17)
elseif(DEFINED CMAKE_CXX14_STANDARD_COMPILE_OPTION
OR DEFINED CMAKE_CXX14_EXTENSION_COMPILE_OPTION)
set(CXX_LATEST_STANDARD 14)
else()
set(CXX_LATEST_STANDARD 11)
endif()
set(CMAKE_CXX_STANDARD ${CXX_LATEST_STANDARD})
endif()
message(STATUS "CMAKE_CXX_STANDARD: ${CXX_LATEST_STANDARD}")

# opennurbs source
file(GLOB opennurbs_SOURCE "${CMAKE_SOURCE_DIR}/*.h"
"${CMAKE_SOURCE_DIR}/*.cpp")
# exclude the examples
list(FILTER opennurbs_SOURCE EXCLUDE REGEX "${CMAKE_SOURCE_DIR}/example*")

if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
list(REMOVE_ITEM opennurbs_SOURCE
"${CMAKE_SOURCE_DIR}/opennurbs_unicode_cp932.cpp")
list(REMOVE_ITEM opennurbs_SOURCE
"${CMAKE_SOURCE_DIR}/opennurbs_unicode_cp949.cpp")
endif()

# remove opennurbs_gl if no opengl
find_package(OpenGL)
if(NOT ${OPENGL_FOUND})
message(WARNING "OpenGL not found. Excluding opennurbs_gl")
list(REMOVE_ITEM opennurbs_SOURCE "${CMAKE_SOURCE_DIR}/opennurbs_gl.cpp")
endif()

# Build the opennurbs library
option(OPENNURBS_SHARED "Build shared libraries" OFF)
if(${OPENNURBS_SHARED})
# if dynamic

# opennurbs shared library
add_library(opennurbs SHARED ${opennurbs_SOURCE})

# define opennurbs_EXPORTS to compile as a shared library
target_compile_definitions(opennurbs PRIVATE OPENNURBS_EXPORTS
ON_COMPILING_OPENNURBS)

# define OPENNURBS_IMORTS for the usage of the library
message(
WARNING
"Define `OPENNURBS_IMORTS` when using the opennurbs.dll before including opennurbs_public.h\n target_compile_definitions(main PUBLIC OPENNURBS_IMPORTS)"
)
else()
# if static

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
add_library(opennurbs STATIC ${opennurbs_SOURCE})
else()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL
"Android")
# Include UUID source (bundled with opennurbs)
file(GLOB UUID_SRC "${CMAKE_SOURCE_DIR}/android_uuid/*.h"
"${CMAKE_SOURCE_DIR}/android_uuid/*.c")
list(REMOVE_ITEM UUID_SRC
"${CMAKE_SOURCE_DIR}/android_uuid/gen_uuid_nt.c")
endif()

# Need to combine all source files for static linking on non-windows
add_library(opennurbs STATIC ${UUID_SRC} ${opennurbs_SOURCE})
endif()

# define ON_COMPILING_OPENNURBS to compile as a static library
target_compile_definitions(opennurbs PRIVATE ON_COMPILING_OPENNURBS)
endif()

# compile definitions
target_compile_definitions(
opennurbs
PRIVATE
OPENNURBS_INPUT_LIBS_DIR="${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>"
UNICODE)

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
# Windows specific

# Fix "WIN32" preprocessor definitions on x64
if(${CMAKE_SIZEOF_VOID_P} EQUAL "8")
message(STATUS "Removing WIN32 definition for 64 bit build of opennurbs")
string(REPLACE "/DWIN32" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
target_compile_definitions(opennurbs PRIVATE WIN64)
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Linux specific

# Linux compiler definitions
target_compile_definitions(opennurbs PRIVATE ON_RUNTIME_LINUX)
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
target_compile_definitions(opennurbs PRIVATE ON_COMPILER_CLANG)
endif()

# Dependencies

# zlib
option({OPENNURBS_EXTERNAL_ZLIB, "use external zlib package" OFF)
if(${OPENNURBS_EXTERNAL_ZLIB} OR ${OPENNURBS_ZLIB_LIB_DIR})
message(STATUS "Using external ZLIB")
find_package(ZLIB REQUIRED)
target_link_libraries(opennurbs PRIVATE ZLIB::ZLIB)
target_compile_definitions(ZLIB::ZLIB PRIVATE MY_ZCALLOC Z_PREFIX)
get_target_property(OPENNURBS_ZLIB_LIB_DIR ZLIB::ZLIB
LIBRARY_OUTPUT_DIRECTORY)
target_compile_definitions(
opennurbs PRIVATE OPENNURBS_ZLIB_LIB_DIR="${OPENNURBS_ZLIB_LIB_DIR}")
else()
# build zlib (bundled with opennurbs)
file(GLOB ZLIB_SOURCE "${CMAKE_SOURCE_DIR}/zlib/*.h"
"${CMAKE_SOURCE_DIR}/zlib/*.c")
add_library(zlib ${ZLIB_SOURCE})
target_compile_definitions(zlib PRIVATE MY_ZCALLOC Z_PREFIX)
set_target_properties(
zlib PROPERTIES ARCHIVE_OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
set(opennurbs_ZLIB_LIB_DIR "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
target_compile_definitions(
opennurbs PRIVATE opennurbs_ZLIB_LIB_DIR=${opennurbs_ZLIB_LIB_DIR})
target_link_libraries(opennurbs PRIVATE zlib)
endif()
# zlib-specific flags for opennurbs
target_compile_definitions(opennurbs PRIVATE MY_ZCALLOC Z_PREFIX)

# shlwapi on windows
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_link_libraries(opennurbs PRIVATE shlwapi)
endif()

# cross_dirent
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
find_path(DIRENT_INCLUDE_DIR dirent.h)
if(${DIRENT_INCLUDE_DIR_FOUND})
target_include_directories(opennurbs PRIVATE ${DIRENT_INCLUDE_DIR_FOUND})
else()
file(DOWNLOAD https://github.com/tronkko/dirent/raw/1.23.2/include/dirent.h
${CMAKE_CURRENT_BINARY_DIR}/_deps/dirent/include/dirent.h)
target_include_directories(
opennurbs PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/_deps/dirent/include/")
endif()
endif()

# uuid with clang on non-linux, android, windows
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux"
AND NOT CMAKE_SYSTEM_NAME STREQUAL "Windows"
AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
# uuid/uuid.h is required by opennurbs
message(STATUS "Finding uuid library")
find_package(UUID QUIET)
if(${UUID_FOUND})
target_include_directories(opennurbs PRIVATE ${UUID_INCLUDE_DIRS})
else()
# find uuid manually
if(NOT UUID_INCLUDE_DIR)
find_path(UUID_INCLUDE_DIR uuid/uuid.h)
endif()
if(EXISTS "${UUID_INCLUDE_DIR}")
include(CheckCXXSymbolExists)

set(UUID_INCLUDE_DIRS ${UUID_INCLUDE_DIR})
set(CMAKE_REQUIRED_INCLUDES ${UUID_INCLUDE_DIRS})
check_cxx_symbol_exists("uuid_generate_random" "uuid/uuid.h"
_uuid_header_only)
if(NOT _uuid_header_only AND NOT UUID_LIBRARY)
include(CheckLibraryExists)
check_library_exists("uuid" "uuid_generate_random" "" _have_libuuid)
if(_have_libuuid)
set(UUID_LIBRARY "uuid")
endif()
endif()
endif()

if(UUID_LIBRARY)
set(UUID_LIBRARIES ${UUID_LIBRARY})
endif()

unset(CMAKE_REQUIRED_INCLUDES)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(uuid DEFAULT_MSG UUID_INCLUDE_DIR)

# finally include it
target_include_directories(opennurbs PRIVATE ${UUID_INCLUDE_DIRS})
endif()
endif()

# OpenGL
if(${OPENGL_FOUND})
target_link_libraries(opennurbs PRIVATE OpenGL::GL OpenGL::GLU)
endif()

# Suppress -Wdefaulted-function-deleted on Clang
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
# TODO fix this
message(WARNING "Suppressing -Wdefaulted-function-deleted for opennurbs")
target_compile_options(opennurbs PRIVATE -Wno-defaulted-function-deleted)
endif()

# Set the outputs of opennurbs CMake
set(opennurbs_LIBRARY ${opennurbs})
set(opennurbs_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}")
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,54 @@ Please see ["Getting started"](https://developer.rhino3d.com/guides/opennurbs/ge

There's also a collection of [example 3dm files](example_files/) available for testing.

## Building Using CMake:

1. Clone the repository
2. `cd` to the root directory of the repository.
3. Run the following to configure the CMake files.
```
cmake -S ./ -B ./build -DCMAKE_FIND_FRAMEWORK=LAST
```

Note: if [ninja-build](https://ninja-build.org/) is installed, you can specify `Ninja` to speed up the build:
```
cmake -S ./ -B ./build -G "Ninja Multi-Config" -DCMAKE_FIND_FRAMEWORK=LAST
```

Note: To use Ninja with the Visual Studio Compiler, open the MSVC command prompt (or run `vcvarsall.bat`), and run:
```
cmake -S ./ -B ./build -G "Ninja Multi-Config" -D CMAKE_CXX_COMPILER=cl -D CMAKE_C_COMPILER=cl
```

Note: `-DCMAKE_FIND_FRAMEWORK=LAST` fixes the issue of the MacOS compilers that choose an incorrect framework to build system headers.

Note: Additionally, pass `-A ARM64` to build for ARM64.

4. Finally, run the following to build the library.
```
cmake --build ./build --config Release
```

### Build as a shared library with CMake

To build as a DLL with Visual Studio, you should add `-DOPENNURBS_SHARED=ON` to the command of step `3`:
```
cmake -S ./ -B ./build -DOPENNURBS_SHARED=ON
```

or with Ninja
```
cmake -S ./ -B ./build -G "Ninja Multi-Config" -D CMAKE_CXX_COMPILER=cl -D CMAKE_C_COMPILER=cl -DOPENNURBS_SHARED=ON
```

Build as usual as we described in step 4.

When using the dll, define `OPENNURBS_IMPORTS` before including `opennurbs_public.h`
```cmake
target_compile_definitions(main PUBLIC OPENNURBS_IMPORTS)
```


## Questions?

For technical support, please head over to [Discourse](https://discourse.mcneel.com/category/opennurbs).
4 changes: 2 additions & 2 deletions opennurbs_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -2133,7 +2133,7 @@ class ON_CLASS ON
// the values. The reason for the gaps between the enum
// values is to leave room for future snaps with prededence
// falling between existing snaps
enum osnap_mode
enum osnap_mode: unsigned int
{
os_none = 0,
os_near = 2,
Expand Down Expand Up @@ -2409,7 +2409,7 @@ class ON_CLASS ON_COMPONENT_INDEX
// Do not change these values; they are stored in 3dm archives
// and provide a persistent way to indentify components of
// complex objects.
enum TYPE
enum TYPE: unsigned int
{
invalid_type = 0,

Expand Down
6 changes: 3 additions & 3 deletions opennurbs_file_utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#pragma ON_PRAGMA_WARNING_BEFORE_DIRTY_INCLUDE
#include <Shlobj.h>
#pragma ON_PRAGMA_WARNING_AFTER_DIRTY_INCLUDE
#if defined(_M_X64) && defined(WIN32) && defined(WIN64)
#if (defined(_M_X64) || defined(_M_ARM64)) && defined(WIN32) && defined(WIN64)
// Shlwapi.h, Shlobj.h and perhaps others, unconditionally define WIN32
#undef WIN32
#endif
Expand Down Expand Up @@ -3302,13 +3302,13 @@ void ON_ContentHash::Dump(

const ON_wString content_time
= ( m_content_time <= 0 )
? L"unknown"
? static_cast<ON_wString>(L"unknown")
: SecondsSinceJanOne1970UTCToString(m_content_time);
text_log.Print(L"Content last modified time = %ls\n",static_cast<const wchar_t*>(content_time));

const ON_wString hash_time
= ( m_hash_time <= 0 )
? L"unknown"
? static_cast<ON_wString>(L"unknown")
: SecondsSinceJanOne1970UTCToString(m_hash_time);
text_log.Print(L"Content hash calculated time = %ls\n",static_cast<const wchar_t*>(content_time));

Expand Down
2 changes: 1 addition & 1 deletion opennurbs_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ void ON_GL( const ON_Material* pMat )
ON_GL( pMat->Diffuse(), alpha, diffuse );
ON_GL( pMat->Specular(), alpha, specular );
ON_GL( pMat->Emission(), alpha, emission );
GLint shine = (GLint)(128.0*(pMat->Shine() / ON_Material::MaxShine()));
GLint shine = (GLint)(128.0*(pMat->Shine() / ON_Material::MaxShine));
if ( shine == 0 ) {
specular[0]=specular[1]=specular[2]=(GLfloat)0.0;
}
Expand Down
8 changes: 4 additions & 4 deletions opennurbs_locale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,7 @@ class ON_CRT_LOCALE

static bool Validate_sprintf_l()
{
#if defined(ON_COMPILER_CLANG) || defined(ON_COMPILER_GNU)
#if (defined(ON_COMPILER_CLANG) || defined(ON_COMPILER_GNU)) && !defined(ON_RUNTIME_WIN)
#if defined(ON_RUNTIME_ANDROID) || defined(ON_RUNTIME_LINUX)
// Test formatted printing
char buffer[64] = { 0 };
Expand All @@ -1368,7 +1368,7 @@ class ON_CRT_LOCALE

static bool Validate_sprintf_s_l()
{
#if defined(ON_COMPILER_CLANG) || defined(ON_COMPILER_GNU)
#if (defined(ON_COMPILER_CLANG) || defined(ON_COMPILER_GNU)) && !defined(ON_RUNTIME_WIN)
#if defined(ON_RUNTIME_ANDROID) || defined(ON_RUNTIME_LINUX)
// Test formatted printing
char buffer[64] = { 0 };
Expand Down Expand Up @@ -1422,7 +1422,7 @@ class ON_CRT_LOCALE

static bool Validate_sscanf_l()
{
#if defined(ON_COMPILER_CLANG) || defined(ON_COMPILER_GNU)
#if (defined(ON_COMPILER_CLANG) || defined(ON_COMPILER_GNU)) && !defined(ON_RUNTIME_WIN)
#if defined(ON_RUNTIME_ANDROID) || defined(ON_RUNTIME_LINUX)
// Test formatted scanning
double a = ON_UNSET_VALUE;
Expand All @@ -1447,7 +1447,7 @@ class ON_CRT_LOCALE

static bool Validate_sscanf_s_l()
{
#if defined(ON_COMPILER_CLANG) || defined(ON_COMPILER_GNU)
#if (defined(ON_COMPILER_CLANG) || defined(ON_COMPILER_GNU)) && !defined(ON_RUNTIME_WIN)
#if defined(ON_RUNTIME_ANDROID) || defined(ON_RUNTIME_LINUX)
// Test formatted scanning
double a = ON_UNSET_VALUE;
Expand Down
4 changes: 2 additions & 2 deletions opennurbs_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ class ON_CLASS ON_Lock
// needs to have dll-interface to be used by clients of class 'ON_Lock'
// m_lock_value is private and all code that manages m_lock_value is explicitly implemented in the DLL.
private:
#if defined(ON_COMPILER_CLANG)
std::atomic<int> m_lock_value;
#if defined(ON_CLANG_CONSTRUCTOR_BUG_INIT)
std::atomic<int> m_lock_value;
#else
std::atomic<int> m_lock_value = ON_Lock::UnlockedValue;
#endif
Expand Down
4 changes: 3 additions & 1 deletion opennurbs_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14831,7 +14831,9 @@ bool ON_MeshCache::Transform(
ON_Mesh* mesh = item->m_mesh_sp.get();
if (nullptr == mesh || mesh->IsEmpty())
continue;
if (false == item->m_mesh_sp.unique())
// NOTE: use_count() == 1 is an approximation in multi-threaded environments
// https:// en.cppreference.com/w/cpp/memory/shared_ptr/unique
if (false == item->m_mesh_sp.use_count() == 1)
{
// make a copy and transform the copy
std::shared_ptr<ON_Mesh>(new ON_Mesh(*mesh)).swap(item->m_mesh_sp);
Expand Down
2 changes: 1 addition & 1 deletion opennurbs_object_history.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ON_Value
// The VALUE_TYPE enum values must never be changed
// because the values are used to determine the parameter
// type during file reading. Additions can be made.
enum VALUE_TYPE
enum VALUE_TYPE: unsigned int
{
no_value_type = 0,

Expand Down
Loading