在xcode中设置C ++编译标志 [英] Setting C++ compile flags in xcode

查看:294
本文介绍了在xcode中设置C ++编译标志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面对这个问题的相同问题:取消定义符号架构x86_64使用FFTW

我尝试在xcode中使用flag -L和-l作为C ++,但它不起作用


  clang:warning:-lsndfile:'linker'输入未使用
clang:warning:-lfftw3:'linker'输入未使用
clang:warning:参数在编译期间未使用:'-L / usr / local / lib'

架构x86_64的未定义符号:
_fftw_destroy_plan,引用自:
main.o中的
_fftw_execute,引用自:
_main in main.o
_fftw_plan_dft_r2c_1d,引用来自:
main.o中的_main
_sf_close,引用自:
main.o中的main
_sf_open,引用为f rom:
main中的主域
_sf_read_double,引用来自:
main.o中的
ld:符号(s)找不到x86_64体系结构
clang:error:linker命令失败,退出代码1(使用-v查看调用)

>但是,如果我在命令行中使用 gcc 进行编译,它可以很好地工作。

  gcc -I / Users / sr2 / Documents / Soft / fftw-3.3.4 -I / usr / local / include 
-L ​​/ usr / local / lib -lfftw3 -lsndfile main.c -o fft_sample

我在哪里错了?

解决方案

不要将这些放在其他C / C ++标记下,它们应该放在其他链接器标记(在链接部分)。

(请注意,我的XCode是旧的,因此它可能与您的版本略有不同。)






你可能想知道,为什么这是必要的?

好吧,当你建立你的项目,需要经历几个阶段。最基本的分解是编译链接。 (它们可能会被进一步细分,但这是重要的区别)。


$ b 编译器需要一个源文件(例如 example.cpp )并输出一个目标文件(如 example.o )。目标文件不可执行。编译时,编译器通常只知道它当前正在处理的一个源文件。因此编译器不需要知道你正在使用哪个库 - 它需要知道的只是头文件的位置。

linker em>接收一个或多个目标文件并将它们组合在一起以创建可执行的二进制文件。此时,它还必须解析未在代码中定义的任何外部符号 - 例如,在外部库中定义的符号。因此,链接器需要知道你正在使用的库。



编译器不知道该怎么做 -l <​​/ code>或 -L 标志 - 它们与将代码编译成目标文件的过程无关。 / p>

当您像命令行一样调用 gcc 时,它会自动为您调用链接器并将它们 -l <​​/ code>和 -L 标志。因此,不会在磁盘上生成目标文件,并且会得到可执行文件。



但是,当您通过XCode构建时,它会做一些不同的事情。它会为每个源文件调用一次编译器,生成一个像上面描述的对象文件。 (这就是为什么您可以在Build Phases - > Compile Sources部分指定特定源文件的额外编译器标志的原因。)由于编译器被要求生成一个目标文件,因此它不会调用链接器,试着传递它应该被转发到链接器的标志,你会得到这样的警告:标志没有被使用。

一旦所有源文件都成功编译,XCode接下来直接调用链接器将它们全部组合到一个可执行的二进制文件中。这是需要了解您的图书馆的阶段。 (顺便说一句,在任何大型项目中,即使您不使用XCode,此方法通常也是可取的。)


I faced with the same issue for this question: Undefine symbols for architecture x86_64 using FFTW
And I tried to use flag -L and -l for C++ in xcode, but it doesn't work Here is the error log:

  clang: warning: -lsndfile: 'linker' input unused
  clang: warning: -lfftw3: 'linker' input unused
  clang: warning: argument unused during compilation: '-L/usr/local/lib'

  Undefined symbols for architecture x86_64:
   "_fftw_destroy_plan", referenced from:
     _main in main.o
   "_fftw_execute", referenced from:
     _main in main.o
   "_fftw_plan_dft_r2c_1d", referenced from:
   _main in main.o
   "_sf_close", referenced from:
    _main in main.o
   "_sf_open", referenced from:
    _main in main.o
   "_sf_read_double", referenced from:
    _main in main.o
   ld: symbol(s) not found for architecture x86_64
   clang: error: linker command failed with exit code 1 (use -v to see invocation)


But if I compile with gcc in command line, it works well.

  gcc -I/Users/sr2/Documents/Soft/fftw-3.3.4 -I/usr/local/include  
      -L/usr/local/lib -lfftw3 -lsndfile main.c -o fft_sample

where am I wrong?

解决方案

Instead of putting these under "Other C/C++ Flags", they should go under "Other Linker Flags" (in the Linking section).

(Note that my XCode is old, so it may be slightly different for your version.)


You might wonder, why is this necessary?

Well, when you build your project, there are several stages to go through. The most basic breakdown is into compiling and linking. (They could perhaps be broken down further, but that's the important distinction here.)

The compiler takes a source file (eg, example.cpp) and outputs an object file (such as example.o). An object file is not executable. When compiling, the compiler generally only knows about the one source file that it's currently processing. Thus the compiler doesn't need to know which libraries you're using - all it needs to know is where the header files are.

The linker takes one or more object files and combines them together to create an executable binary. At this point, it must also resolve any external symbols not defined in your code - for example, symbols defined in an external library. For that reason, the linker needs to know about any libraries you're using.

The compiler does not know what to do with an -l or -L flag - they're not relevant to the process of compiling your code into an object file.

When you invoke gcc from the command-line like you demonstrated, it automatically invokes the linker for you and forwards those -l and -L flags to it. Because of this, no object file is produced on disk, and you get an executable file.

However, when you build through XCode, it does things a little differently. It invokes the compiler once for each of your source files, producing an object file like I described above. (This is the reason why you can specify extra compiler flags for specific source files in the Build Phases -> Compile Sources section.) Because the compiler has been asked to produce an object file, it does not invoke the linker, and since you're trying to pass it flags that should be forwarded to the linker, you get that warning that the flags are not used.

Once all the source files have successfully compiled, XCode next invokes the linker directly to combine them all into a single executable binary. This is the stage that needs to know about your libraries. (Incidentally, in any large project, this method is generally preferable even if you're not using XCode.)

这篇关于在xcode中设置C ++编译标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆