在一个生成文件中编译 C++ 和 C
Compiling C++ and C in one Makefile
我有一个使用arm-none-eabi-gcc工具链为ARM设备编写和开发的项目。它使用仅适用于 C 编译的自定义生成文件。我们试图过渡到一个主要C++项目,同时保留 C 源文件,但我在更新 makefile 时遇到了问题。我知道这个问题已经被问过几次了,但没有一个能够完全解决我们的问题。如何包含 C 源文件和头文件以编译 g++ 和 cpp 文件?
我非常感谢任何愿意并能够查看我们的 makefile 以帮助解决编译问题的人。makefile很长,所以这里有一个有点删节的版本,应该包括所有关键的内容。
请记住,我在这里只包含 makefile,而不是 platform_id.mk 或 $(PLATFORM_MCU(.mk,但我对这些文件非常有信心。
BIN_NAME = $(PLATFORM)_firmware.bin
ifdef PLATFORM
include $(PROJECT_ROOT)build/platform_id.mk
include $(PROJECT_ROOT)hal/$(PLATFORM_MCU)/$(PLATFORM_MCU).mk
include $(PROJECT_ROOT)build/$(PLATFORM_MCU_CORE)/$(PLATFORM_MCU_CORE).mk
else
$(error "Platform not defined. Used the -e flag to define the platform in the environment
endif
$(info $(msg))
# C compiler flags
CFLAGS +=
-std=c99
-Og
-g3
-Wall
-fdata-sections
-ffunction-sections
-MMD
-DHAVE_MMAP=0
-Dmalloc_getpagesize=8
-DMORECORE_CLEARS=0
-DDEFAULT_TRIM_THRESHOLD=8
# C++ compiler flags
CXXFLAGS +=
-Wall
-D__STDC_LIMIT_MACROS
# C Pre Processor flags
CPPFLAGS +=
# Undefine WIN32 variable if building on Windows host
ifdef WIN32
CFLAGS += -UWIN32
msg = You're on a windows host.
else
msg = You're not on a windows host.
endif
ifdef TOOLCHAIN
AR = $(TOOLCHAIN)-ar
CC = $(TOOLCHAIN)-gcc
CXX = $(TOOLCHAIN)-g++
endif
# Binary make targets
TARGET = out/$(PLATFORM_MCU)/$(BIN_NAME)
# Binary Sources
VPATH += $(wildcard */src/)
# extract all *.c filenames, don't pull the filepath with it
C_SRCS += $(notdir $(wildcard */src/*.c))
# extract all *.cpp filesnames, don't pull the filepath with it
CXX_SRCS += $(notdir $(wildcard */src/*.cpp))
# extract all *.s filenames, don't pull the filepath with it
S_SRCS += $(notdir $(wildcard */src/*.s))
# Objects
OBJECTS_C += $(patsubst %.c,out/$(PLATFORM_MCU)/obj/%.o,$(C_SRCS))
OBJECTS_CXX += $(patsubst %.cpp,out/$(PLATFORM_MCU)/obj/%.o,$(CXX_SRCS))
# Dependencies
DEP_C := $(OBJECTS_C:.o=.d)
DEP_CXX := $(OBJECTS_CXX:.o=.d)
# Includes
NULL =
SPACE = $(NULL) $(NULL)
INCLUDE_SRC = $(subst $(SPACE),$(SPACE)-I,$(VPATH))
PATH_INC = $(wildcard */inc/)
INCLUDE_INC = $(subst $(SPACE),$(SPACE)-I,$(PATH_INC))
C_INC +=
-I$(INCLUDE_INC)
-I$(INCLUDE_SRC)
# Clean and precious
PRECIOUS += out/$(PLATFORM_MCU)/obj/%.o
CLEAN += out/$(PLATFORM_MCU)/
# all
all: $(TARGET)
# Create binary
$(TARGET): $(OBJECTS_C) $(OBJECTS_CXX) $(S_SRCS)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(C_INC) -T$(LDFILE) $(LFLAGS) -o $@
$(TOOLCHAIN)-objcopy -O binary $@ $(basename $@).bin
# Compile from cpp files. Compilation works when this is removed (and toolchain and files are tweaked to represent that)
out/$(PLATFORM_MCU)/obj/%.o: %.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(C_INC) -o $@ -c $<
-include $(DEP_CXX)
# Create binary from c files
out/$(PLATFORM_MCU)/obj/%.o: %.c
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) $(C_INC) -o $@ -c $<
-include $(DEP_C)
.PRECIOUS: $(PRECIOUS)
.PHONY: all clean
clean:
rm -rf $(CLEAN)
在运行make -e PLATFORM=test
错误很多,主要说明 c 源代码中的各种函数没有定义。现在 main.cpp 只不过是int main()
和包含到包含大多数其他 C 头文件的头文件中。
下面是编译器错误之一的示例:
hal/atsamg55/sam/drivers/usart/usart.h:333:47: error: 'p_usart' was not declared in this scope
uint32_t usart_get_writeprotect_status(Usart *p_usart);
这是主要的.cpp
#include "headers.h"
int main(){
while(1)
{
}
return 0;
}
再次感谢您提供的任何帮助。
感谢您的帮助,我想我能够解决问题,并希望将其发布在这里,以防将来对任何人有所帮助。所有 C 文件的错误来自我没有正确将定义从 CFLAGS 传输到 CXX 标志的错误。一旦我添加了与 -DBOARD=TEST 相关的标志,我的头文件就能够识别我正在使用的板,这允许它通过"包含"链进行。
相关文章:
- 使用 Makefile 中的头文件编译 Pybind (不使用 cmake)
- 如何使用命令提示符、记事本和 MinGW 使用主文件、头文件和实现文件编译C++程序?
- 无论如何可以将webm / mp4文件编译/记忆为.exe程序吗?(C++)
- 从生成文件编译错误:"Unable to open output file" ..."No such file or directory"
- 如何使用 GLFW 预编译的二进制文件编译 Visual Studio 2019 发布版本
- Arduino IDE中自定义库类的.h文件编译错误的原因是什么
- makefile和错误将与大型项目分开的文件编译
- 如何使用生成文件编译具有多个目录的 c++ 项目
- 我可以将Visual Studio 2015头文件编译成dll并在VS2013中使用它吗?
- 使用Bazel将C 文件编译为python.h
- 使用 .a 文件编译简单的C++文件
- OpenCV 3.2 文件编译
- 如何从多个 cpp 文件编译 WebAssembly
- 从多个文件编译可以"undefined reference"
- 使用静态依赖性为共享二进制文件编译语法需要更加清晰
- 将Gsoap Src文件编译到我的项目中
- 如何用多个文件编译make下的dlib
- 字段的类型不完整,从多个文件编译
- 强制将特定文件编译为Objective-C/文件类型,但将整个项目编译为Objective C++
- OpenGLES 标头(包括 Availability.h)可防止 CPP 文件编译