2011-11-12 12 views
23

Tôi đang xây dựng một phần mở rộng C++ để sử dụng trong Python. Tôi thấy cảnh báo này được tạo trong quá trình biên dịch - khi một loại:cc1plus: cảnh báo: tùy chọn dòng lệnh "-Hệ thống nguyên mẫu" hợp lệ cho Ada/C/ObjC nhưng không cho C++

python setup.py build_ext -i 

Điều gì gây ra nó và cách khắc phục?

BTW, đây là một bản sao của tập tin cài đặt của tôi:

#!/usr/bin/env python 

    """ 
    setup.py file for SWIG example 
    """ 

    from distutils.core import setup, Extension 


    example_module = Extension('_foolib', 
           sources=['example_wrap.cxx', 
             '../wrapper++/src/Foo.cpp' 
             ], 
           libraries=["foopp"] 
           ) 

    setup (name = 'foolib', 
      version = '0.1', 
      author  = "Me, Myself and I", 
      description = """Example""", 
      ext_modules = [example_module], 
      py_modules = ["example"], 
      ) 

Tôi đang sử dụng gcc 4.4.3 trên Ubuntu

Trả lời

31

tôi có thể trả lời một phần của câu hỏi, tại sao bạn nhận được thông báo .

Thứ gì đó trong quá trình xây dựng của bạn đang gọi gcc trên tệp nguồn C++ với tùy chọn -Wstrict-prototypes. Đối với C và Objective-C, điều này làm cho trình biên dịch cảnh báo về các khai báo hàm kiểu cũ không khai báo các kiểu đối số.

Đối với C++, tùy chọn này không có ý nghĩa; những tuyên bố đó thậm chí không được ngôn ngữ cho phép (nguyên mẫu là bắt buộc).

(Tôi không biết tại sao thông báo đề cập đến Ada; -Wstrict-prototypes thậm chí còn ít ý nghĩa hơn đối với Ada so với C++. Đây không phải là một vấn đề lớn, nhưng tôi đã gửi this bug report, được đánh dấu là GIẢI THÍCH/CỐ ĐỊNH từ 2015-12 -06.)

Giải pháp nên loại bỏ tùy chọn -Wstrict-prototypes khỏi yêu cầu gcc. Nhưng vì bạn không gọi trực tiếp gcc, thật khó để biết cách thực hiện điều đó.

tôi đã có thể tái tạo các cảnh báo bằng setup.py bạn, sau khi tự tạo ra một tập tin dummy example_wrap.cxx:

% python setup.py build_ext -i 
running build_ext 
building '_foolib' extension 
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c example_wrap.cxx -o build/temp.linux-i686-2.7/example_wrap.o 
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++ 
... 

Vì vậy, nó có thể là một lỗi nhỏ trong Python của build_ext.

Nhưng vì đó chỉ là cảnh báo chứ không phải lỗi nghiêm trọng, tôi cho rằng bạn có thể bỏ qua nó một cách an toàn. gcc cảnh báo về tùy chọn vô nghĩa, nhưng sau đó nó chỉ bỏ qua nó.

EDIT:

Nhìn qua các nguồn Python-2.7.2, phần này của configure.in có thể là thủ phạm:

case $GCC in 
yes) 
    if test "$CC" != 'g++' ; then 
     STRICT_PROTO="-Wstrict-prototypes" 
    fi 

(Tôi giả định đó là viện dẫn khi sử dụng build_ext.)

Chỉ bật tùy chọn -Wstrict-prototypes nếu trình biên dịch là không phải được gọi là g++ - nhưng trong trường hợp của bạn, nó sử dụng lệnh gcc để biên dịch mã nguồn C++. Và trong Lib/distutils/command/build_ext.py, build_extension() không chú ý đến ngôn ngữ tệp nguồn khi gọi self.compiler.compile(), chỉ khi gọi self.compiler.link_shared_object(). (Có vẻ như kỳ quặc, đối với các trình biên dịch khác với gcc, bạn sẽ không nhất thiết có thể sử dụng lệnh tương tự để biên dịch C và C++ - và dù sao đi nữa, bạn cũng nên sử dụng lệnh g++.)

CẬP NHẬT: Báo cáo lỗi Python đã được gửi: https://bugs.python.org/issue9031 và bị đóng dưới dạng bản sao của số này: https://bugs.python.org/issue1222585, vẫn mở khi tôi viết điều này.

Nhưng như tôi đã nói, đó chỉ là cảnh báo và bạn có thể bỏ qua nó một cách an toàn. Có lẽ các nhà bảo trì Python có thể sử dụng thông tin trên để khắc phục sự cố trong bản phát hành trong tương lai.

+2

Bây giờ đó là một số trò chơi tuyệt vời! Cảm ơn bạn đã gặp rắc rối khi ngửi nó. Tôi sẽ gửi nó cho các nhà bảo trì Python. –

+0

@HomunculusReticulli: Tuyệt, vui lòng theo dõi ở đây với bất kỳ phản hồi nào bạn nhận được. –

+0

@HomunculusReticulli: FYI, tôi đã báo cáo lỗi chống lại gcc vì thực tế là tùy chọn được chấp nhận cho Ada (điều này không liên quan trực tiếp đến câu hỏi hiện tại). http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51115 –

1

Cụ thể hơn, distutils sử dụng các tùy chọn tương tự python được xây dựng, bạn có thể thêm tùy chọn sử dụng extra_compile_args khi tạo distutils.core.Extension nhưng dường như không có cách nào để loại bỏ đối số hiện có trong gcc hoặc distutils.

Xem http://bugs.python.org/issue9031 để biết chi tiết, nó đã bị đóng cửa như một bản sao của http://bugs.python.org/issue1222585, nhưng 9031 chi tiết khía cạnh này của vấn đề

12

-Wstrict-prototypes tùy chọn được đọc bởi distutils từ /usr/lib/pythonX.Y/config/Makefile như một phần của biến OPT. Có vẻ như bị tấn công, nhưng bạn có thể ghi đè nó bằng cách đặt os.environ['OPT'] trong setup.py của bạn.

Dưới đây là một mã mà dường như không phải là quá độc hại:

import os 
from distutils.sysconfig import get_config_vars 

(opt,) = get_config_vars('OPT') 
os.environ['OPT'] = " ".join(
    flag for flag in opt.split() if flag != '-Wstrict-prototypes' 
) 
9

Đoạn mã sau trong setup.py sẽ loại bỏ tất cả các trường hợp của lá cờ này pesky:

# Remove the "-Wstrict-prototypes" compiler option, which isn't valid for C++. 
import distutils.sysconfig 
cfg_vars = distutils.sysconfig.get_config_vars() 
for key, value in cfg_vars.items(): 
    if type(value) == str: 
     cfg_vars[key] = value.replace("-Wstrict-prototypes", "") 
# ================================== 
0

Vì lợi ích của ai đến đây sau khi cố gắng cài đặt pydoop dưới pypy, giải pháp này đã được áp dụng trong pydoop 1.0.0:

from distutils.sysconfig import get_config_var 
_UNWANTED_OPTS = frozenset(['-Wstrict-prototypes']) 
os.environ['OPT'] = ' '.join(
    _ for _ in get_config_var('OPT').strip().split() if _ not in _UNWANTED_OPTS 

ngắt cài đặt dưới pypy vì pypy sysconfig không cung cấp biến 'OPT', làm cho nó bị hủy bỏ khi nó cố gắng áp dụng strip() thành None. Giải pháp là chỉ để bình luận ra toàn bộ khối.

10

Xóa-nguyên mẫu chính từ biến môi trường OPT không có hiệu lực. Điều gì làm việc là để phân lớp build_ext như sau:

from distutils.command.build_ext import build_ext 
from distutils.sysconfig import customize_compiler 

class my_build_ext(build_ext): 
    def build_extensions(self): 
     customize_compiler(self.compiler) 
     try: 
      self.compiler.compiler_so.remove("-Wstrict-prototypes") 
     except (AttributeError, ValueError): 
      pass 
     build_ext.build_extensions(self) 

và sau đó sử dụng my_build_ext bên trong setup chức năng:

setup(cmdclass = {'build_ext': my_build_ext}) 
+0

Cảm ơn bạn. Đây là lệnh tôi đang tìm kiếm. Cũng làm việc với setuptools, fwiw. –

0

Đây là một giải pháp 3.x Python với setuptools.

from setuptools import setup 
from setuptools.command.build_ext import build_ext 


# Avoid a gcc warning below: 
# cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid 
# for C/ObjC but not for C++ 
class BuildExt(build_ext): 
    def build_extensions(self): 
     self.compiler.compiler_so.remove('-Wstrict-prototypes') 
     super(BuildExt, self).build_extensions() 

setup(
    ... 
    cmdclass={'build_ext': BuildExt}, 
    ... 
) 
Các vấn đề liên quan