Skip to content

ENH: Add support to find Headers in Apple Frameworks #448

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions simplecpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3006,6 +3006,34 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
if (!path.empty())
return path;
}
#ifdef __APPLE__
// a named lambda function to insert the ".framework/Headers" part for apple frameworks
auto get_apple_framework_relative_path= [](std::string appleFrameworkHeader) -> std::string
{
// try the Framework path on apple OS, if there is a path in front
const size_t slashPos = appleFrameworkHeader.find('/');
if (slashPos != std::string::npos)
{
constexpr auto framework_separator{ ".framework/Headers" };
appleFrameworkHeader.insert(slashPos, framework_separator);
}
return appleFrameworkHeader;
};

// on Apple, try to find the header in the framework path
// Convert <includePath>/PKGNAME/myHeader -> <includePath>/PKGNAME.framework/Headers/myHeader
const std::string appleFrameworkHeader = get_apple_framework_relative_path(header);
if (appleFrameworkHeader != header)
{
for (const auto & includePath: dui.includePaths)
{
const std::string frameworkCandidatePath = includePath + '/' + appleFrameworkHeader;
std::string simplePath = openHeaderDirect(f, simplecpp::simplifyPath(frameworkCandidatePath ));
if (!simplePath.empty())
return simplePath;
}
}
#endif // __APPLE__
return "";
}

Expand Down
33 changes: 32 additions & 1 deletion test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2084,6 +2084,32 @@ static void systemInclude()
ASSERT_EQUALS("", toString(outputList));
}

#if 0 // Disabled until the test can be written properly
#ifdef __APPLE__
static void appleFrameworkIncludeTest()
{
// This test is for the Apple framework include handling.
// If -I /Library/Developer/CommandLineTools/SDKs/MacOSX14.5.sdk/System/Library/Frameworks
// then:
const char code[] = "#include <Foundation/Foundation.h>\n";
// should find the include file:
// /Library/Developer/CommandLineTools/SDKs/MacOSX14.5.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
std::vector<std::string> files;
const simplecpp::TokenList rawtokens = makeTokenList(code,files,"sourcecode.cpp");
simplecpp::FileDataCache cache;
cache.insert({"Foundation/Foundation.h", simplecpp::TokenList(files)});

simplecpp::TokenList tokens2(files);
simplecpp::DUI dui;
dui.includePaths.push_back("/Library/Developer/CommandLineTools/SDKs/MacOSX14.5.sdk/System/Library/Frameworks");

simplecpp::OutputList outputList;
simplecpp::preprocess(tokens2, rawtokens, files, cache, dui, &outputList);
ASSERT_EQUALS("", toString(outputList));
}
#endif
#endif

static void multiline1()
{
const char code[] = "#define A \\\n"
Expand Down Expand Up @@ -3388,6 +3414,11 @@ int main(int argc, char **argv)
TEST_CASE(preprocess_files);

TEST_CASE(fuzz_crash);

#if 0 // Disabled until the test can be written properly
#ifdef __APPLE__
// Apple-specific test cases
TEST_CASE(appleFrameworkIncludeTest);
#endif
#endif
return numberOfFailedAssertions > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
Loading