5

*NIX プラットフォームでソース コードをビルドする一般的な方法の 1 つは、configureスクリプトを使用することです。内部では、configure は一連のテスト プログラムを構築して、どのライブラリにアクセスできるかを判断しようとします。次に、特定の「依存関係」が欠落している場合に、プログラマーが代替案を提供したり、ライブラリ/プログラムの簡素化されたバージョンを構築したりできるように、一連のマクロを条件付きで定義するプロジェクトに含まれるヘッダー ファイルを生成します。を使用して機能的に同等のものはありnumpy.distutilsますか?

例として、これが私のものsetup.pyです:

from numpy.distutils.misc_util import Configuration

def configuration(parent_package='',top_path=None):
    config = Configuration('pyggcm',parent_package,top_path)

    #TODO: Currently, I have some macros to conditionally build the seek-code
    #Unfortunately, that's not the best solution (by far).  Perhaps if we
    #changed to using stream access it would work better, without the need
    #for these silly macros.
    config.add_extension('_fortfile',sources=['_fortfile/_fortfile.F90'],
                         define_macros=[
                             ('FSEEKABLE',1),  #compiler provides fseek and ftell
                             ('HAVE_STREAM',1) #compiler provides access='stream' for opening files. (f2003 standard)
                             ])  

    config.add_extension('jrrle',sources=['jrrle/jrrle.f90'])
    config.add_scripts(['scripts/ggcm_timehist',
                        'scripts/ggcm_plasmasheet',
                        'scripts/ggcm_plot'])
    return config


from numpy.distutils.core import setup    
setup(configuration=configuration)

これは無条件にFSEEKABLEコードをビルドするため、ユーザーの Fortran コンパイラがサポートしていない場合は手動で編集する必要があります (マクロはGNU 組み込み関数をラップします) fseekftellFortran コンパイラがこれらの組み込み関数を提供しているかどうかを判断する方法はありますか?

4

2 に答える 2

1

これを試して:

import os
import shutil
import tempfile
from distutils.ccompiler import new_compiler

def hasfunction(cc, funcname, include=None, extra_postargs=None):
    tmpdir = tempfile.mkdtemp(prefix='hasfunction-')
    devnull = oldstderr = None
    try:
        try:
            fname = os.path.join(tmpdir, 'funcname.c')
            f = open(fname, 'w')
            if include is not None:
                f.write('#include %s\n' % include)
            f.write('int main(void) {\n')
            f.write('    %s;\n' % funcname)
            f.write('}\n')
            f.close()
            devnull = open(os.devnull, 'w')
            oldstderr = os.dup(sys.stderr.fileno())
            os.dup2(devnull.fileno(), sys.stderr.fileno())
            objects = cc.compile([fname], output_dir=tmpdir,
                                 extra_postargs=extra_postargs)
            cc.link_executable(objects, os.path.join(tmpdir, 'a.out'))
        except Exception as e:
            return False
        return True
    finally:
        if oldstderr is not None:
            os.dup2(oldstderr, sys.stderr.fileno())
        if devnull is not None:
            devnull.close()
        shutil.rmtree(tmpdir)

例:

def detect_sse3():
    "Does this compiler support SSE3 intrinsics?"
    compiler = new_compiler()
    return hasfunction(compiler, '__m128 v; _mm_hadd_ps(v,v)',
                       include='<pmmintrin.h>',
                       extra_postargs=['-msse3'])
于 2013-10-27T10:30:04.930 に答える
0

コードフラグメントをファイルに生成し、エラーコードをチェックしてコンパイルしてみるのが通常のアプローチであり、うまく機能するはずですが、distutilsの一部としてこれを行った人は誰もいません。おそらく python ベースのビルド ツールの 1 つがこれをサポートしているのではないかと思います。あなたの最善の策は GNU autoconfigure だと思います。

于 2013-06-28T18:23:10.020 に答える