Skip to content

Commit

Permalink
Added Conan support
Browse files Browse the repository at this point in the history
- Added conanfile.py
- Set C++17 standard
- Added .gitignore (always handy)
- Changed behaviour of finding clipper
  It will first try to find polyclipping the target name
  used by Conan and polyclipping itself. if that fails.
  It will default back to the original behaviour of the
  require_package module which looks for the target
  Clipper::Clipper. This target is then linked to an
  interface library polyclipping::polyclipping allowing
  it to link by both use cases.
  • Loading branch information
jellespijker committed Aug 6, 2021
1 parent 031e4e6 commit 4a3f15d
Show file tree
Hide file tree
Showing 8 changed files with 338 additions and 5 deletions.
123 changes: 123 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
### C++ template
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

### CMake template
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps

### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

.idea/
tmp/*
test_package/build/*
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ cmake_minimum_required(VERSION 3.1)

project(Libnest2D)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED)
# Use C++17 Standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Add our own cmake module path.
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules/)
Expand Down
150 changes: 150 additions & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
from conans import ConanFile, tools
from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake

class libnest2dConan(ConanFile):
name = "libnest2d"
version = "4.10.0"
license = "LGPL-3.0"
author = "Ultimaker B.V."
url = "https://github.com/Ultimaker/libnest2d"
description = "2D irregular bin packaging and nesting library written in modern C++"
topics = ("conan", "cura", "prusaslicer", "nesting", "c++", "bin packaging")
settings = "os", "compiler", "build_type", "arch"
exports = "LICENSE.txt"
options = {
"shared": [True, False],
"fPIC": [True, False],
"tests": [True, False],
"header_only": [True, False],
"geometries": ["clipper", "boost", "eigen"],
"optimizer": ["nlopt", "optimlib"],
"threading": ["std", "tbb", "omp", "none"],
"python_version": "ANY"
}
default_options = {
"shared": True,
"tests": False,
"fPIC": True,
"header_only": False,
"geometries": "clipper",
"optimizer": "nlopt",
"threading": "std",
"python_version": "3.9"
}
scm = {
"type": "git",
"subfolder": ".",
"url": "auto",
"revision": "auto"
}

# TODO: Move lib naming logic to python_requires project
_ext = None

@property
def ext(self):
if self._ext:
return self._ext
self._ext = "lib" if self.settings.os == "Windows" else "a"
if self.options.shared:
if self.settings.os == "Windows":
self._ext = "dll"
elif self.settings.os == "Macos":
self._ext = "dylib"
else:
self._ext = "so"
return self._ext

_lib_name = None

@property
def lib_name(self):
if self._lib_name:
return self._lib_name
ext = "d" if self.settings.build_type == "Debug" else ""
ext += "" if self.settings.os == "Windows" else f".{self.ext}"
self._lib_name = f"{self.name}_{self.options.geometries}_{self.options.optimizer}{ext}"
return self._lib_name

def configure(self):
if self.options.shared or self.settings.compiler == "Visual Studio":
del self.options.fPIC
if self.options.geometries == "clipper":
self.options["clipper"].shared = self.options.shared
self.options["boost"].header_only = True
self.options["boost"].python_version = self.options.python_version
self.options["boost"].shared = self.options.shared
if self.options.optimizer == "nlopt":
self.options["nlopt"].shared = self.options.shared

def build_requirements(self):
self.build_requires("cmake/[>=3.16.2]")
if self.options.tests:
self.build_requires("catch2/[>=2.13.6]", force_host_context=True)

def requirements(self):
if self.options.geometries == "clipper":
self.requires("clipper/[>=6.4.2]")
self.requires("boost/1.70.0")
elif self.options.geometries == "eigen":
self.requires("eigen/[>=3.3.7]")
if self.options.optimizer == "nlopt":
self.requires("nlopt/[>=2.7.0]")

def validate(self):
if self.settings.compiler.get_safe("cppstd"):
tools.check_min_cppstd(self, 17)

def generate(self):
cmake = CMakeDeps(self)
cmake.generate()

tc = CMakeToolchain(self)

# FIXME: This shouldn't be necessary (maybe a bug in Conan????)
if self.settings.compiler == "Visual Studio":
tc.blocks["generic_system"].values["generator_platform"] = None
tc.blocks["generic_system"].values["toolset"] = None

tc.variables["LIBNEST2D_HEADER_ONLY"] = self.options.header_only
if self.options.header_only:
tc.variables["BUILD_SHARED_LIBS"] = False
else:
tc.variables["BUILD_SHARED_LIBS"] = self.options.shared
tc.variables["LIBNEST2D_BUILD_UNITTESTS"] = self.options.tests
tc.variables["LIBNEST2D_GEOMETRIES"] = self.options.geometries
tc.variables["LIBNEST2D_OPTIMIZER"] = self.options.optimizer
tc.variables["LIBNEST2D_THREADING"] = self.options.threading
tc.generate()

_cmake = None

def configure_cmake(self):
if self._cmake:
return self._cmake
self._cmake = CMake(self)
self._cmake.configure()
return self._cmake

def build(self):
cmake = self.configure_cmake()
cmake.build()

def package(self):
cmake = self.configure_cmake()
cmake.install()

def package_info(self):
self.cpp_info.includedirs = ["include"]
if self.in_local_cache:
self.cpp_info.libdirs = ["lib"]
else:
self.cpp_info.libdirs = [f"cmake-build-{self.settings.build_type}".lower()]
self.cpp_info.libs = [self.lib_name]
self.cpp_info.defines.append(f"LIBNEST2D_GEOMETRIES_{self.options.geometries}")
self.cpp_info.defines.append(f"LIBNEST2D_OPTIMIZERS_{self.options.optimizer}")
self.cpp_info.defines.append(f"LIBNEST2D_THREADING_{self.options.threading}")
self.cpp_info.names["cmake_find_package"] = self.name
self.cpp_info.names["cmake_find_package_multi"] = self.name
if self.settings.os in ["Linux", "FreeBSD", "Macos"]:
self.cpp_info.system_libs.append("pthread")
11 changes: 9 additions & 2 deletions include/libnest2d/backends/clipper/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
add_library(clipperBackend INTERFACE)

require_package(Clipper 6.1 REQUIRED)
target_link_libraries(clipperBackend INTERFACE Clipper::Clipper)
find_package(polyclipping 6.1 QUIET)
if(NOT TARGET polyclipping::polyclipping)
message(STATUS "Using require_package to obtain Clipper")
require_package(Clipper 6.1 REQUIRED)
add_library(polyclipping::polyclipping INTERFACE IMPORTED)
target_link_libraries(polyclipping::polyclipping INTERFACE Clipper::Clipper)
endif()
target_link_libraries(clipperBackend INTERFACE polyclipping::polyclipping)


# Clipper backend is not enough on its own, it still need some functions
# from Boost geometry
Expand Down
2 changes: 1 addition & 1 deletion include/libnest2d/backends/clipper/clipper_polygon.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef CLIPPER_POLYGON_HPP
#define CLIPPER_POLYGON_HPP

#include <clipper.hpp>
#include <polyclipping/clipper.hpp>

namespace ClipperLib {

Expand Down
10 changes: 10 additions & 0 deletions test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.13)

project(Libnest2D_example)
set(CMAKE_CXX_STANDARD 17)
find_package(libnest2d REQUIRED)

add_executable(test main.cpp)

target_link_libraries(test PRIVATE libnest2d::libnest2d)
target_include_directories(test PRIVATE ${libnest2d_INCLUDE_DIRS})
35 changes: 35 additions & 0 deletions test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import os
from conans import ConanFile, CMake, tools
from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake


class LibNest2DTestConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"

def build_requirements(self):
self.build_requires("cmake/[>=3.16.2]")

def requirements(self):
self.requires(f"libnest2d/4.10.0@ultimaker/testing")

def generate(self):
cmake = CMakeDeps(self)
cmake.generate()
tc = CMakeToolchain(self)
if self.settings.compiler == "Visual Studio":
tc.blocks["generic_system"].values["generator_platform"] = None
tc.blocks["generic_system"].values["toolset"] = None
tc.generate()

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def imports(self):
self.copy("*.dll", str(self.settings.build_type), "lib")
self.copy("*.dll", str(self.settings.build_type), "lib")
self.copy("*.dylib", str(self.settings.build_type), "lib")

def test(self):
pass # only interested in compiling and linking
6 changes: 6 additions & 0 deletions test_package/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <libnest2d/nester.hpp>

int main(void /*int argc, char **argv*/) {
auto pi = libnest2d::Pi;
return 0;
}

0 comments on commit 4a3f15d

Please sign in to comment.