Skip to content

Commit d85bbd8

Browse files
hjmjohnsonjcfr
authored andcommitted
feat: Add Apple Framework header support for __has_include
Apple frameworks store headers under: <Pkg.framework/Headers/MyHdr.h> This patch extends `openHeader(...)` so that `__has_include(<Pkg/MyHdr.h>)` resolves to the framework layout. A new test `appleFrameworkHasIncludeTest` verifies the behavior. Tests: - Add dummy `Foundation.h` fixture under `testsuite/Foundation.framework/Headers/`. Note: this applies only to `__has_include`; plain `#include` still uses the existing lookup logic. Co-authored-by: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com>
1 parent b4a53dd commit d85bbd8

3 files changed

Lines changed: 56 additions & 0 deletions

File tree

simplecpp.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,6 +3005,30 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
30053005
if (!path.empty())
30063006
return path;
30073007
}
3008+
3009+
// a named lambda function to insert the ".framework/Headers" part for apple frameworks
3010+
auto get_apple_framework_relative_path= [](const std::string& appleFrameworkHeader) -> std::string {
3011+
// try the Framework path on apple OS, if there is a path in front
3012+
const size_t slashPos = appleFrameworkHeader.find('/');
3013+
if (slashPos == std::string::npos) {
3014+
return appleFrameworkHeader;
3015+
}
3016+
constexpr auto frameworkSuffix{ ".framework/Headers" };
3017+
return appleFrameworkHeader.substr(0, slashPos) + frameworkSuffix + appleFrameworkHeader.substr(slashPos);
3018+
};
3019+
// on Apple, try to find the header in the framework path
3020+
// Convert <includePath>/PKGNAME/myHeader -> <includePath>/PKGNAME.framework/Headers/myHeader
3021+
// Works on any platform, but only relevant when compiling against Apple SDKs.
3022+
const std::string appleFrameworkHeader = get_apple_framework_relative_path(header);
3023+
if (appleFrameworkHeader != header) {
3024+
for (const auto & includePath: dui.includePaths) {
3025+
const std::string frameworkCandidatePath = includePath + '/' + appleFrameworkHeader;
3026+
std::string simplePath = openHeaderDirect(f, simplecpp::simplifyPath(frameworkCandidatePath));
3027+
if (!simplePath.empty())
3028+
return simplePath;
3029+
}
3030+
}
3031+
30083032
return "";
30093033
}
30103034

test.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,6 +2141,36 @@ static void circularInclude()
21412141
ASSERT_EQUALS("", toString(outputList));
21422142
}
21432143

2144+
static void appleFrameworkHasIncludeTest()
2145+
{
2146+
const char code[] =
2147+
"#ifdef __has_include\n"
2148+
"#if __has_include(<Foundation/Foundation.h>)\n"
2149+
"A\n"
2150+
"#else\n"
2151+
"B\n"
2152+
"#endif\n"
2153+
"#endif\n";
2154+
2155+
std::vector<std::string> files;
2156+
const simplecpp::TokenList rawtokens = makeTokenList(code, files, "sourcecode.cpp");
2157+
2158+
simplecpp::FileDataCache cache;
2159+
simplecpp::TokenList tokens2(files);
2160+
simplecpp::DUI dui;
2161+
#ifdef SIMPLECPP_TEST_SOURCE_DIR
2162+
dui.includePaths.push_back(testSourceDir + "/testsuite");
2163+
#else
2164+
dui.includePaths.push_back("./testsuite");
2165+
#endif
2166+
dui.std = "c++17"; // enable __has_include
2167+
2168+
simplecpp::OutputList outputList;
2169+
simplecpp::preprocess(tokens2, rawtokens, files, cache, dui, &outputList);
2170+
2171+
ASSERT_EQUALS("\n\nA", tokens2.stringify()); // should take the "A" branch
2172+
}
2173+
21442174
static void multiline1()
21452175
{
21462176
const char code[] = "#define A \\\n"
@@ -3407,6 +3437,7 @@ int main(int argc, char **argv)
34073437
TEST_CASE(nestedInclude);
34083438
TEST_CASE(systemInclude);
34093439
TEST_CASE(circularInclude);
3440+
TEST_CASE(appleFrameworkHasIncludeTest);
34103441

34113442
TEST_CASE(nullDirective1);
34123443
TEST_CASE(nullDirective2);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// Dummy Foundation.h for appleFrameworkIncludeTest

0 commit comments

Comments
 (0)