ste*_*n f 10 c c++ gcc clang osx-mavericks
转换到OS X Mavericks和XCode 5.0.1之后,我再也不能优雅地将已编译的C文件(从gcc输出)链接到C++项目(从g ++输出).
从我的makefile生成的令人讨厌的命令对是:
gcc `pkg-config --cflags glib-2.0` -g -Wall -O3 `pkg-config --cflags flann` -c -o vec.o vec.c
g++ `pkg-config --cflags glib-2.0` -g -Wall -O3 -stdlib=libstdc++ -lstdc++ layoutquality.cpp vec.o `pkg-config --libs glib-2.0` -L/usr/local/Cellar/flann/1.8.4/lib -lflann -o layoutquality
Run Code Online (Sandbox Code Playgroud)
链接器抱怨的是:
体系结构x86_64的未定义符号:"load_dmat(char const*)",引用自:layoutquality中的_main-I8HOqy.o ld:未找到体系结构x86_64的符号
哪里load_dmat只是文件vec.c中的一个函数.如果我在第一行中替换了gccwith g++,那么所有内容都会编译并链接正常,但是clang说:
clang:警告:在C++模式下将'c'输入视为'c ++'时,不推荐使用此行为
是否有一种无害的,不推荐的编译和链接方式?与链接g++与目标文件一起gcc工作的罚款之前,我升级到OS X小牛和新的命令行工具.任何有关变化和如何前进的见解都会很棒,谢谢.
Abe*_*lle 19
在"vec.c"之前添加"-x c"(不带引号)应修复它.
如果在同一行中编译多个.c/.cpp文件,则可以在每个C或C++文件名列表之前使用"-x c"或"-x c ++"来适当地切换上下文.例如:
g++ -x c alpha.c beta.c -x c++ gamma.cpp
Run Code Online (Sandbox Code Playgroud)
这是一个Makefile让我们C++在C程序中使用代码/函数的例子.
CC=clang
CXX=clang++
CFLAGS=-Wall -g
CXXFLAGS=-Wall -g -std=c++11 -I.
DEPS=CPP.h
OBJ=main.o CPP.o
RM=rm -f
# compile only, C source
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
# compile only, C++ source
%.o: %.cpp $(DEPS)
$(CXX) -c -o $@ $< $(CXXFLAGS)
# link
main: $(OBJ)
$(CXX) -o $@ $^ $(CXXFLAGS)
clean:
$(RM) $(OBJ)
Run Code Online (Sandbox Code Playgroud)
如您所见,我们使用CXXFLAGS和CFLAGS分别对编译器进行两次单独调用来单独生成对象.在使用Xcode的clang的Mac环境中,clang(CC)和clang ++(CXX)实际上是同一个东西.只有不同的旗帜很重要.我只是被陈述的定义迂腐CC并CXX在上面的例子Makefile.
生成目标文件后,我们很高兴将它们链接在一起.
但请注意,您必须执行一个额外步骤才能使C++C代码可以使用您的代码.
在CPP.h此示例中,您必须明确用于extern "C"指定C++代码的链接以供使用C.
例如,像这样:
#ifdef __cplusplus
extern "C" {
#endif
double timesTwo(double number);
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
预处理器宏#ifdef __cplusplus和#endif是确保我们的头文件不会导致C模式编译错误,并仅在效果℃持续++ -编译模式.
此完整示例仅包含4个文件.
的Makefile源极和CPP.h被上面所解释的.
对于一个完整的认识,我包括main.c并且CPP.cpp在这里.
main.c:
#include <stdio.h>
#include "CPP.h"
int main()
{
printf("Running main.c\n");
double ans = timesTwo(3.0);
printf("The answer from our C++ timesTwo function, when given 3.0, is %f\n", ans);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
CPP.cpp:
#include "CPP.h"
double timesTwo(double number)
{
return 2 * number;
}
Run Code Online (Sandbox Code Playgroud)
我相信这个解释和示例阐明了我们如何设置我们Makefile,指定#ifdef __cplusplus预处理器宏和extern "C"链接声明以允许C++ - to-C互操作,并且在运行make时没有错误的clang警告.
您很可能是Name mangling的受害者。为了避免 C++ 中的名称修改,请使用extern "C"around 声明,例如:
#ifdef __cplusplus
extern "C" {
#endif
void load_dmat(char const*);
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14207 次 |
| 最近记录: |