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

Adding cppad_mixed to conda-forge #28958

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
45ac9d1
First version of cppad-mixed (passes conda build on linux)
bradbell Jan 27, 2025
ebbc82e
First verison of cppad-mixed that passes conda build on windows.
bradbell Jan 27, 2025
891e1ce
cppad-mixed: fix license SPDX Idenfifier.
bradbell Jan 27, 2025
9aa3bce
cppad-mixed: clean up.
bradbell Jan 27, 2025
1cc58c1
Merge branch 'conda-forge:main' into main
bradbell Jan 27, 2025
69e01a8
cppad-mixed: Fix osx cannot find cholmod and unix does not have make.
bradbell Jan 28, 2025
3c283ad
cppad-mixed: 1. Move some requirements from build to host.
bradbell Jan 28, 2025
c11af49
cppad-mixed: requirements: change suitesparse->libcholmod
bradbell Jan 28, 2025
4e22c8a
cppad-mixed: run_test.py: Test installed version (Linux only)
bradbell Jan 30, 2025
b7dae80
cppad-mixed: meta.yaml: add pkg-config and eigen to test requirements.
bradbell Jan 30, 2025
9176c91
Merge branch 'conda-forge:main' into main
bradbell Jan 30, 2025
09c1eb7
Merge branch 'main' of github.com:bradbell/staged-recipes
bradbell Jan 30, 2025
83528bf
cppad-mixed: copy Eigen's source from the internet (to get it in test
bradbell Jan 30, 2025
19460e1
cppad-mixed: run_test.py: if compile error, print message.
bradbell Jan 30, 2025
afe6084
cppad_mixed: run_test.py: Improve error messaging.
bradbell Jan 30, 2025
c28e56b
cppad-mixed: use test.requirements section of meta.yaml.
bradbell Jan 30, 2025
00820e7
cppad-mixed: run_test.py: Remove dead code.
bradbell Jan 30, 2025
2682d00
cppad-mixed: meta.yaml: test: using $CC instead of clang to test.
bradbell Jan 31, 2025
e765c0f
cppad-mixed: Test and fix Darwin (MacOS).
bradbell Jan 31, 2025
9ec9825
cppad-mixed: run_test.py: use cmake to figure out how link and run in
bradbell Feb 1, 2025
bc0f80f
Merge branch 'conda-forge:main' into main
bradbell Feb 1, 2025
3807faf
Merge branch 'main' of github.com:bradbell/staged-recipes
bradbell Feb 1, 2025
ae4dfc9
cppad-mixed: Linux and osx should have make during test.
bradbell Feb 1, 2025
7e3745a
cppad-mixed: Advance to 2025.0.2 to avoid Patching CMakeLists.txt
bradbell Feb 2, 2025
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
39 changes: 39 additions & 0 deletions recipes/cppad-mixed/bld.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
:: echo
echo off

:: build
mkdir build
cd build

:: PKG_CONFIG_PATH
set PKG_CONFIG_PATH=^
%BUILD_PREIX%\Library\lib\pkgconfig;^
%BUILD_PREIX%\Library\share\pkgconfig;
ehco PKG_CONFIG_PATH=%PKG_CONFIG_PATH%

:: cmake
cmake -S %SRC_DIR% -B . ^
-G "NMake Makefiles" ^
-D CMAKE_BUILD_TYPE=Release ^
-D cmake_install_prefix="%PREFIX%\Library" ^
-D cmake_search_prefix="%BUILD_PREFIX%\Library" ^
-D extra_cxx_flags="" ^
-D cmake_libdir=lib ^
-D ldlt_cholmod=yes ^
-D optimize_cppad_function=yes ^
-D for_hes_sparsity=yes
if errorlevel 1 exit 1

:: build
cmake --build . --config Release
if errorlevel 1 exit 1

:: check
cmake --build . --config Release --target check
if errorlevel 1 exit 1

:: install
cmake --build . --config Release --target install
if errorlevel 1 exit 1

echo 'bld.bat: OK'
40 changes: 40 additions & 0 deletions recipes/cppad-mixed/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#! /usr/bin/env bash
set -e -u
echo "build.sh: Start"
#
# PKG_CONFIG_PATH
PKG_CONFIG_PATH="$BUILD_PREFIX/lib/pkgconfig"
PKG_CONFIG_PATH+=":$BUILD_PREFIX/share/pkgconfig"
echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH"
#
# extra_cxx_flags
extra_cxx_flags='-Wpedantic -std=c++11 -Wall -Wshadow -Wconversion'
if [[ "${target_platform}" == osx-* ]]; then
# https://conda-forge.org/docs/maintainer/knowledge_base.html#
# newer-c-features-with-old-sdk
extra_cxx_flags+=" -D_LIBCPP_DISABLE_AVAILABILITY"
fi
extra_cxx_flags+=' -Wno-sign-conversion'
#
# build
mkdir build && cd build
#
# cmake
cmake -S $SRC_DIR -B . \
-G 'Unix Makefiles' \
-D CMAKE_BUILD_TYPE=Release \
-D cmake_install_prefix="$PREFIX" \
-D cmake_search_prefix="$BUILD_PREFIX" \
-D extra_cxx_flags="$extra_cxx_flags" \
-D cmake_libdir=lib \
-D ldlt_cholmod=yes \
-D optimize_cppad_function=yes \
-D for_hes_sparsity=yes
#
# check
make -j4 check
#
# install
make -j4 install
#
echo 'build.sh: Done: OK'
84 changes: 84 additions & 0 deletions recipes/cppad-mixed/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# conda-verify warnings:
#
# [C2115] Found duplicate build requirements: ...
# This warning lists two copies of 'vs2017_win-64' but meta.yaml does not
# specify this requriement (it is comming automatially).
#
# [C2122] Found invalid license family "AGPL-3.0-or-later"
# This is a valid SPDX license identifier; see
# https://spdx.org/licenses/AGPL-3.0-or-later.html
#
{% set name = "cppad-mixed" %}
{% set version = "2025.0.2" %}

package:
name: {{ name }}
version: {{ version }}

source:
url: https://github.com/bradbell/cppad_mixed/archive/{{ version }}.tar.gz
# 2025.0.1
# sha256: 9cb39c79118dd67bc7c22f781aa7fbe9a6792b85d335929bad3ec92a016bf0b4
sha256: a5b8ddd1dc029b4e2f2a168599308c4c4f88b04b39f735709d8f6a986e13ec2e
#

build:
number: 0
# No ABI policy, let's be conservative
run_exports:
- {{ pin_subpackage(name, max_pin='x.x') }}

requirements:
build:
- {{ compiler('c') }}
- {{ stdlib("c") }}
- {{ compiler('cxx') }}
- cmake
- make # [not win]
host:
- pkg-config
- eigen
- cppad
- gsl
- libcholmod
- ipopt
- libopenblas # [linux]

test:
requires:
- {{ compiler('cxx') }}
- cmake
- make # [not win]
- pkg-config
- eigen
- libcholmod
source_files:
# run_test.py assumes this file is in the temporary test directory.
- example/user/no_random.cpp
commands:
#
# cppad_mixed.hpp
- if not exist %PREFIX%\\Library\\include\\cppad\\mixed\\cppad_mixed.hpp exit 1 # [win]
- test -f ${PREFIX}/include/cppad/mixed/cppad_mixed.hpp # [not win]
#
# cppad_mixed.pc
- if not exist %PREFIX%\\Library\\lib\\pkgconfig\\cppad_mixed.pc exit 1 # [win]
- test -f ${PREFIX}/lib/pkgconfig/cppad_mixed.pc # [not_win]
#
# cppad_mixed library
- if not exist %PREFIX%\\Library\\lib\\cppad_mixed.lib exit 1 # [win]
- test -f ${PREFIX}/lib/libcppad_mixed.so # [linux]
- test -f ${PREFIX}/lib/libcppad_mixed.dylib # [osx]

about:
home: https://cppad-mixed.readthedocs.io/stable-2025
license: AGPL-3.0-or-later
license_file: agpl-3.0.txt
summary: C++ Laplace Approximation of Mixed Effects Models

dev_url: https://github.com/bradbell/cppad_mixed
doc_url: https://cppad-mixed.readthedocs.io/stable-2025/

extra:
recipe-maintainers:
- bradbell
159 changes: 159 additions & 0 deletions recipes/cppad-mixed/run_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#! /usr/bin/env python
#
# example_file
# This file must be in the test.sources of meta.yaml
example_file = 'example/user/no_random.cpp'
#
# imports
import sys
import os
import subprocess
import platform
#
# system_command
# 1. print the command before executing it
# 2. double check for errors during the command
# 3 print any error message that is returned before aborting
def system_command(command) :
print( " ".join( command ) )
try :
result = subprocess.run(
command,
check = False,
capture_output = True ,
encoding = 'utf-8',
env = os.environ
)
#
except subprocess.CalledProcessErrror as e :
if e.stdout != None and e.stdout != "" :
print( e.stdout )
sys.exit( e.stderr )
#
if result.stdout != None and result.stdout != "" :
print( result.stdout )
if result.returncode != 0 :
sys.exit( result.stderr )
return result.stdout
#
# main
# Put this code in a function so as to not polute the file namespace
def main() :
#
print( 'run_test.py: Start' )
#
# system
system = platform.system()
assert system in [ 'Linux', 'Darwin', 'Windows' ]
print( f'system = {system}' )
#
# prefix, os.environ['PKG_CONFIG_PATH']
prefix = os.environ['PREFIX']
if system == 'Windows' :
prefix = f'{prefix}\\Library'
os.environ['PKG_CONFIG_PATH'] = f'{prefix}\\lib\\pkgconfig'
os.environ['PKG_CONFIG_PATH'] += f':{prefix}\\share\\pkgconfig'
else :
os.environ['PKG_CONFIG_PATH'] = f'{prefix}/lib/pkgconfig'
os.environ['PKG_CONFIG_PATH'] += f':{prefix}/share/pkgconfig'
prefix = prefix.replace( '\\' , '/' )
#
# cppad_mixed_lib
path_dict = {
'Linux' : 'libcppad_mixed.so' ,
'Darwin' : 'libcppad_mixed.so' ,
'Windows' : 'cppad_mixed.lib'
}
cppad_mixed_lib = path_dict[system]
#
# example_file
assert example_file[-4 :] == '.cpp'
#
# example_function
start = example_file.rfind('/') + 1
example_function = example_file[start : -4] + '_xam'
#
# main.cpp
# Create C++ program that runs the example fucntion and check its result
data = '''
# include <iostream>
# include <cstdlib>
extern bool EXAMPLE_FUNCTION(void);

int main(void)
{ if( ! EXAMPLE_FUNCTION() )
{ std::cout << "EXAMPLE_FUNCTION: Error" << std::endl;
std::exit(1);
}
std::cout << "EXAMPLE_FUNCTION: OK" << std::endl;
std::exit(0);
}
'''
data = data.replace( 'EXAMPLE_FUNCTION', example_function )
with open('main.cpp', 'w') as fobj :
fobj.write(data)
#
# CMakeLists.txt
# Create a project that compiles, links, and runs the C++ program.
data = '''
cmake_minimum_required( VERSION 3.10 )
project( check_install )
#
# include_directories
# link_directories
find_package(PkgConfig)
foreach(pkg gsl eigen3 ipopt cppad cppad_mixed)
pkg_check_modules( ${pkg} QUIET ${pkg} )
if( ${pkg}_FOUND )
message(STATUS "Found ${pkg}.pc file")
else( )
message(STATUS
"Cannot find *.pc file for ${pkg} or a package it requires"
)
message(FATAL_ERROR "PKG_CONFIG_PATH=$ENV{PKG_CONFIG_PATH}")
endif( )
include_directories( SYSTEM ${${pkg}_INCLUDE_DIRS} )
link_directories( ${${pkg}_LIBRARY_DIRS} )
endforeach( )
#
# Kludge: CHOLMOD.pc is missing on conda-forge windows install
include_directories( SYSTEM PREFIX/include/suitesparse )
#
# check_main
add_executable( main main.cpp EXAMPLE_FILE )
target_link_libraries(main ${cppad_mixed_LIBRARIES} )
add_custom_target(check_main main)
'''
data = data.replace( 'EXAMPLE_FILE', example_file )
data = data.replace( 'PREFIX', prefix )
with open('CMakeLists.txt', 'w') as fobj :
fobj.write(data)
#
# build
os.mkdir('build')
os.chdir('build')
#
# cmake
command = [
'cmake',
'-S', '..' ,
'-B', '.' ,
'-D', 'CMAKE_BUILD_TYPE=Release' ,
]
system_command( command )
#
# check_main
command = [
'cmake',
'--build', '.',
'--config', 'Release',
'--target', 'check_main'
]
system_command( command )
#
print( 'run_test.py: OK' )
#
#
# python main
if __name__ == "__main__" :
main()