Setting c ++ compilation flags in xcode

I faced the same problem for this question: Define symbols for x86_64 architecture using FFTW
And I tried to use the -L and -l for C ++ flag 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

on the 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 going wrong?

+3


source to share


1 answer


Rather than putting them under Other C / C ++ Flags, they should be under Other Linker Flags (under the Linking section).

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


You may wonder why this is necessary?

Well, when you build your project, there are several steps to go through. The most basic breakdown is compilation and linking. (They could be broken down further, but that's an important difference here.)

The compiler takes a source file (eg example.cpp) and outputs an object file (eg example.o). The object file is not executable. When compiling, the compiler usually only knows about one source file that it is processing. This way, the compiler doesn't have to know which libraries you are using - all it needs to know are the header files.



The component takes one or more object files and concatenates them together to create an executable binary. At this point, it should also allow any external symbols not defined in your code, such as symbols defined in an external library. For this reason, the linker needs to be aware of any libraries you are using.

The compiler doesn't know what to do with the flag -l

or -l

- they have nothing to do with the process of compiling your code into an object file.

When you call gcc

from the command line, as you have shown, it automatically invokes the linker for you and forwards the tags -l

and to it -l

. Because of this, no object file is created on disk and you end up with an executable file.

However, when you build through Xcode, it does things a little differently. It calls the compiler once for each of your source files, creating an object file as described above. (This is why you can specify additional compiler flags for specific source files under Build Phases -> Compile Sources.) Since the compiler was prompted to create an object file, it does not invoke the linker. Retrying to pass the flags to be sent to the linker will give you warning that flags are not used.

After all the source files have been successfully compiled, Xcode next calls the linker directly to merge them all into a single executable binary. This is the step to be aware of about your libraries. (By the way, in any large project, this method is usually preferred, even if you are not using Xcode.)

+6


source







All Articles