diff options
-rw-r--r-- | Source/cmExportBuildFileGenerator.cxx | 15 | ||||
-rw-r--r-- | Source/cmExportBuildFileGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 47 | ||||
-rw-r--r-- | Source/cmExportFileGenerator.h | 8 | ||||
-rw-r--r-- | Source/cmExportInstallFileGenerator.cxx | 22 | ||||
-rw-r--r-- | Source/cmExportInstallFileGenerator.h | 6 | ||||
-rw-r--r-- | Source/cmGeneratorExpression.cxx | 36 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 14 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 25 | ||||
-rw-r--r-- | Source/cmTarget.h | 3 | ||||
-rw-r--r-- | Tests/ExportImport/Export/CMakeLists.txt | 11 | ||||
-rw-r--r-- | Tests/ExportImport/Export/sublib/CMakeLists.txt | 6 | ||||
-rw-r--r-- | Tests/ExportImport/Export/sublib/subdir.cpp | 7 | ||||
-rw-r--r-- | Tests/ExportImport/Export/sublib/subdir.h | 12 | ||||
-rw-r--r-- | Tests/ExportImport/Import/A/CMakeLists.txt | 47 | ||||
-rw-r--r-- | Tests/ExportImport/Import/A/deps_shared_iface.cpp | 20 |
16 files changed, 216 insertions, 66 deletions
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 29f6743..61e130d 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -62,6 +62,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) cmTarget* te = *tei; this->GenerateImportTargetCode(os, te); + te->AppendBuildInterfaceIncludes(); + ImportPropertyMap properties; this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te, @@ -70,20 +72,22 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te, cmGeneratorExpression::BuildInterface, properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", + te, properties); this->GenerateInterfaceProperties(te, os, properties); } - this->GenerateMissingTargetsCheckCode(os, missingTargets); - // Generate import file content for each configuration. for(std::vector<std::string>::const_iterator ci = this->Configurations.begin(); ci != this->Configurations.end(); ++ci) { - this->GenerateImportConfig(os, ci->c_str()); + this->GenerateImportConfig(os, ci->c_str(), missingTargets); } + this->GenerateMissingTargetsCheckCode(os, missingTargets); + return true; } @@ -91,7 +95,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) void cmExportBuildFileGenerator ::GenerateImportTargetsConfig(std::ostream& os, - const char* config, std::string const& suffix) + const char* config, std::string const& suffix, + std::vector<std::string> &missingTargets) { for(std::vector<cmTarget*>::const_iterator tei = this->Exports->begin(); @@ -104,7 +109,6 @@ cmExportBuildFileGenerator if(!properties.empty()) { // Get the rest of the target details. - std::vector<std::string> missingTargets; this->SetImportDetailProperties(config, suffix, target, properties, missingTargets); this->SetImportLinkInterface(config, suffix, @@ -119,7 +123,6 @@ cmExportBuildFileGenerator // properties); // Generate code in the export file. - this->GenerateMissingTargetsCheckCode(os, missingTargets); this->GenerateImportPropertyCode(os, config, target, properties); } } diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 726537b..5e1be16 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -44,7 +44,8 @@ protected: virtual bool GenerateMainFile(std::ostream& os); virtual void GenerateImportTargetsConfig(std::ostream& os, const char* config, - std::string const& suffix); + std::string const& suffix, + std::vector<std::string> &missingTargets); virtual void HandleMissingTarget(std::string& link_libs, std::vector<std::string>& missingTargets, cmMakefile* mf, diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 94e24c7..4a7c6f9 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -107,7 +107,8 @@ bool cmExportFileGenerator::GenerateImportFile() //---------------------------------------------------------------------------- void cmExportFileGenerator::GenerateImportConfig(std::ostream& os, - const char* config) + const char* config, + std::vector<std::string> &missingTargets) { // Construct the property configuration suffix. std::string suffix = "_"; @@ -121,7 +122,19 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os, } // Generate the per-config target information. - this->GenerateImportTargetsConfig(os, config, suffix); + this->GenerateImportTargetsConfig(os, config, suffix, missingTargets); +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, + cmTarget *target, + ImportPropertyMap &properties) +{ + const char *input = target->GetProperty(propName); + if (input) + { + properties[propName] = input; + } } //---------------------------------------------------------------------------- @@ -665,21 +678,29 @@ cmExportFileGenerator void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os, const std::vector<std::string>& missingTargets) { + if (missingTargets.empty()) + { + return; + } os << "# Make sure the targets which have been exported in some other \n" "# export set exist.\n"; + std::set<std::string> emitted; for(unsigned int i=0; i<missingTargets.size(); ++i) { - os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n" - << " IF(CMAKE_FIND_PACKAGE_NAME)\n" - << " SET( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n" - << " SET( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE " - << "\"Required imported target \\\"" << missingTargets[i] - << "\\\" not found ! \")\n" - << " ELSE()\n" - << " MESSAGE(FATAL_ERROR \"Required imported target \\\"" - << missingTargets[i] << "\\\" not found ! \")\n" - << " ENDIF()\n" - << "ENDIF()\n"; + if (emitted.insert(missingTargets[i]).second) + { + os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n" + << " IF(CMAKE_FIND_PACKAGE_NAME)\n" + << " SET( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n" + << " SET( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE " + << "\"Required imported target \\\"" << missingTargets[i] + << "\\\" not found ! \")\n" + << " ELSE()\n" + << " MESSAGE(FATAL_ERROR \"Required imported target \\\"" + << missingTargets[i] << "\\\" not found ! \")\n" + << " ENDIF()\n" + << "ENDIF()\n"; + } } os << "\n"; } diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 4d97a63..eb3f3c3 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -47,7 +47,8 @@ protected: // Generate per-configuration target information to the given output // stream. - void GenerateImportConfig(std::ostream& os, const char* config); + void GenerateImportConfig(std::ostream& os, const char* config, + std::vector<std::string> &missingTargets); // Methods to implement export file code generation. void GenerateImportHeaderCode(std::ostream& os, const char* config = 0); @@ -85,7 +86,8 @@ protected: /** Each subclass knows where the target files are located. */ virtual void GenerateImportTargetsConfig(std::ostream& os, const char* config, - std::string const& suffix) = 0; + std::string const& suffix, + std::vector<std::string> &missingTargets) = 0; /** Each subclass knows how to deal with a target that is missing from an * export set. */ @@ -99,6 +101,8 @@ protected: cmGeneratorExpression::PreprocessContext, ImportPropertyMap &properties, std::vector<std::string> &missingTargets); + void PopulateInterfaceProperty(const char *propName, cmTarget *target, + ImportPropertyMap &properties); void GenerateInterfaceProperties(cmTarget *target, std::ostream& os, const ImportPropertyMap &properties); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 68881a1..965f63d 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -89,11 +89,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) te, cmGeneratorExpression::InstallInterface, properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", + te, properties); this->GenerateInterfaceProperties(te, os, properties); } - this->GenerateMissingTargetsCheckCode(os, missingTargets); // Now load per-configuration properties for them. os << "# Load information for each installed configuration.\n" @@ -105,23 +106,29 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) << "ENDFOREACH(f)\n" << "\n"; + this->GenerateImportedFileCheckLoop(os); + // Generate an import file for each configuration. bool result = true; for(std::vector<std::string>::const_iterator ci = this->Configurations.begin(); ci != this->Configurations.end(); ++ci) { - if(!this->GenerateImportFileConfig(ci->c_str())) + if(!this->GenerateImportFileConfig(ci->c_str(), missingTargets)) { result = false; } } + + this->GenerateMissingTargetsCheckCode(os, missingTargets); + return result; } //---------------------------------------------------------------------------- bool -cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config) +cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config, + std::vector<std::string> &missingTargets) { // Skip configurations not enabled for this export. if(!this->IEGen->InstallsForConfig(config)) @@ -161,7 +168,7 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config) this->GenerateImportHeaderCode(os, config); // Generate the per-config target information. - this->GenerateImportConfig(os, config); + this->GenerateImportConfig(os, config, missingTargets); // End with the import file footer. this->GenerateImportFooterCode(os); @@ -176,7 +183,8 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config) void cmExportInstallFileGenerator ::GenerateImportTargetsConfig(std::ostream& os, - const char* config, std::string const& suffix) + const char* config, std::string const& suffix, + std::vector<std::string> &missingTargets) { // Add code to compute the installation prefix relative to the // import file location. @@ -225,7 +233,6 @@ cmExportInstallFileGenerator if(!properties.empty()) { // Get the rest of the target details. - std::vector<std::string> missingTargets; this->SetImportDetailProperties(config, suffix, te->Target, properties, missingTargets); @@ -240,15 +247,12 @@ cmExportInstallFileGenerator // properties); // Generate code in the export file. - this->GenerateMissingTargetsCheckCode(os, missingTargets); this->GenerateImportPropertyCode(os, config, te->Target, properties); this->GenerateImportedFileChecksCode(os, te->Target, properties, importedLocations); } } - this->GenerateImportedFileCheckLoop(os); - // Cleanup the import prefix variable. if(!this->ImportPrefix.empty()) { diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index e719ecc..e187749 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -56,7 +56,8 @@ protected: virtual bool GenerateMainFile(std::ostream& os); virtual void GenerateImportTargetsConfig(std::ostream& os, const char* config, - std::string const& suffix); + std::string const& suffix, + std::vector<std::string> &missingTargets); virtual void HandleMissingTarget(std::string& link_libs, std::vector<std::string>& missingTargets, cmMakefile* mf, @@ -72,7 +73,8 @@ protected: /** Generate a per-configuration file for the targets. */ - bool GenerateImportFileConfig(const char* config); + bool GenerateImportFileConfig(const char* config, + std::vector<std::string> &missingTargets); /** Fill in properties indicating installed file locations. */ void SetImportLocationProperty(const char* config, diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index d306dee..78ae8f2 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -148,6 +148,38 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() } //---------------------------------------------------------------------------- +static std::string stripEmptyListElements(const std::string &input) +{ + std::string result; + + const char *c = input.c_str(); + bool skipSemiColons = true; + for ( ; *c; ++c) + { + if(c[0] == ';') + { + if(skipSemiColons) + { + continue; + } + skipSemiColons = true; + } + else + { + skipSemiColons = false; + } + result += *c; + } + + if (!result.empty() && *(result.end() - 1) == ';') + { + result.resize(result.size() - 1); + } + + return result; +} + +//---------------------------------------------------------------------------- static std::string stripAllGeneratorExpressions(const std::string &input) { std::string result; @@ -186,7 +218,7 @@ static std::string stripAllGeneratorExpressions(const std::string &input) lastPos = pos; } result += input.substr(lastPos); - return result; + return stripEmptyListElements(result); } //---------------------------------------------------------------------------- @@ -247,7 +279,7 @@ static std::string stripExportInterface(const std::string &input, } result += input.substr(lastPos); - return result; + return stripEmptyListElements(result); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index d030aa7..d2baf53 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -941,19 +941,7 @@ void cmGlobalGenerator::Generate() for ( tit = targets->begin(); tit != targets->end(); ++ tit ) { - if (mf->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES")) - { - const char *binDir = mf->GetStartOutputDirectory(); - const char *srcDir = mf->GetStartDirectory(); - const std::string dirs = std::string(binDir ? binDir : "") - + std::string(binDir ? ";" : "") - + std::string(srcDir ? srcDir : ""); - if (!dirs.empty()) - { - tit->second.AppendProperty("INTERFACE_INCLUDE_DIRECTORIES", - ("$<BUILD_INTERFACE:" + dirs + ">").c_str()); - } - } + tit->second.AppendBuildInterfaceIncludes(); } } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 6f68140..815da40 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -150,6 +150,7 @@ cmTarget::cmTarget() this->DLLPlatform = false; this->IsApple = false; this->IsImportedTarget = false; + this->BuildInterfaceIncludesAppended = false; } //---------------------------------------------------------------------------- @@ -2681,6 +2682,30 @@ void cmTarget::AppendProperty(const char* prop, const char* value, } //---------------------------------------------------------------------------- +void cmTarget::AppendBuildInterfaceIncludes() +{ + if (this->BuildInterfaceIncludesAppended) + { + return; + } + this->BuildInterfaceIncludesAppended = true; + + if (this->Makefile->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES")) + { + const char *binDir = this->Makefile->GetStartOutputDirectory(); + const char *srcDir = this->Makefile->GetStartDirectory(); + const std::string dirs = std::string(binDir ? binDir : "") + + std::string(binDir ? ";" : "") + + std::string(srcDir ? srcDir : ""); + if (!dirs.empty()) + { + this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES", + ("$<BUILD_INTERFACE:" + dirs + ">").c_str()); + } + } +} + +//---------------------------------------------------------------------------- void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, bool before) { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 0963c5c..69a00c1 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -490,6 +490,8 @@ public: void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, bool before = false); + void AppendBuildInterfaceIncludes(); + void GetLinkDependentTargetsForProperty(const std::string &p, std::set<std::string> &targets); bool IsNullImpliedByLinkLibraries(const std::string &p); @@ -611,6 +613,7 @@ private: mutable std::map<cmStdString, std::set<std::string> > LinkDependentProperties; mutable std::set<std::string> LinkImplicitNullProperties; + bool BuildInterfaceIncludesAppended; // Cache target output paths for each configuration. struct OutputInfo; diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index 779d889..dd615d1 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -162,6 +162,10 @@ include(GenerateExportHeader) add_library(testSharedLibRequired SHARED testSharedLibRequired.cpp) generate_export_header(testSharedLibRequired) +set_property(TARGET testSharedLibRequired + PROPERTY + INTERFACE_POSITION_INDEPENDENT_CODE ON +) set_property(TARGET testSharedLibRequired APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}" ) @@ -182,7 +186,7 @@ set_property(TARGET testSharedLibDepends APPEND PROPERTY ) set_property(TARGET testSharedLibDepends APPEND PROPERTY LINK_INTERFACE_LIBRARIES - $<1:$<TARGET_NAME:testSharedLibRequired>> + $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>> ) # LINK_PRIVATE because the LINK_INTERFACE_LIBRARIES is specified above. @@ -247,9 +251,12 @@ if(WIN32) install(TARGETS testLib5 RUNTIME DESTINATION bin) endif() +add_subdirectory(sublib) # For CMAKE_BUILD_INTERFACE_INCLUDES test. + # Export from build tree. export(TARGETS testExe1 testLib1 testLib2 testLib3 - testExe2libImp testLib3Imp testLib3ImpDep + testExe2libImp testLib3Imp testLib3ImpDep subdirlib + testSharedLibRequired testSharedLibDepends NAMESPACE bld_ FILE ExportBuildTree.cmake ) diff --git a/Tests/ExportImport/Export/sublib/CMakeLists.txt b/Tests/ExportImport/Export/sublib/CMakeLists.txt new file mode 100644 index 0000000..2d11040 --- /dev/null +++ b/Tests/ExportImport/Export/sublib/CMakeLists.txt @@ -0,0 +1,6 @@ + +set(CMAKE_BUILD_INTERFACE_INCLUDES ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +add_library(subdirlib SHARED subdir.cpp) +generate_export_header(subdirlib) diff --git a/Tests/ExportImport/Export/sublib/subdir.cpp b/Tests/ExportImport/Export/sublib/subdir.cpp new file mode 100644 index 0000000..35b0743 --- /dev/null +++ b/Tests/ExportImport/Export/sublib/subdir.cpp @@ -0,0 +1,7 @@ + +#include "subdir.h" + +int SubDirObject::foo() +{ + return 0; +} diff --git a/Tests/ExportImport/Export/sublib/subdir.h b/Tests/ExportImport/Export/sublib/subdir.h new file mode 100644 index 0000000..3a4b73d --- /dev/null +++ b/Tests/ExportImport/Export/sublib/subdir.h @@ -0,0 +1,12 @@ + +#ifndef SUBDIR_H +#define SUBDIR_H + +#include "subdirlib_export.h" + +struct SUBDIRLIB_EXPORT SubDirObject +{ + int foo(); +}; + +#endif diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index abb2ab0..4812e7e 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -159,22 +159,39 @@ endif() add_executable(deps_iface deps_iface.c) target_link_libraries(deps_iface testLibDepends) -set_property(TARGET deps_iface APPEND PROPERTY - COMPILE_DEFINITIONS - $<TARGET_PROPERTY:testLibDepends,INTERFACE_COMPILE_DEFINITIONS> -) -set_property(TARGET deps_iface APPEND PROPERTY - INCLUDE_DIRECTORIES - $<TARGET_PROPERTY:testLibDepends,INTERFACE_INCLUDE_DIRECTORIES> -) +target_include_directories(deps_iface PRIVATE testLibDepends) +target_compile_definitions(deps_iface PRIVATE testLibDepends) add_executable(deps_shared_iface deps_shared_iface.cpp) target_link_libraries(deps_shared_iface testSharedLibDepends) -set_property(TARGET deps_shared_iface APPEND PROPERTY - COMPILE_DEFINITIONS - $<TARGET_PROPERTY:testSharedLibDepends,INTERFACE_COMPILE_DEFINITIONS> -) -set_property(TARGET deps_shared_iface APPEND PROPERTY - INCLUDE_DIRECTORIES - $<TARGET_PROPERTY:testSharedLibDepends,INTERFACE_INCLUDE_DIRECTORIES> +target_include_directories(deps_shared_iface PRIVATE testSharedLibDepends) +target_compile_definitions(deps_shared_iface PRIVATE testSharedLibDepends) + +if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag(-fPIE run_pic_test) +else() + if (CMAKE_CXX_COMPILER_ID MATCHES "PGI" + OR CMAKE_CXX_COMPILER_ID MATCHES "PathScale" + OR CMAKE_SYSTEM_NAME MATCHES "IRIX64" + OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") + set(run_pic_test 0) + else() + set(run_pic_test 1) + endif() +endif() + +if (run_pic_test) + target_compile_definitions(deps_shared_iface PRIVATE CHECK_PIC_WORKS) +endif() + +#----------------------------------------------------------------------------- +# Test that targets imported from the build tree have their dependencies +# evaluated correctly. The above already tests the same for the install tree. + +add_executable(deps_shared_iface2 deps_shared_iface.cpp) +target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib) +target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends bld_subdirlib) +target_compile_definitions(deps_shared_iface2 + PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB ) diff --git a/Tests/ExportImport/Import/A/deps_shared_iface.cpp b/Tests/ExportImport/Import/A/deps_shared_iface.cpp index 4f7eb23..43f832a 100644 --- a/Tests/ExportImport/Import/A/deps_shared_iface.cpp +++ b/Tests/ExportImport/Import/A/deps_shared_iface.cpp @@ -2,10 +2,28 @@ #include "testSharedLibDepends.h" +#ifdef CHECK_PIC_WORKS +#if defined(__ELF__) && !defined(__PIC__) && !defined(__PIE__) +#error Expected by INTERFACE_POSITION_INDEPENDENT_CODE property of dependency +#endif +#endif + +#ifdef TEST_SUBDIR_LIB +#include "subdir.h" +#endif + int main(int,char **) { TestSharedLibDepends dep; TestSharedLibRequired req; - return dep.foo() + req.foo(); +#ifdef TEST_SUBDIR_LIB + SubDirObject sdo; +#endif + + return dep.foo() + req.foo() +#ifdef TEST_SUBDIR_LIB + + sdo.foo() +#endif + ; } |