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