2

我正在使用 Python 2.7 distutils 来构建 C++ 库。但是每次我发出构建命令时

python setup.py build

所有目标文件都会重新构建,即使 c++ 文件没有改变。
我的一个朋友告诉我,Python 2.6 不会出现这种情况。

我对这个董事会的问题:

  1. 有没有办法强制 distutils 增量构建代码?
  2. 如果无法增量构建代码,
    2.1。有没有办法使用 Python 2.6 distutils 或
    2.2。是否可以更改 Python 2.7 distuils 包?
4

2 回答 2

2

你不能那样做。编译后的 .o 文件以简单且错误的方式重用,因此在 2.7 中删除了此优化。有关详细信息,请参阅http://bugs.python.org/issue5372

于 2012-10-27T17:58:52.107 回答
1

我不知道这是否能解决您的确切问题,但我有一个类似的问题,我通过以下方法修复了:

我有一个相对较大的 C++ 包,它带有一个基于 cython 的 python 包装器。我最终做的是使用 CMake(它进行增量构建)将包编译为静态库,然后使用 cython 包装器在静态库中链接——尽管为了安全起见,它每次都重新编译,但它非常稳定。我的 setup.py 被黑是为了接受一些告诉 CMake 做什么的标志。

我的 setup.py 中处理 CMake 部分(https://github.com/CoolProp/CoolProp/blob/master/wrappers/Python/setup.py)的相关片段如下所示:

# ******************************
#       CMAKE OPTIONS
# ******************************

# Example using CMake to build static library:
# python setup.py install --cmake-compiler vc9 --cmake-bitness 64

if '--cmake-compiler' in sys.argv:
    i = sys.argv.index('--cmake-compiler')
    sys.argv.pop(i)
    cmake_compiler = sys.argv.pop(i)
else:
    cmake_compiler = ''

if '--cmake-bitness' in sys.argv:
    i = sys.argv.index('--cmake-bitness')
    sys.argv.pop(i)
    cmake_bitness = sys.argv.pop(i)
else:
    cmake_bitness = ''

USING_CMAKE = cmake_compiler or cmake_bitness

cmake_config_args = []
cmake_build_args = ['--config','"Release"']
STATIC_LIBRARY_BUILT = False
if USING_CMAKE:

    # Always force build since any changes in the C++ files will not force a rebuild
    touch('CoolProp/CoolProp.pyx')

    if 'clean' in sys.argv:
        if os.path.exists('cmake_build'):
            print('removing cmake_build folder...')
            shutil.rmtree('cmake_build')
            print('removed.')

    if cmake_compiler == 'vc9':
        if cmake_bitness == '32':
            generator = ['-G','"Visual Studio 9 2008"']
        elif cmake_bitness == '64':
            generator = ['-G','"Visual Studio 9 2008 Win64"']
        else:
            raise ValueError('cmake_bitness must be either 32 or 64; got ' + cmake_bitness)
    elif cmake_compiler == 'vc10':
        if cmake_bitness == '32':
            generator = ['-G','"Visual Studio 10 2010"']
        elif cmake_bitness == '64':
            generator = ['-G','"Visual Studio 10 2010 Win64"']
        else:
            raise ValueError('cmake_bitness must be either 32 or 64; got ' + cmake_bitness)
    else:
        raise ValueError('cmake_compiler [' + cmake_compiler + '] is invalid')

    cmake_build_dir = os.path.join('cmake_build', '{compiler}-{bitness}bit'.format(compiler=cmake_compiler, bitness=cmake_bitness))
    if not os.path.exists(cmake_build_dir):
        os.makedirs(cmake_build_dir)
    subprocess.check_call(' '.join(['cmake','../../../..','-DCOOLPROP_STATIC_LIBRARY=ON']+generator+cmake_config_args), shell = True, stdout = sys.stdout, stderr = sys.stderr, cwd = cmake_build_dir)
    subprocess.check_call(' '.join(['cmake','--build', '.']+cmake_build_args), shell = True, stdout = sys.stdout, stderr = sys.stderr, cwd = cmake_build_dir)

    # Now find the static library that we just built
    if sys.platform == 'win32':
        static_libs = []
        for search_suffix in ['Release/*.lib','Release/*.a', 'Debug/*.lib', 'Debug/*.a']:
            static_libs += glob.glob(os.path.join(cmake_build_dir,search_suffix))

    if len(static_libs) != 1:
        raise ValueError("Found more than one static library using CMake build.  Found: "+str(static_libs))
    else:
        STATIC_LIBRARY_BUILT = True
        static_library_path = os.path.dirname(static_libs[0])
于 2014-11-10T22:32:45.057 回答