2015-07-10 3 views
3

я столкнулся с той же проблемой на этот вопрос: Undefine symbols for architecture x86_64 using FFTW
И я пытался использовать флаг -L и -l для C++ в Xcode, но он не работает enter image description here Вот журнал ошибок:Настройка C++ скомпилировать флаги в Xcode

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) 


Но если я компилирую с 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 

Где я ошибаюсь?

ответ

5

Вместо того, чтобы помещать их под «Другие флаги C/C++», они должны находиться под «Другие флаги компоновщика» (в разделе «Связывание»).

(Обратите внимание, что моя XCode старая, так что может немного отличаться для вашей версии.)


Вы могли бы задаться вопросом, почему это необходимо?

Ну, когда вы строите свой проект, нужно пройти несколько этапов. Самая основная разбивка на компиляция и ссылка. (Они могли бы, возможно, быть разбиты, но это важное различие здесь.)

компилятор принимает исходный файл (например, example.cpp) и выводит объектный файл (например, example.o). Объектный файл не является исполняемым. При компиляции компилятор обычно знает только об одном исходном файле, который он обрабатывает. Таким образом, компилятор не должен знать, какие библиотеки вы используете - все, что ему нужно знать, - это файлы заголовков.

Компонент принимает один или несколько объектных файлов и объединяет их вместе для создания исполняемого двоичного файла. На этом этапе он также должен разрешить любые внешние символы, не определенные в вашем коде, например символы, определенные во внешней библиотеке. По этой причине компоновщик должен знать о любых библиотеках, которые вы используете.

Компилятор не знает, что делать с флагом -l или -L - они не имеют отношения к процессу компиляции кода в объектный файл.

Когда вы вызываете gcc из командной строки, как вы продемонстрировали, она автоматически вызывает компоновщик для вас и пересылает туда те -l и -L флагов. Из-за этого на диске не создается объектный файл, и вы получаете исполняемый файл.

Однако, когда вы строите через XCode, он делает все по-другому. Он вызывает компилятор один раз для каждого из ваших исходных файлов, создавая объектный файл, как описано выше. (Вот почему вы можете указать дополнительные флаги компилятора для определенных исходных файлов в разделе «Сборка фаз -> Компиляция источников».) Поскольку компилятору было предложено создать объектный файл, он не вызывает компоновщик, Повторяя попытку передать флаги, которые должны быть отправлены компоновщику, вы получите предупреждение о том, что флаги не используются.

После того как все исходные файлы были успешно скомпилированы, XCode next вызывает компоновщик напрямую, чтобы объединить их все в один исполняемый двоичный файл. Это этап, который должен знать о ваших библиотеках. (Кстати, в любом крупном проекте этот метод обычно предпочтительнее, даже если вы не используете XCode.)

+0

Ничего себе, это сработало. Огромное спасибо. Но не могли бы вы объяснить, почему он работает в «Other Linker Flags»? Когда я создаю проект C++ в xcode. Я искал, а другие ребята говорят, что мне нужно положить в 'Other C/C++ Flags' – R4j

+0

. Я добавил объяснение в сообщение. – celticminstrel

+0

Это очень ясно. Теперь я могу понять. Спасибо за вашу помощь! – R4j

Смежные вопросы