Skip to content

Commit 81dad8f

Browse files
hjmjohnsonjcfr
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 cfd1797 commit 81dad8f

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
@@ -3012,6 +3012,30 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
30123012
if (!path.empty())
30133013
return path;
30143014
}
3015+
3016+
// a named lambda function to insert the ".framework/Headers" part for apple frameworks
3017+
auto get_apple_framework_relative_path= [](const std::string& appleFrameworkHeader) -> std::string {
3018+
// try the Framework path on apple OS, if there is a path in front
3019+
const size_t slashPos = appleFrameworkHeader.find('/');
3020+
if (slashPos == std::string::npos) {
3021+
return appleFrameworkHeader;
3022+
}
3023+
constexpr auto frameworkSuffix{ ".framework/Headers" };
3024+
return appleFrameworkHeader.substr(0, slashPos) + frameworkSuffix + appleFrameworkHeader.substr(slashPos);
3025+
};
3026+
// on Apple, try to find the header in the framework path
3027+
// Convert <includePath>/PKGNAME/myHeader -> <includePath>/PKGNAME.framework/Headers/myHeader
3028+
// Works on any platform, but only relevant when compiling against Apple SDKs.
3029+
const std::string appleFrameworkHeader = get_apple_framework_relative_path(header);
3030+
if (appleFrameworkHeader != header) {
3031+
for (const auto & includePath: dui.includePaths) {
3032+
const std::string frameworkCandidatePath = includePath + '/' + appleFrameworkHeader;
3033+
std::string simplePath = openHeaderDirect(f, simplecpp::simplifyPath(frameworkCandidatePath));
3034+
if (!simplePath.empty())
3035+
return simplePath;
3036+
}
3037+
}
3038+
30153039
return "";
30163040
}
30173041

test.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,36 @@ static void circularInclude()
21312131
ASSERT_EQUALS("", toString(outputList));
21322132
}
21332133

2134+
static void appleFrameworkHasIncludeTest()
2135+
{
2136+
const char code[] =
2137+
"#ifdef __has_include\n"
2138+
"#if __has_include(<Foundation/Foundation.h>)\n"
2139+
"A\n"
2140+
"#else\n"
2141+
"B\n"
2142+
"#endif\n"
2143+
"#endif\n";
2144+
2145+
std::vector<std::string> files;
2146+
const simplecpp::TokenList rawtokens = makeTokenList(code, files, "sourcecode.cpp");
2147+
2148+
simplecpp::FileDataCache cache;
2149+
simplecpp::TokenList tokens2(files);
2150+
simplecpp::DUI dui;
2151+
#ifdef SIMPLECPP_TEST_SOURCE_DIR
2152+
dui.includePaths.push_back(std::string(SIMPLECPP_TEST_SOURCE_DIR) + "/testsuite");
2153+
#else
2154+
dui.includePaths.push_back("./testsuite");
2155+
#endif
2156+
dui.std = "c++17"; // enable __has_include
2157+
2158+
simplecpp::OutputList outputList;
2159+
simplecpp::preprocess(tokens2, rawtokens, files, cache, dui, &outputList);
2160+
2161+
ASSERT_EQUALS("\n\nA", tokens2.stringify()); // should take the "A" branch
2162+
}
2163+
21342164
static void multiline1()
21352165
{
21362166
const char code[] = "#define A \\\n"
@@ -3359,6 +3389,7 @@ int main(int argc, char **argv)
33593389
TEST_CASE(nestedInclude);
33603390
TEST_CASE(systemInclude);
33613391
TEST_CASE(circularInclude);
3392+
TEST_CASE(appleFrameworkHasIncludeTest);
33623393

33633394
TEST_CASE(nullDirective1);
33643395
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)