Skip to content

Commit

Permalink
Feature conan recipe (#1)
Browse files Browse the repository at this point in the history
* Add conan recipe and workflows
* Only build Release and one compiler on each platform
  • Loading branch information
joakimono authored Apr 10, 2024
1 parent 08ded2a commit 5c91425
Show file tree
Hide file tree
Showing 12 changed files with 676 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* eol=lf
51 changes: 51 additions & 0 deletions .github/workflows/ci-conan-gcc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
name: Linux GCC

on: [push, workflow_dispatch]

env:
CONAN_UPLOAD: ${{ secrets.CONAN_URL }}
CONAN_PASSWORD_SINTEF: ${{ secrets.CONAN_PASSWORD }}
CONAN_LOGIN_USERNAME_SINTEF: ${{ secrets.CONAN_USER }}
CONFIG_URL: https://github.com/sintef-ocean/conan-configs.git

jobs:
conan-with-gcc:
name: Conan
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
version: [2.0.4]
build_type: [Release]
profile: [gcc]
compiler_version: [12]
channel: ["${{ (github.head_ref || github.ref_name) == 'master' && 'stable' || 'testing' }}"]
container:
image: conanio/gcc${{ matrix.compiler_version }}-ubuntu18.04
options: -u 0
steps:
- uses: actions/checkout@v3
- name: Install prerequisites
run: |
sudo apt-get update
sudo apt-get install -y jq
pip3 install --upgrade setuptools pip
pip3 install --upgrade conan~=2.0
- name: Configure Conan and package name
run: |
conan remote add sintef ${{ env.CONAN_UPLOAD }}
echo "pkg_name=$(conan inspect -f json . | jq .name -r)" >> $GITHUB_ENV
- name: Conan create
run: |
git config --global --add safe.directory '*'
conan config install ${{ env.CONFIG_URL }} --type git -sf conan2.0
conan config install ${{ env.CONFIG_URL }} --type git -sf profiles -tf profiles
conan create -s build_type=${{ matrix.build_type }} \
-s compiler.version=${{ matrix.compiler_version }} \
-pr:b=${{ matrix.profile }} -pr:h=${{ matrix.profile }} \
--conf tools.build:skip_test=False \
--version ${{ matrix.version }} --user sintef --channel ${{ matrix.channel }} \
-b missing -b outdated -b ${{ env.pkg_name }}* .
- name: Conan upload
run: conan upload --confirm -r sintef ${{ env.pkg_name }}* --force
46 changes: 46 additions & 0 deletions .github/workflows/ci-conan-msvc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
name: Windows MSVC

on: [push, workflow_dispatch]

env:
CONAN_UPLOAD: ${{ secrets.CONAN_URL }}
CONAN_PASSWORD_SINTEF: ${{ secrets.CONAN_PASSWORD }}
CONAN_LOGIN_USERNAME_SINTEF: ${{ secrets.CONAN_USER }}
CONFIG_URL: https://github.com/sintef-ocean/conan-configs.git

jobs:
conan-with-msvc:
name: Conan
runs-on: windows-2022
strategy:
fail-fast: false
matrix:
version: [2.0.4]
build_type: [Release]
profile: [msvc17]
compiler_version: [193]
channel: ["${{ (github.head_ref || github.ref_name) == 'master' && 'stable' || 'testing' }}"]
steps:
- uses: actions/checkout@v4
- name: Install prerequisites
run: |
pip3 install --upgrade setuptools pip
pip3 install --upgrade conan~=2.0
- name: Configure Conan
run: |
conan remote add sintef ${{ env.CONAN_UPLOAD }}
$pkg_name=conan inspect -f json . | jq .name -r
echo "pkg_name=$pkg_name" >> $Env:GITHUB_ENV
- name: Conan create
run: |
conan config install ${{ env.CONFIG_URL }} --type git -sf conan2.0
conan config install ${{ env.CONFIG_URL }} --type git -sf profiles -tf profiles
conan create -s build_type=${{ matrix.build_type }} `
-s compiler.version=${{ matrix.compiler_version }} `
-pr:b=${{ matrix.profile }} -pr:h=${{ matrix.profile }} `
--conf tools.build:skip_test=False `
--version ${{ matrix.version }} --user sintef --channel ${{ matrix.channel }} `
-b missing -b outdated -b ${{ env.pkg_name }}* .
- name: Conan upload
run: conan upload --confirm -r sintef ${{ env.pkg_name }}* --force
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*~
test_package/build/
*.pyc
*.swp
*.swo
__pycache__
temp/
CMakeUserPresets.json
build/
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[![Linux GCC](https://github.com/sintef-ocean/conan-fmu-compliance-checker/workflows/Linux%20GCC/badge.svg)](https://github.com/sintef-ocean/conan-fmu-compliance-checker/actions?query=workflow%3A"Linux+GCC")
[![Windows MSVC](https://github.com/sintef-ocean/conan-fmu-compliance-checker/workflows/Windows%20MSVC/badge.svg)](https://github.com/sintef-ocean/conan-fmu-compliance-checker/actions?query=workflow%3A"Windows+MSVC")

[Conan.io](https://conan.io) recipe for [Modelica tools' FMUComplianceChecker](https://github.com/modelica-tools/FMUComplianceChecker).

## How to use this package

1. Add remote to conan's package [remotes](https://docs.conan.io/2/reference/commands/remote.html)

```bash
$ conan remote add sintef https://artifactory.smd.sintef.no/artifactory/api/conan/conan-local
```

2. Using [*conanfile.txt*](https://docs.conan.io/2/reference/conanfile_txt.html) and *cmake* in your project.

Add *conanfile.txt*:
```
[options]
eprosima-fmu-compliance-checker:with_tools=True
[tool_requires]
cmake/[>=3.25.0]
fmu-compliance-checker/2.0.4@sintef/stable
[layout]
cmake_layout
[generators]
CMakeDeps
CMakeToolchain
VirtualBuildEnv
```

A command line tool `fmuCheck.linux64` or `fmuCheck.win64` is available to check FMUs when virtual environment is active.
There is also a convenience executable target `FMUComplianceChecker::executable` for CMake users that can be used,
as well as `add_fmu_compliance_check(testName fmuPath)`, which adds an `add_test()` using the executable target.
```
find_package(FMUComplianceChecker REQUIRED CONFIG)
add_fmu_compliance_check("MyFMU_is_compliant" ${PATH_TO_FMU})
```

## Package options

| Option | Allowed values | Default |
|--------|----------------|---------|
| fPIC | [True, False] | True |

To build and run tests, set `tools.build:skip_test=False` in `global.conf`, in `[conf]` or
`--conf` as part of `conan install`.

## Known recipe issues
14 changes: 14 additions & 0 deletions conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
sources:
"2.0.4":
url:
- "https://github.com/modelica-tools/FMUComplianceChecker/archive/refs/tags/2.0.4.tar.gz"
sha256: "361a1995fe498f5399092cff119c78a4500abbb7b9ca8c77d48a7de72c294f59"
patches:
"2.0.4":
- patch_file: "patches/0001-add-revised-license.patch"
patch_description: "Add a fixed license"
patch_type: "backport"
patch_source: "https://github.com/modelica-tools/FMUComplianceChecker/pull/36"
- patch_file: "patches/0002-make-conan-changes.patch"
patch_description: "Use fmilibrary as conan requirement and do conanisation changes"
patch_type: "conan"
117 changes: 117 additions & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
from os import path
import posixpath
from conan import ConanFile, conan_version
from conan.tools.microsoft import is_msvc_static_runtime, is_msvc
from conan.tools.files import (
apply_conandata_patches, export_conandata_patches, get, copy, save, rename)
from conan.tools.scm import Version
from conan.tools.env import Environment
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout

required_conan_version = ">=2.0"


class PackageConan(ConanFile):
name = "fmu-compliance-checker"
description = "short description"
license = "BSD-3-Clause"
url = "https://github.com/sintef-ocean/conan-fmu-compliance-checker"
homepage = "https://github.com/modelica-tools/FMUComplianceChecker"
topics = ("fmi", "fmi-standard", "compliance")
package_type = "application"
settings = "os", "arch", "compiler", "build_type"
options = {
"fPIC": [True, False],
}
default_options = {
"fPIC": True,
}

def export_sources(self):
export_conandata_patches(self)
copy(self, "fmuchk.cmake", self.recipe_folder, self.export_sources_folder)

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def configure(self):
self.options["fmilib/*"].with_fmus = True
self.settings.rm_safe("compiler.libcxx")
self.settings.rm_safe("compiler.cppstd")

def package_id(self):
del self.info.settings.compiler
del self.info.settings.build_type

def layout(self):
cmake_layout(self, src_folder="src")

def requirements(self):
self.requires("fmi1/1.0.1")
self.requires("fmi2/2.0.4")
self.requires("fmilib/2.4.1@sintef/testing")
#self.requires("fmilib/2.4.1") # Pending fmilib on conan center index

def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True)

def generate(self):
tc = CMakeToolchain(self)
if is_msvc(self):
tc.variables["FMUCHK_BUILD_WITH_STATIC_RTLIB"] = is_msvc_static_runtime(self)

copy(self, "*.h", self.dependencies["fmi1"].cpp_info.components["cosim"].includedirs[0],
path.join(self.build_folder, "fmis", "FMI1"))
copy(self, "*.h", self.dependencies["fmi2"].cpp_info.includedirs[0],
path.join(self.build_folder, "fmis", "FMI2"))
copy(self, "*.fmu", self.dependencies["fmilib"].cpp_info.resdirs[0],
path.join(self.build_folder, "fmus"), keep_path=False)

tc.variables["FMUCHK_INSTALL_PREFIX"] = posixpath.join(self.build_folder, "install").replace("\\", "/")
tc.variables["FMUCHK_FMI_STANDARD_HEADERS"] = posixpath.join(self.build_folder, "fmis").replace("\\", "/")
tc.variables["FMUCHK_FMIL"] = str(self.build_folder).replace("\\", "/")

tc.generate()
tc = CMakeDeps(self)
tc.generate()

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

if not self.conf.get("tools.build:skip_test", default=True):
env = Environment()
env.define("CTEST_OUTPUT_ON_FAILURE", "ON")
with env.vars(self).apply():
cmake.test()

cmake.install() # It installs to build folder

def package(self):
copy(self, pattern="LICENSE", dst=path.join(self.package_folder, "licenses"),
src=self.source_folder)

copy(self, pattern="*", dst=path.join(self.package_folder, "bin"),
src=path.join(self.build_folder, "install"), keep_path=False)

# This removes a lint hook error
save(self, path.join(self.package_folder, "bin", "fmuCheckExecutable"),
"The executable is named fmuCheck.{os}{arch}")

copy(self, "fmuchk.cmake", self.export_sources_folder,
path.join(self.package_folder, "res"))

def package_info(self):
self.cpp_info.frameworkdirs = []
self.cpp_info.libdirs = []
self.cpp_info.resdirs = ["res"]
self.cpp_info.includedirs = []
self.cpp_info.builddirs = ["res"]

self.cpp_info.set_property("cmake_build_modules",
[path.join("res", "fmuchk.cmake")])

self.cpp_info.set_property("cmake_file_name", "FMUComplianceChecker")
24 changes: 24 additions & 0 deletions fmuchk.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
if(NOT TARGET FMUComplianceChecker::executable)
if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
set(_os "darwin")
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
set(_os "linux")
elseif(WIN32)
set(_os "win")
else()
message(FATAL_ERROR "Unknown or unsupported platform: ${CMAKE_SYSTEM_NAME}")
endif()
math(EXPR _wordSize 8*${CMAKE_SIZEOF_VOID_P})
add_executable(FMUComplianceChecker::executable IMPORTED GLOBAL)
set_target_properties(FMUComplianceChecker::executable
PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/../bin/fmuCheck.${_os}${_wordSize}")
endif()

message(STATUS "Add macro 'add_fmu_compliance_check'")
macro(add_fmu_compliance_check testName fmuPath)
add_test(
NAME "${testName}"
COMMAND FMUComplianceChecker::executable "${fmuPath}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
endmacro()
Loading

0 comments on commit 5c91425

Please sign in to comment.