diff --git a/changelog/collect_c_source_and_headers_for_ImportC.dd b/changelog/collect_c_source_and_headers_for_ImportC.dd
new file mode 100644
index 0000000..59bc29d
--- /dev/null
+++ b/changelog/collect_c_source_and_headers_for_ImportC.dd
@@ -0,0 +1,9 @@
+Add new properties 'cSourcePaths' and 'cImportPaths' to SDL/JSON
+
+`cSourcePaths` passes the C source files in all specified directories to the compiler.
+All C sources found in the given directories for 'cImportPaths' are passed to the D compiler.
+This ensures backward compatible behaviour for projects that stored C sources aside of D source file, while porting them to D.
+
+The second keyword 'cImportPaths' will add additional search paths for C headers. These directories are passed to the D compilers
+as addition include paths. The feature might need additional tweaking, because the include paths are currently joint with the
+D import paths. This might change in future to support independant search paths for C to be passed to the D compilers.
diff --git a/source/dub/compilers/buildsettings.d b/source/dub/compilers/buildsettings.d
index c7b06b0..9d5652c 100644
--- a/source/dub/compilers/buildsettings.d
+++ b/source/dub/compilers/buildsettings.d
@@ -41,6 +41,7 @@
string[] versionFilters;
string[] debugVersionFilters;
string[] importPaths;
+ string[] cImportPaths;
string[] stringImportPaths;
string[] importFiles;
string[] stringImportFiles;
@@ -81,6 +82,7 @@
assert(ret.targetType == targetType);
assert(ret.targetName == targetName);
assert(ret.importPaths == importPaths);
+ assert(ret.cImportPaths == cImportPaths);
return ret;
}
@@ -105,6 +107,7 @@
addVersionFilters(bs.versionFilters);
addDebugVersionFilters(bs.debugVersionFilters);
addImportPaths(bs.importPaths);
+ addCImportPaths(bs.cImportPaths);
addStringImportPaths(bs.stringImportPaths);
addImportFiles(bs.importFiles);
addStringImportFiles(bs.stringImportFiles);
@@ -145,6 +148,7 @@
void addVersionFilters(in string[] value...) { add(versionFilters, value); }
void addDebugVersionFilters(in string[] value...) { add(debugVersionFilters, value); }
void addImportPaths(in string[] value...) { add(importPaths, value); }
+ void addCImportPaths(in string[] value...) { add(cImportPaths, value); }
void addStringImportPaths(in string[] value...) { add(stringImportPaths, value); }
void prependStringImportPaths(in string[] value...) { prepend(stringImportPaths, value); }
void addImportFiles(in string[] value...) { add(importFiles, value); }
@@ -329,12 +333,13 @@
versions = 1<<5,
debugVersions = 1<<6,
importPaths = 1<<7,
- stringImportPaths = 1<<8,
- options = 1<<9,
+ cImportPaths = 1<<8,
+ stringImportPaths = 1<<9,
+ options = 1<<10,
none = 0,
commandLine = dflags|copyFiles,
commandLineSeparate = commandLine|lflags,
- all = dflags|lflags|libs|sourceFiles|copyFiles|versions|debugVersions|importPaths|stringImportPaths|options,
+ all = dflags|lflags|libs|sourceFiles|copyFiles|versions|debugVersions|importPaths|cImportPaths|stringImportPaths|options,
noOptions = all & ~options
}
diff --git a/source/dub/compilers/dmd.d b/source/dub/compilers/dmd.d
index 166f6b5..78fd9d4 100644
--- a/source/dub/compilers/dmd.d
+++ b/source/dub/compilers/dmd.d
@@ -251,6 +251,11 @@
settings.importPaths = null;
}
+ if (!(fields & BuildSetting.cImportPaths)) {
+ settings.addDFlags(settings.cImportPaths.map!(s => "-I"~s)().array());
+ settings.cImportPaths = null;
+ }
+
if (!(fields & BuildSetting.stringImportPaths)) {
settings.addDFlags(settings.stringImportPaths.map!(s => "-J"~s)().array());
settings.stringImportPaths = null;
diff --git a/source/dub/compilers/gdc.d b/source/dub/compilers/gdc.d
index d7a8e4c..0d34446 100644
--- a/source/dub/compilers/gdc.d
+++ b/source/dub/compilers/gdc.d
@@ -110,6 +110,11 @@
settings.importPaths = null;
}
+ if (!(fields & BuildSetting.cImportPaths)) {
+ settings.addDFlags(settings.cImportPaths.map!(s => "-I"~s)().array());
+ settings.cImportPaths = null;
+ }
+
if (!(fields & BuildSetting.stringImportPaths)) {
settings.addDFlags(settings.stringImportPaths.map!(s => "-J"~s)().array());
settings.stringImportPaths = null;
diff --git a/source/dub/compilers/ldc.d b/source/dub/compilers/ldc.d
index 6b8f545..3cb90e5 100644
--- a/source/dub/compilers/ldc.d
+++ b/source/dub/compilers/ldc.d
@@ -131,6 +131,11 @@
settings.importPaths = null;
}
+ if (!(fields & BuildSetting.cImportPaths)) {
+ settings.addDFlags(settings.cImportPaths.map!(s => "-I"~s)().array());
+ settings.cImportPaths = null;
+ }
+
if (!(fields & BuildSetting.stringImportPaths)) {
settings.addDFlags(settings.stringImportPaths.map!(s => "-J"~s)().array());
settings.stringImportPaths = null;
diff --git a/source/dub/description.d b/source/dub/description.d
index bf580bd..fb2dc8f 100644
--- a/source/dub/description.d
+++ b/source/dub/description.d
@@ -90,6 +90,7 @@
string[] versions; /// D version identifiers to set
string[] debugVersions; /// D debug version identifiers to set
string[] importPaths;
+ string[] cImportPaths;
string[] stringImportPaths;
string[] preGenerateCommands; /// Commands executed before creating the description, with variables not substituted.
string[] postGenerateCommands; /// Commands executed after creating the description, with variables not substituted.
diff --git a/source/dub/dub.d b/source/dub/dub.d
index 64a1426..28ada24 100644
--- a/source/dub/dub.d
+++ b/source/dub/dub.d
@@ -524,10 +524,14 @@
auto recipe = parsePackageRecipe(recipe_content, recipe_filename, null, recipe_default_package_name);
enforce(recipe.buildSettings.sourceFiles.length == 0, "Single-file packages are not allowed to specify source files.");
enforce(recipe.buildSettings.sourcePaths.length == 0, "Single-file packages are not allowed to specify source paths.");
+ enforce(recipe.buildSettings.cSourcePaths.length == 0, "Single-file packages are not allowed to specify C source paths.");
enforce(recipe.buildSettings.importPaths.length == 0, "Single-file packages are not allowed to specify import paths.");
+ enforce(recipe.buildSettings.cImportPaths.length == 0, "Single-file packages are not allowed to specify C import paths.");
recipe.buildSettings.sourceFiles[""] = [path.toNativeString()];
recipe.buildSettings.sourcePaths[""] = [];
+ recipe.buildSettings.cSourcePaths[""] = [];
recipe.buildSettings.importPaths[""] = [];
+ recipe.buildSettings.cImportPaths[""] = [];
recipe.buildSettings.mainSourceFile = path.toNativeString();
if (recipe.buildSettings.targetType == TargetType.autodetect)
recipe.buildSettings.targetType = TargetType.executable;
@@ -747,6 +751,9 @@
foreach (importPath; buildSettings.importPaths) {
settings.runArgs ~= ["-I", buildNormalizedPath(dependencyPackage.path.toNativeString(), importPath.idup)];
}
+ foreach (cimportPath; buildSettings.cImportPaths) {
+ settings.runArgs ~= ["-I", buildNormalizedPath(dependencyPackage.path.toNativeString(), cimportPath.idup)];
+ }
}
string configFilePath = buildPath(m_project.rootPackage.path.toNativeString(), "dscanner.ini");
diff --git a/source/dub/generators/build.d b/source/dub/generators/build.d
index 6ea65b5..8583eab 100644
--- a/source/dub/generators/build.d
+++ b/source/dub/generators/build.d
@@ -214,6 +214,7 @@
string makeRelative(string path) { return shrinkPath(NativePath(path), cwd); }
foreach (ref f; buildsettings.sourceFiles) f = makeRelative(f);
foreach (ref p; buildsettings.importPaths) p = makeRelative(p);
+ foreach (ref p; buildsettings.cImportPaths) p = makeRelative(p);
foreach (ref p; buildsettings.stringImportPaths) p = makeRelative(p);
// perform the actual build
@@ -378,6 +379,7 @@
}
buildsettings.targetPath = makeRelative(buildsettings.targetPath);
foreach (ref p; buildsettings.importPaths) p = makeRelative(p);
+ foreach (ref p; buildsettings.cImportPaths) p = makeRelative(p);
foreach (ref p; buildsettings.stringImportPaths) p = makeRelative(p);
bool is_temp_target = false;
@@ -683,6 +685,7 @@
buildsettings.lflags,
buildsettings.stringImportPaths,
buildsettings.importPaths,
+ buildsettings.cImportPaths,
settings.platform.architecture,
[
(cast(uint)(buildsettings.options & ~BuildOption.color)).to!string, // exclude color option from id
diff --git a/source/dub/generators/cmake.d b/source/dub/generators/cmake.d
index b87a368..5c679fb 100644
--- a/source/dub/generators/cmake.d
+++ b/source/dub/generators/cmake.d
@@ -84,6 +84,9 @@
foreach(directory; info.buildSettings.importPaths)
script.put("include_directories(%s)\n".format(directory.sanitizeSlashes));
+ foreach(directory; info.buildSettings.cImportPaths)
+ script.put("c_include_directories(%s)\n".format(directory.sanitizeSlashes));
+
if(addTarget)
{
script.put("add_%s(%s %s\n".format(targetType, name, libType));
diff --git a/source/dub/generators/generator.d b/source/dub/generators/generator.d
index 72282f7..8ff77d0 100644
--- a/source/dub/generators/generator.d
+++ b/source/dub/generators/generator.d
@@ -740,6 +740,7 @@
parent.addVersionFilters(child.versionFilters);
parent.addDebugVersionFilters(child.debugVersionFilters);
parent.addImportPaths(child.importPaths);
+ parent.addCImportPaths(child.cImportPaths);
parent.addStringImportPaths(child.stringImportPaths);
parent.addInjectSourceFiles(child.injectSourceFiles);
// linker stuff propagates up from static *and* dynamic library deps
@@ -1047,6 +1048,7 @@
env["LIBS"] = join(build_settings.libs, " ");
env["SOURCE_FILES"] = join(build_settings.sourceFiles, " ");
env["IMPORT_PATHS"] = join(build_settings.importPaths, " ");
+ env["C_IMPORT_PATHS"] = join(build_settings.cImportPaths, " ");
env["STRING_IMPORT_PATHS"] = join(build_settings.stringImportPaths, " ");
env["DC"] = settings.platform.compilerBinary;
diff --git a/source/dub/generators/visuald.d b/source/dub/generators/visuald.d
index a5feb5f..1524a18 100644
--- a/source/dub/generators/visuald.d
+++ b/source/dub/generators/visuald.d
@@ -303,8 +303,10 @@
// include paths and string imports
string imports = join(getPathSettings!"importPaths"(), " ");
+ string cimports = join(getPathSettings!"cImportPaths"(), " ");
string stringImports = join(getPathSettings!"stringImportPaths"(), " ");
- ret.formattedWrite(" %s\n", imports);
+ string combinedImports = join([imports, cimports], " ");
+ ret.formattedWrite(" %s\n", combinedImports);
ret.formattedWrite(" %s\n", stringImports);
ret.formattedWrite(" %s\n", "$(DMDInstallDir)windows\\bin\\dmd.exe"); // FIXME: use the actually selected compiler!
diff --git a/source/dub/internal/utils.d b/source/dub/internal/utils.d
index 28127ef..b9109cc 100644
--- a/source/dub/internal/utils.d
+++ b/source/dub/internal/utils.d
@@ -559,13 +559,13 @@
{
import std.algorithm : map;
import std.array : array;
- import std.range : walkLength;
+ import std.range : walkLength, chain;
assert(base_path.absolute);
if (!file.absolute) file = base_path ~ file;
size_t path_skip = 0;
- foreach (ipath; settings.importPaths.map!(p => NativePath(p))) {
+ foreach (ipath; chain(settings.importPaths, settings.cImportPaths).map!(p => NativePath(p))) {
if (!ipath.absolute) ipath = base_path ~ ipath;
assert(!ipath.empty);
if (file.startsWith(ipath) && ipath.bySegment.walkLength > path_skip)
diff --git a/source/dub/package_.d b/source/dub/package_.d
index 368f807..27f696d 100644
--- a/source/dub/package_.d
+++ b/source/dub/package_.d
@@ -623,6 +623,7 @@
ret.versions = bs.versions;
ret.debugVersions = bs.debugVersions;
ret.importPaths = bs.importPaths;
+ ret.cImportPaths = bs.cImportPaths;
ret.stringImportPaths = bs.stringImportPaths;
ret.preGenerateCommands = bs.preGenerateCommands;
ret.postGenerateCommands = bs.postGenerateCommands;
diff --git a/source/dub/project.d b/source/dub/project.d
index b22f73d..f68155a 100644
--- a/source/dub/project.d
+++ b/source/dub/project.d
@@ -934,6 +934,7 @@
case "versions":
case "debugVersions":
case "importPaths":
+ case "cImportPaths":
case "stringImportPaths":
case "options":
auto bs = buildSettings.dup;
@@ -943,6 +944,8 @@
auto ensureTrailingSlash = (string path) => path.endsWith(dirSeparator) ? path : path ~ dirSeparator;
static if (attributeName == "importPaths")
bs.importPaths = bs.importPaths.map!(ensureTrailingSlash).array();
+ else static if (attributeName == "cImportPaths")
+ bs.cImportPaths = bs.cImportPaths.map!(ensureTrailingSlash).array();
else static if (attributeName == "stringImportPaths")
bs.stringImportPaths = bs.stringImportPaths.map!(ensureTrailingSlash).array();
@@ -984,6 +987,7 @@
case "stringImportFiles":
case "sourceFiles":
case "importPaths":
+ case "CImportPaths":
case "stringImportPaths":
return values.map!(escapeShellFileName).array();
@@ -1060,7 +1064,7 @@
auto getFixedBuildSetting(Package pack) {
// Is relative path(s) to a directory?
enum isRelativeDirectory =
- attributeName == "importPaths" || attributeName == "stringImportPaths" ||
+ attributeName == "importPaths" || attributeName == "cImportPaths" || attributeName == "stringImportPaths" ||
attributeName == "targetPath" || attributeName == "workingDirectory";
// Is relative path(s) to a file?
@@ -1327,6 +1331,7 @@
dst.addVersionFilters(processVars(project, pack, gsettings, settings.versionFilters, false, buildEnvs));
dst.addDebugVersionFilters(processVars(project, pack, gsettings, settings.debugVersionFilters, false, buildEnvs));
dst.addImportPaths(processVars(project, pack, gsettings, settings.importPaths, true, buildEnvs));
+ dst.addCImportPaths(processVars(project, pack, gsettings, settings.cImportPaths, true, buildEnvs));
dst.addStringImportPaths(processVars(project, pack, gsettings, settings.stringImportPaths, true, buildEnvs));
dst.addRequirements(settings.requirements);
dst.addOptions(settings.options);
diff --git a/source/dub/recipe/json.d b/source/dub/recipe/json.d
index 7993fa2..2f1e3e6 100644
--- a/source/dub/recipe/json.d
+++ b/source/dub/recipe/json.d
@@ -209,6 +209,7 @@
case "files":
case "sourceFiles": bs.sourceFiles[suffix] = deserializeJson!(string[])(value); break;
case "sourcePaths": bs.sourcePaths[suffix] = deserializeJson!(string[])(value); break;
+ case "cSourcePaths": bs.cSourcePaths[suffix] = deserializeJson!(string[])(value); break;
case "sourcePath": bs.sourcePaths[suffix] ~= [value.get!string]; break; // deprecated
case "excludedSourceFiles": bs.excludedSourceFiles[suffix] = deserializeJson!(string[])(value); break;
case "injectSourceFiles": bs.injectSourceFiles[suffix] = deserializeJson!(string[])(value); break;
@@ -219,6 +220,7 @@
case "-versionFilters": bs.versionFilters[suffix] = deserializeJson!(string[])(value); break;
case "-debugVersionFilters": bs.debugVersionFilters[suffix] = deserializeJson!(string[])(value); break;
case "importPaths": bs.importPaths[suffix] = deserializeJson!(string[])(value); break;
+ case "cImportPaths": bs.cImportPaths[suffix] = deserializeJson!(string[])(value); break;
case "stringImportPaths": bs.stringImportPaths[suffix] = deserializeJson!(string[])(value); break;
case "preGenerateCommands": bs.preGenerateCommands[suffix] = deserializeJson!(string[])(value); break;
case "postGenerateCommands": bs.postGenerateCommands[suffix] = deserializeJson!(string[])(value); break;
@@ -279,6 +281,7 @@
foreach (suffix, arr; bs.libs) ret[withSuffix("libs", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.sourceFiles) ret[withSuffix("sourceFiles", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.sourcePaths) ret[withSuffix("sourcePaths", suffix)] = serializeToJson(arr);
+ foreach (suffix, arr; bs.cSourcePaths) ret[withSuffix("cSourcePaths", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.excludedSourceFiles) ret[withSuffix("excludedSourceFiles", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.injectSourceFiles) ret[withSuffix("injectSourceFiles", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.copyFiles) ret[withSuffix("copyFiles", suffix)] = serializeToJson(arr);
@@ -288,6 +291,7 @@
foreach (suffix, arr; bs.versionFilters) ret[withSuffix("-versionFilters", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.debugVersionFilters) ret[withSuffix("-debugVersionFilters", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.importPaths) ret[withSuffix("importPaths", suffix)] = serializeToJson(arr);
+ foreach (suffix, arr; bs.cImportPaths) ret[withSuffix("cImportPaths", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.stringImportPaths) ret[withSuffix("stringImportPaths", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.preGenerateCommands) ret[withSuffix("preGenerateCommands", suffix)] = serializeToJson(arr);
foreach (suffix, arr; bs.postGenerateCommands) ret[withSuffix("postGenerateCommands", suffix)] = serializeToJson(arr);
diff --git a/source/dub/recipe/packagerecipe.d b/source/dub/recipe/packagerecipe.d
index 909e653..c8bb5ec 100644
--- a/source/dub/recipe/packagerecipe.d
+++ b/source/dub/recipe/packagerecipe.d
@@ -426,6 +426,7 @@
@StartsWith("libs") string[][string] libs;
@StartsWith("sourceFiles") string[][string] sourceFiles;
@StartsWith("sourcePaths") string[][string] sourcePaths;
+ @StartsWith("cSourcePaths") string[][string] cSourcePaths;
@StartsWith("excludedSourceFiles") string[][string] excludedSourceFiles;
@StartsWith("injectSourceFiles") string[][string] injectSourceFiles;
@StartsWith("copyFiles") string[][string] copyFiles;
@@ -435,6 +436,7 @@
@StartsWith("versionFilters") string[][string] versionFilters;
@StartsWith("debugVersionFilters") string[][string] debugVersionFilters;
@StartsWith("importPaths") string[][string] importPaths;
+ @StartsWith("cImportPaths") string[][string] cImportPaths;
@StartsWith("stringImportPaths") string[][string] stringImportPaths;
@StartsWith("preGenerateCommands") string[][string] preGenerateCommands;
@StartsWith("postGenerateCommands") string[][string] postGenerateCommands;
@@ -524,14 +526,18 @@
return files.data;
}
- // collect source files
+ // collect source files. Note: D source from 'sourcePaths' and C sources from 'cSourcePaths' are joint into 'sourceFiles'
dst.addSourceFiles(collectFiles(sourcePaths, "*.d"));
+ dst.addSourceFiles(collectFiles(cSourcePaths, "*.{c,i}"));
auto sourceFiles = dst.sourceFiles.sort();
// collect import files and remove sources
import std.algorithm : copy, setDifference;
- auto importFiles = collectFiles(importPaths, "*.{d,di}").sort();
+ auto importFiles =
+ chain(collectFiles(importPaths, "*.{d,di}"), collectFiles(cImportPaths, "*.h"))
+ .array()
+ .sort();
immutable nremoved = importFiles.setDifference(sourceFiles).copy(importFiles.release).length;
importFiles = importFiles[0 .. $ - nremoved];
dst.addImportFiles(importFiles.release);
@@ -551,6 +557,7 @@
getPlatformSetting!("versionFilters", "addVersionFilters")(dst, platform);
getPlatformSetting!("debugVersionFilters", "addDebugVersionFilters")(dst, platform);
getPlatformSetting!("importPaths", "addImportPaths")(dst, platform);
+ getPlatformSetting!("cImportPaths", "addCImportPaths")(dst, platform);
getPlatformSetting!("stringImportPaths", "addStringImportPaths")(dst, platform);
getPlatformSetting!("preGenerateCommands", "addPreGenerateCommands")(dst, platform);
getPlatformSetting!("postGenerateCommands", "addPostGenerateCommands")(dst, platform);
diff --git a/source/dub/recipe/sdl.d b/source/dub/recipe/sdl.d
index 9e10e49..012268e 100644
--- a/source/dub/recipe/sdl.d
+++ b/source/dub/recipe/sdl.d
@@ -145,6 +145,7 @@
case "libs": setting.parsePlatformStringArray(bs.libs); break;
case "sourceFiles": setting.parsePlatformStringArray(bs.sourceFiles); break;
case "sourcePaths": setting.parsePlatformStringArray(bs.sourcePaths); break;
+ case "cSourcePaths": setting.parsePlatformStringArray(bs.cSourcePaths); break;
case "excludedSourceFiles": setting.parsePlatformStringArray(bs.excludedSourceFiles); break;
case "mainSourceFile": bs.mainSourceFile = setting.stringTagValue; break;
case "injectSourceFiles": setting.parsePlatformStringArray(bs.injectSourceFiles); break;
@@ -155,6 +156,7 @@
case "x:versionFilters": setting.parsePlatformStringArray(bs.versionFilters); break;
case "x:debugVersionFilters": setting.parsePlatformStringArray(bs.debugVersionFilters); break;
case "importPaths": setting.parsePlatformStringArray(bs.importPaths); break;
+ case "cImportPaths": setting.parsePlatformStringArray(bs.cImportPaths); break;
case "stringImportPaths": setting.parsePlatformStringArray(bs.stringImportPaths); break;
case "preGenerateCommands": setting.parsePlatformStringArray(bs.preGenerateCommands); break;
case "postGenerateCommands": setting.parsePlatformStringArray(bs.postGenerateCommands); break;
@@ -284,6 +286,7 @@
foreach (suffix, arr; bs.libs) adda("libs", suffix, arr);
foreach (suffix, arr; bs.sourceFiles) adda("sourceFiles", suffix, arr);
foreach (suffix, arr; bs.sourcePaths) adda("sourcePaths", suffix, arr);
+ foreach (suffix, arr; bs.cSourcePaths) adda("cSourcePaths", suffix, arr);
foreach (suffix, arr; bs.excludedSourceFiles) adda("excludedSourceFiles", suffix, arr);
foreach (suffix, arr; bs.injectSourceFiles) adda("injectSourceFiles", suffix, arr);
foreach (suffix, arr; bs.copyFiles) adda("copyFiles", suffix, arr);
@@ -293,6 +296,7 @@
foreach (suffix, arr; bs.versionFilters) adda("versionFilters", suffix, arr, "x");
foreach (suffix, arr; bs.debugVersionFilters) adda("debugVersionFilters", suffix, arr, "x");
foreach (suffix, arr; bs.importPaths) adda("importPaths", suffix, arr);
+ foreach (suffix, arr; bs.cImportPaths) adda("cImportPaths", suffix, arr);
foreach (suffix, arr; bs.stringImportPaths) adda("stringImportPaths", suffix, arr);
foreach (suffix, arr; bs.preGenerateCommands) adda("preGenerateCommands", suffix, arr);
foreach (suffix, arr; bs.postGenerateCommands) adda("postGenerateCommands", suffix, arr);
@@ -476,6 +480,8 @@
sourceFiles "source3"
sourcePaths "sourcepath1" "sourcepath2"
sourcePaths "sourcepath3"
+cSourcePaths "csourcepath1" "csourcepath2"
+cSourcePaths "csourcepath3"
excludedSourceFiles "excluded1" "excluded2"
excludedSourceFiles "excluded3"
mainSourceFile "main source"
@@ -496,6 +502,8 @@
x:debugVersionFilters
importPaths "import1" "import2"
importPaths "import3"
+cImportPaths "cimport1" "cimport2"
+cImportPaths "cimport3"
stringImportPaths "string1" "string2"
stringImportPaths "string3"
preGenerateCommands "preg1" "preg2"
@@ -579,6 +587,7 @@
assert(rec.buildSettings.libs == ["": ["lib1", "lib2", "lib3"]]);
assert(rec.buildSettings.sourceFiles == ["": ["source1", "source2", "source3"]]);
assert(rec.buildSettings.sourcePaths == ["": ["sourcepath1", "sourcepath2", "sourcepath3"]]);
+ assert(rec.buildSettings.cSourcePaths == ["": ["csourcepath1", "csourcepath2", "csourcepath3"]]);
assert(rec.buildSettings.excludedSourceFiles == ["": ["excluded1", "excluded2", "excluded3"]]);
assert(rec.buildSettings.mainSourceFile == "main source");
assert(rec.buildSettings.sourceFiles == ["": ["source1", "source2", "source3"]]);
@@ -589,6 +598,7 @@
assert(rec.buildSettings.versionFilters == ["": ["version1", "version2", "version3"]]);
assert(rec.buildSettings.debugVersionFilters == ["": ["debug1", "debug2", "debug3"]]);
assert(rec.buildSettings.importPaths == ["": ["import1", "import2", "import3"]]);
+ assert(rec.buildSettings.cImportPaths == ["": ["cimport1", "cimport2", "cimport3"]]);
assert(rec.buildSettings.stringImportPaths == ["": ["string1", "string2", "string3"]]);
assert(rec.buildSettings.preGenerateCommands == ["": ["preg1", "preg2", "preg3"]]);
assert(rec.buildSettings.postGenerateCommands == ["": ["postg1", "postg2", "postg3"]]);
@@ -673,6 +683,13 @@
}
unittest {
+ auto sdl = "name \"test\"\ncSourcePaths";
+ PackageRecipe rec;
+ parseSDL(rec, sdl, null, "testfile");
+ assert("" in rec.buildSettings.cSourcePaths);
+}
+
+unittest {
auto sdl =
`name "test"
dependency "package" repository="git+https://some.url" version="12345678"
diff --git a/test/use-c-sources/.min_frontend b/test/use-c-sources/.min_frontend
new file mode 100644
index 0000000..1dbb4ff
--- /dev/null
+++ b/test/use-c-sources/.min_frontend
@@ -0,0 +1 @@
+2.101
diff --git a/test/use-c-sources/dub.json b/test/use-c-sources/dub.json
new file mode 100644
index 0000000..c1d1c45
--- /dev/null
+++ b/test/use-c-sources/dub.json
@@ -0,0 +1,11 @@
+{
+ "toolchainRequirements": {
+ "dub": ">=1.29.0",
+ "frontend": ">=2.101.0"
+ },
+ "cSourcePaths": [
+ "source"
+ ],
+ "description": "A minimal D application using ImportC and C sources in a dub project.",
+ "name": "use-c-sources"
+}
\ No newline at end of file
diff --git a/test/use-c-sources/source/app.d b/test/use-c-sources/source/app.d
new file mode 100644
index 0000000..e00eaca
--- /dev/null
+++ b/test/use-c-sources/source/app.d
@@ -0,0 +1,37 @@
+/** Some test code for ImportC */
+module app.d;
+
+import std.algorithm.iteration;
+import std.array;
+import std.conv;
+import std.exception;
+import std.range;
+import std.stdio;
+import std.string;
+
+import some_c_code;
+
+void main()
+{
+ doCCalls();
+}
+
+/// Call C functions in zstd_binding module
+void doCCalls()
+{
+ relatedCode(42);
+
+ ulong a = 3;
+ uint b = 4;
+ auto rs0 = multiplyU64byU32(&a, &b);
+ writeln("Result of multiplyU64byU32(3,4) = ", rs0);
+
+ uint[8] arr = [1, 2, 3, 4, 5, 6, 7, 8];
+ auto rs1 = multiplyAndAdd(arr.ptr, arr.length, 3);
+ writeln("Result of sum(%s*3) = ".format(arr), rs1);
+
+ foreach (n; 1 .. 20)
+ {
+ writeln("fac(", n, ") = ", fac(n));
+ }
+}
diff --git a/test/use-c-sources/source/some_c_code.c b/test/use-c-sources/source/some_c_code.c
new file mode 100644
index 0000000..487e52d
--- /dev/null
+++ b/test/use-c-sources/source/some_c_code.c
@@ -0,0 +1,34 @@
+
+#include
+
+#include "some_c_code.h"
+
+// Some test functions follow to proof that C code can be called from D main()
+
+void relatedCode(size_t aNumber)
+{
+ printf("Hallo! This is some output from C code! (%d)\n", aNumber);
+}
+
+uint64_t multiplyU64byU32(uint64_t*a, uint32_t*b)
+{
+ return *a * *b;
+}
+
+uint64_t multiplyAndAdd(uint32_t*arr, size_t arrlen, uint32_t mult)
+{
+ uint64_t acc = 0;
+ for (int i = 0; i < arrlen; i++)
+ {
+ acc += arr[i]*mult;
+ }
+ return acc;
+}
+
+uint64_t fac(uint64_t n)
+{
+ if (n > 1)
+ return n * fac(n-1);
+ else
+ return 1;
+}
diff --git a/test/use-c-sources/source/some_c_code.h b/test/use-c-sources/source/some_c_code.h
new file mode 100644
index 0000000..9643eb2
--- /dev/null
+++ b/test/use-c-sources/source/some_c_code.h
@@ -0,0 +1,12 @@
+#ifndef SOME_C_CODE_H
+#define SOME_C_CODE_H
+
+#include
+#include
+
+extern void relatedCode(size_t aNumber);
+extern uint64_t multiplyU64byU32(uint64_t*a, uint32_t*b);
+extern uint64_t multiplyAndAdd(uint32_t*arr, size_t arrlen, uint32_t mult);
+extern uint64_t fac(uint64_t n);
+
+#endif
\ No newline at end of file