我有多个功能可以在项目的构建时启用或禁用。
当前实现使用$(document).ready(function () {
'use strict';
//cards
$(".card").each(function () {
//capture the data-* sets
var img = this.dataset.img,
alt = this.dataset.alt,
heading = this.dataset.heading,
text = this.dataset.text,
url = this.dataset.url,
//set the template
template = '<img src="' + img + '" alt="' + alt + '"> <h3>' + heading + '</h3> <p>' + text + '</p>';
//append the template to the parent
this.appendChild(template);
});
});
等声明。每当我需要执行与特定功能相关的操作时,我都会使用预处理器指令,例如 Creates a new array with the specified component type and
length.
* Invoking this method is equivalent to creating an array
* as follows:
* <blockquote>
* <pre>
**** int[] x = {length};***
* Array.newInstance(componentType, x);
* </pre>
* </blockquote>
*
* <p>The number of dimensions of the new array must not
* exceed 255.
*
* @param componentType the {@code Class} object representing the
* component type of the new array
*** @param length the length of the new array**
。
功能定义存储在全局头文件中。
这种方法有两个缺点:
#define FEATURE_FOO
每个文件中的此全局标头。 这不是很好:
#ifdef
因为我更喜欢这个:
#include
因此,解决此问题的另一种方法是在构建时声明我的所有功能:
// file: foo.c
#include <stdio.h>
#include "main_header.h"
#ifdef FEATURE_FOO
...
#endif
我不喜欢的是我手动需要将每个功能传递给我的编译器。
可接受的解决方法是阅读包含所有功能的// file: foo.c
#ifdef FEATURE_FOO
#include <stdio.h>
...
#endif
文件。在我的Makefile中,我将:
gcc -DFEATURE_FOO -c %< -o %@
我能找到更好的选择吗?
答案 0 :(得分:5)
您可以使用gcc的选项-include myheader.h
。
它将myheader.h
的内容添加到当前翻译单元源的最开头。
答案 1 :(得分:1)
我在大部分项目中都使用基于GNU make的构建过程,虽然到目前为止它并不是关于功能,但我也使用了可以帮助你的技术。
首先,拥有配置文件的想法非常好,但为什么不用make
语法和include
呢?
我使用类似的东西
# default configuration
CC := gcc
DEBUG := 0
GCC32 := 0
USELTO := 1
# read local configuration
-include defaults.mk
您可以使用它来获取功能列表,例如在defaults.mk
FEATURES := foo bar baz
然后执行类似
的操作FEATUREDEFINES := $(addprefix -DFEATURE_, $(FEATURES))
当您使用$(eval ...)
函数时,GNU make可以提供更多 black magic - 这可能是根据您的设置从编译中完全排除源文件的一个很好的选择。我将其用于特定于平台的实现。例如,我有这个包含用于构建二进制文件的Makefile:
P:= src
T:= csnake
csnake_SOURCES:= csnake.c utils.c game.c board.c snake.c food.c screen.c
csnake_PLATFORMSOURCES:= ticker.c
csnake_LDFLAGS:= -lm
csnake_posix_LDFLAGS:= -lcurses
csnake_dos_LDFLAGS:= -Wl,-Bstatic -lpdcurses
csnake_win32_LDFLAGS:= -static-libgcc -Wl,-Bstatic -lpdcurses \
-Wl,-Bdynamic -lwinmm
csnake_win32_RES:= res$(PSEP)csnake.rc
$(eval $(BINRULES))
我的P
是源树中的当前相对路径,T
是要构建的目标,PSEP
只是包含/
或{{1}的辅助变量为了与Windows兼容。其余部分应该是不言自明的 - 对于\
,$(T)_PLATFORMSOURCES
在相对路径$(BINRULES)
中查找。它的工作原理如下:
platform/$(PLATFORM)/
所有这些双倍的美元都在那里,因为define BINRULES
BINARIES += $$(BINDIR)$$(PSEP)$(T)$$(EXE)
$(T)_SOURCES_FULL := $$(addprefix $(P)$$(PSEP),$$($(T)_SOURCES))
ifneq ($$(strip $$($(T)_PLATFORMSOURCES)),)
$(T)_SOURCES_FULL += $$(addprefix \
$(P)$$(PSEP)platform$$(PSEP)$$(PLATFORM)$$(PSEP), \
$$($(T)_PLATFORMSOURCES))
endif
[...] (... further rules ... )
endef
会扩展变量 - 这是$(eval ...)
和$(T)
所需要的,但不是所有其他变量,所以它们受到额外的美元保护。我只是引用了为决定在这里编译哪些文件而魔术的部分。如果你考虑做这样的事情,see the full example