Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting C++ compile flags in xcode

Tags:

c++

xcode

gcc

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 enter image description here 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?

like image 871
ductran Avatar asked Jul 10 '15 16:07

ductran


People also ask

What C compiler does Xcode use?

Xcode uses two different compilers: one for Swift and the other for Objective-C, Objective-C++ and C/C++ files. clang is Apple's official compiler for the C languages family. It is open-sourced here: swift-clang. swiftc is a Swift compiler executable which is used by Xcode to compile and run Swift source code.

What is compile flag?

Compiler flags are options you give to gcc when it compiles a file or set of files. You may provide these directly on the command line, or your development tools may generate them when they invoke gcc. This section describes just the flags that are specific to Objective-C.


1 Answers

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.)

like image 153
celticminstrel Avatar answered Nov 10 '22 00:11

celticminstrel