diff options
author | Nicolas Despres <nicolas.despres@gmail.com> | 2016-05-14 01:18:20 +0200 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-05-17 09:34:12 -0400 |
commit | 8a862a4d4b852c9f61ae4ed7fc46042b00a83123 (patch) | |
tree | 591906a0300c9619e57394105455d93126dab939 | |
parent | 038e7716e58e4cf79bda6ba72b92814a14978a8f (diff) | |
download | cmake-8a862a4d4b852c9f61ae4ed7fc46042b00a83123.tar.gz |
Ninja: Support embedding of CMake as subninja project
Add a `CMAKE_NINJA_OUTPUT_PATH_PREFIX` variable. When it is set, CMake
generates a `build.ninja` file suitable for embedding into another ninja
project potentially generated by an alien generator.
28 files changed, 412 insertions, 7 deletions
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 181fbbcd1f..ec741ae12c 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -281,6 +281,7 @@ Variables that Control the Build /variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG /variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG /variable/CMAKE_MODULE_LINKER_FLAGS + /variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX /variable/CMAKE_NO_BUILTIN_CHRPATH /variable/CMAKE_NO_SYSTEM_FROM_IMPORTED /variable/CMAKE_OSX_ARCHITECTURES diff --git a/Help/release/dev/ninja-output-path-prefix.rst b/Help/release/dev/ninja-output-path-prefix.rst new file mode 100644 index 0000000000..47a96603a1 --- /dev/null +++ b/Help/release/dev/ninja-output-path-prefix.rst @@ -0,0 +1,6 @@ +ninja-output-path-prefix +------------------------ + +* The :generator:`Ninja` generator learned to read a new + :variable:`CMAKE_NINJA_OUTPUT_PATH_PREFIX` variable to configure + the generated ``build.ninja`` file for use as a ``subninja``. diff --git a/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst b/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst new file mode 100644 index 0000000000..64091aaaf5 --- /dev/null +++ b/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst @@ -0,0 +1,27 @@ +CMAKE_NINJA_OUTPUT_PATH_PREFIX +------------------------------ + +Set output files path prefix for the :generator:`Ninja` generator. + +Every output files listed in the generated ``build.ninja`` will be +prefixed by the contents of this variable (a trailing slash is +appended if missing). This is useful when the generated ninja file is +meant to be embedded as a ``subninja`` file into a *super* ninja +project. For example, a ninja build file generated with a command +like:: + + cd top-build-dir/sub && + cmake -G Ninja -DCMAKE_NINJA_OUTPUT_PATH_PREFIX=sub/ path/to/source + +can be embedded in ``top-build-dir/build.ninja`` with a directive like +this:: + + subninja sub/build.ninja + +The ``auto-regeneration`` rule in ``top-build-dir/build.ninja`` must have an +order-only dependency on ``sub/build.ninja``. + +.. note:: + When ``CMAKE_NINJA_OUTPUT_PATH_PREFIX`` is set, the project generated + by CMake cannot be used as a standalone project. No default targets + are specified. diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index 76acaca8f6..ee803c8e82 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -379,4 +379,19 @@ std::reverse_iterator<Iter> cmMakeReverseIterator(Iter it) return std::reverse_iterator<Iter>(it); } +inline bool cmHasSuffix(const std::string& str, const std::string& suffix) +{ + if (str.size() < suffix.size()) { + return false; + } + return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; +} + +inline void cmStripSuffixIfExists(std::string& str, const std::string& suffix) +{ + if (cmHasSuffix(str, suffix)) { + str.resize(str.size() - suffix.size()); + } +} + #endif diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 3c5a8e3bba..d65b463ded 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -488,6 +488,7 @@ void cmGlobalNinjaGenerator::Generate() this->OpenBuildFileStream(); this->OpenRulesFileStream(); + this->InitOutputPathPrefix(); this->TargetAll = this->NinjaOutputPath("all"); this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt"); @@ -717,6 +718,23 @@ void cmGlobalNinjaGenerator::CloseRulesFileStream() } } +static void EnsureTrailingSlash(std::string& path) +{ + if (path.empty()) { + return; + } + std::string::value_type last = path[path.size() - 1]; +#ifdef _WIN32 + if (last != '\\') { + path += '\\'; + } +#else + if (last != '/') { + path += '/'; + } +#endif +} + std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path) { cmLocalNinjaGenerator* ng = @@ -1136,8 +1154,10 @@ void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os) this->WritePhonyBuild(os, "The main all target.", outputs, this->AllDependencies); - cmGlobalNinjaGenerator::WriteDefault(os, outputs, - "Make the all target the default."); + if (!this->HasOutputPathPrefix()) { + cmGlobalNinjaGenerator::WriteDefault(os, outputs, + "Make the all target the default."); + } } void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) @@ -1251,7 +1271,28 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) /*variables=*/cmNinjaVars()); } +void cmGlobalNinjaGenerator::InitOutputPathPrefix() +{ + this->OutputPathPrefix = + this->LocalGenerators[0]->GetMakefile()->GetSafeDefinition( + "CMAKE_NINJA_OUTPUT_PATH_PREFIX"); + EnsureTrailingSlash(this->OutputPathPrefix); +} + std::string cmGlobalNinjaGenerator::NinjaOutputPath(std::string const& path) { - return path; + if (!this->HasOutputPathPrefix() || cmSystemTools::FileIsFullPath(path)) { + return path; + } + return this->OutputPathPrefix + path; +} + +void cmGlobalNinjaGenerator::StripNinjaOutputPathPrefixAsSuffix( + std::string& path) +{ + if (path.empty()) { + return; + } + EnsureTrailingSlash(path); + cmStripSuffixIfExists(path, this->OutputPathPrefix); } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 15c0f34526..6d9bfe8358 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -315,6 +315,8 @@ public: bool SupportsConsolePool() const; std::string NinjaOutputPath(std::string const& path); + bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); } + void StripNinjaOutputPathPrefixAsSuffix(std::string& path); protected: virtual void Generate(); @@ -401,6 +403,9 @@ private: std::string NinjaVersion; private: + void InitOutputPathPrefix(); + + std::string OutputPathPrefix; std::string TargetAll; std::string CMakeCacheFile; }; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 994daeae2a..4d58242a5f 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -669,10 +669,12 @@ void cmNinjaTargetGenerator::EnsureDirectoryExists( if (cmSystemTools::FileIsFullPath(path.c_str())) { cmSystemTools::MakeDirectory(path.c_str()); } else { - const std::string fullPath = std::string(this->GetGlobalGenerator() - ->GetCMakeInstance() - ->GetHomeOutputDirectory()) + - "/" + path; + cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator(); + std::string fullPath = + std::string(gg->GetCMakeInstance()->GetHomeOutputDirectory()); + // Also ensures their is a trailing slash. + gg->StripNinjaOutputPathPrefixAsSuffix(fullPath); + fullPath += path; cmSystemTools::MakeDirectory(fullPath.c_str()); } } diff --git a/Tests/RunCMake/Ninja/CheckNoPrefixSubDir.cmake b/Tests/RunCMake/Ninja/CheckNoPrefixSubDir.cmake new file mode 100644 index 0000000000..b845f2f4a7 --- /dev/null +++ b/Tests/RunCMake/Ninja/CheckNoPrefixSubDir.cmake @@ -0,0 +1,7 @@ +add_custom_target(check_no_prefix_sub_dir ALL + COMMAND "${CMAKE_COMMAND}" + "-DNINJA_OUTPUT_PATH_PREFIX=${CMAKE_NINJA_OUTPUT_PATH_PREFIX}" + "-DCUR_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/CheckNoPrefixSubDirScript.cmake" + VERBATIM + ) diff --git a/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake b/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake new file mode 100644 index 0000000000..5a03fcb7e6 --- /dev/null +++ b/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake @@ -0,0 +1,8 @@ +# Check that the prefix sub-directory is not repeated. + +if(EXISTS "${CUR_BIN_DIR}/${NINJA_OUTPUT_PATH_PREFIX}") + message(FATAL_ERROR + "no sub directory named after the CMAKE_NINJA_OUTPUT_PATH_PREFIX " + "should be in the binary directory." + ) +endif() diff --git a/Tests/RunCMake/Ninja/CheckOutput.cmake b/Tests/RunCMake/Ninja/CheckOutput.cmake new file mode 100644 index 0000000000..ddb35a75ed --- /dev/null +++ b/Tests/RunCMake/Ninja/CheckOutput.cmake @@ -0,0 +1,23 @@ +# Add rules to check the generated executable works. + +set(hello_output "${CMAKE_CURRENT_BINARY_DIR}/hello.output") +add_custom_command( + OUTPUT "${hello_output}" + COMMAND "$<TARGET_FILE:hello>" > "${hello_output}" + DEPENDS hello + VERBATIM + ) + +if(NOT DEFINED HELLO_OUTPUT_STRING) + set(HELLO_OUTPUT_STRING "Hello world!\n") +endif() + +set(hello_output_ref "${CMAKE_CURRENT_BINARY_DIR}/hello.output.ref") +file(WRITE "${hello_output_ref}" "${HELLO_OUTPUT_STRING}") + +add_custom_target(check_output ALL + COMMAND "${CMAKE_COMMAND}" -E compare_files + "${hello_output}" "${hello_output_ref}" + DEPENDS "${hello_output}" "${hello_output_ref}" + VERBATIM + ) diff --git a/Tests/RunCMake/Ninja/CustomCommandWorkingDirectory.cmake b/Tests/RunCMake/Ninja/CustomCommandWorkingDirectory.cmake new file mode 100644 index 0000000000..8e01c8c657 --- /dev/null +++ b/Tests/RunCMake/Ninja/CustomCommandWorkingDirectory.cmake @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.5) +project(hello NONE) + +add_custom_command( + OUTPUT hello.copy.c + COMMAND "${CMAKE_COMMAND}" -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/hello.c" + hello.copy.c + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) +add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/hello.copy.c") + +include(CheckNoPrefixSubDir.cmake) diff --git a/Tests/RunCMake/Ninja/Executable.cmake b/Tests/RunCMake/Ninja/Executable.cmake new file mode 100644 index 0000000000..4e17d68898 --- /dev/null +++ b/Tests/RunCMake/Ninja/Executable.cmake @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.5) +project(hello C) +add_executable(hello hello.c) +include(CheckOutput.cmake) +include(CheckNoPrefixSubDir.cmake) diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index 4e068882df..8160c2dd80 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -32,3 +32,148 @@ function(run_SubDir) run_cmake_command(SubDir-build ${CMAKE_COMMAND} --build . --target ${SubDir_all}) endfunction() run_SubDir() + +function(run_ninja dir) + execute_process( + COMMAND "${RunCMake_MAKE_PROGRAM}" + WORKING_DIRECTORY "${dir}" + OUTPUT_VARIABLE ninja_stdout + ERROR_VARIABLE ninja_stderr + RESULT_VARIABLE ninja_result + ) + if(NOT ninja_result EQUAL 0) + message(STATUS " +============ beginning of ninja's stdout ============ +${ninja_stdout} +=============== end of ninja's stdout =============== +") + message(STATUS " +============ beginning of ninja's stderr ============ +${ninja_stderr} +=============== end of ninja's stderr =============== +") + message(FATAL_ERROR + "top ninja build failed exited with status ${ninja_result}") + endif() +endfunction(run_ninja) + +function(sleep delay) + execute_process( + COMMAND ${CMAKE_COMMAND} -E sleep ${delay} + RESULT_VARIABLE result + ) + if(NOT result EQUAL 0) + message(FATAL_ERROR "failed to sleep for ${delay} second.") + endif() +endfunction(sleep) + +function(touch path) + execute_process( + COMMAND ${CMAKE_COMMAND} -E touch ${path} + RESULT_VARIABLE result + ) + if(NOT result EQUAL 0) + message(FATAL_ERROR "failed to touch main ${path} file.") + endif() +endfunction(touch) + +macro(ninja_escape_path path out) + string(REPLACE "\$ " "\$\$" "${out}" "${path}") + string(REPLACE " " "\$ " "${out}" "${${out}}") + string(REPLACE ":" "\$:" "${out}" "${${out}}") +endmacro(ninja_escape_path) + +macro(shell_escape string out) + string(REPLACE "\"" "\\\"" "${out}" "${string}") +endmacro(shell_escape) + +function(run_sub_cmake test ninja_output_path_prefix) + set(top_build_dir "${RunCMake_BINARY_DIR}/${test}-build/") + file(REMOVE_RECURSE "${top_build_dir}") + file(MAKE_DIRECTORY "${top_build_dir}") + + ninja_escape_path("${ninja_output_path_prefix}" + escaped_ninja_output_path_prefix) + + # Generate top build ninja file. + set(top_build_ninja "${top_build_dir}/build.ninja") + shell_escape("${top_build_ninja}" escaped_top_build_ninja) + set(build_ninja_dep "${top_build_dir}/build_ninja_dep") + ninja_escape_path("${build_ninja_dep}" escaped_build_ninja_dep) + shell_escape("${CMAKE_COMMAND}" escaped_CMAKE_COMMAND) + file(WRITE "${build_ninja_dep}" "fake dependency of top build.ninja file\n") + if(WIN32) + set(cmd_prefix "cmd.exe /C \"") + set(cmd_suffix "\"") + else() + set(cmd_prefix "") + set(cmd_suffix "") + endif() + file(WRITE "${top_build_ninja}" "\ +subninja ${escaped_ninja_output_path_prefix}/build.ninja +default ${escaped_ninja_output_path_prefix}/all + +# Sleep for 1 second before to regenerate to make sure the timestamp of +# the top build.ninja will be strictly greater than the timestamp of the +# sub/build.ninja file. We assume the system as 1 sec timestamp resolution. +rule RERUN + command = ${cmd_prefix}\"${escaped_CMAKE_COMMAND}\" -E sleep 1 && \"${escaped_CMAKE_COMMAND}\" -E touch \"${escaped_top_build_ninja}\"${cmd_suffix} + description = Testing regeneration + generator = 1 + +build build.ninja: RERUN ${escaped_build_ninja_dep} || ${escaped_ninja_output_path_prefix}/build.ninja + pool = console +") + + # Run sub cmake project. + set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_OUTPUT_PATH_PREFIX=${ninja_output_path_prefix}") + set(RunCMake_TEST_BINARY_DIR "${top_build_dir}/${ninja_output_path_prefix}") + run_cmake(${test}) + + # Check there is no 'default' statement in Ninja file generated by CMake. + set(sub_build_ninja "${RunCMake_TEST_BINARY_DIR}/build.ninja") + file(READ "${sub_build_ninja}" sub_build_ninja_file) + if(sub_build_ninja_file MATCHES "\ndefault [^\n][^\n]*all\n") + message(FATAL_ERROR + "unexpected 'default' statement found in '${sub_build_ninja}'") + endif() + + # Run ninja from the top build directory. + run_ninja("${top_build_dir}") + + # Test regeneration rules run in order. + set(main_cmakelists "${RunCMake_SOURCE_DIR}/CMakeLists.txt") + sleep(1) # Assume the system as 1 sec timestamp resolution. + touch("${main_cmakelists}") + touch("${build_ninja_dep}") + run_ninja("${top_build_dir}") + file(TIMESTAMP "${main_cmakelists}" mtime_main_cmakelists UTC) + file(TIMESTAMP "${sub_build_ninja}" mtime_sub_build_ninja UTC) + file(TIMESTAMP "${top_build_ninja}" mtime_top_build_ninja UTC) + + # Check sub build.ninja is regenerated. + if(mtime_main_cmakelists STRGREATER mtime_sub_build_ninja) + message(FATAL_ERROR + "sub build.ninja not regenerated: + CMakeLists.txt = ${mtime_main_cmakelists} + sub/build.ninja = ${mtime_sub_build_ninja}") + endif() + + # Check top build.ninja is regenerated after sub build.ninja. + if(NOT mtime_top_build_ninja STRGREATER mtime_sub_build_ninja) + message(FATAL_ERROR + "top build.ninja not regenerated strictly after sub build.ninja: + sub/build.ninja = ${mtime_sub_build_ninja} + build.ninja = ${mtime_top_build_ninja}") + endif() + +endfunction(run_sub_cmake) + +foreach(ninja_output_path_prefix "sub space" "sub") + run_sub_cmake(Executable "${ninja_output_path_prefix}") + run_sub_cmake(StaticLib "${ninja_output_path_prefix}") + run_sub_cmake(SharedLib "${ninja_output_path_prefix}") + run_sub_cmake(TwoLibs "${ninja_output_path_prefix}") + run_sub_cmake(SubDirPrefix "${ninja_output_path_prefix}") + run_sub_cmake(CustomCommandWorkingDirectory "${ninja_output_path_prefix}") +endforeach(ninja_output_path_prefix) diff --git a/Tests/RunCMake/Ninja/SharedLib.cmake b/Tests/RunCMake/Ninja/SharedLib.cmake new file mode 100644 index 0000000000..1a78390e32 --- /dev/null +++ b/Tests/RunCMake/Ninja/SharedLib.cmake @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.5) +project(hello C) +add_library(greeting SHARED greeting.c) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +add_executable(hello hello_with_greeting.c) +target_link_libraries(hello greeting) +include(CheckOutput.cmake) +include(CheckNoPrefixSubDir.cmake) diff --git a/Tests/RunCMake/Ninja/StaticLib.cmake b/Tests/RunCMake/Ninja/StaticLib.cmake new file mode 100644 index 0000000000..0f815ae5e5 --- /dev/null +++ b/Tests/RunCMake/Ninja/StaticLib.cmake @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.5) +project(hello C) +add_definitions(-DGREETING_STATIC) +add_library(greeting STATIC greeting.c) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +add_executable(hello hello_with_greeting.c) +target_link_libraries(hello greeting) +include(CheckOutput.cmake) +include(CheckNoPrefixSubDir.cmake) diff --git a/Tests/RunCMake/Ninja/SubDirPrefix.cmake b/Tests/RunCMake/Ninja/SubDirPrefix.cmake new file mode 100644 index 0000000000..30ad1e6073 --- /dev/null +++ b/Tests/RunCMake/Ninja/SubDirPrefix.cmake @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.5) +project(hello C) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") +add_subdirectory(SubDirPrefix) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +add_executable(hello hello_sub_greeting.c) +target_link_libraries(hello greeting) +include(CheckOutput.cmake) diff --git a/Tests/RunCMake/Ninja/SubDirPrefix/CMakeLists.txt b/Tests/RunCMake/Ninja/SubDirPrefix/CMakeLists.txt new file mode 100644 index 0000000000..575597d488 --- /dev/null +++ b/Tests/RunCMake/Ninja/SubDirPrefix/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(greeting SHARED greeting.c) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/Tests/RunCMake/Ninja/SubDirPrefix/greeting.c b/Tests/RunCMake/Ninja/SubDirPrefix/greeting.c new file mode 100644 index 0000000000..ba3e55beb0 --- /dev/null +++ b/Tests/RunCMake/Ninja/SubDirPrefix/greeting.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +#if defined(_WIN32) && !defined(GREETING_STATIC) +__declspec(dllexport) +#endif + void greeting(void) +{ + printf("Hello world!\n"); +} diff --git a/Tests/RunCMake/Ninja/SubDirPrefix/greeting.h b/Tests/RunCMake/Ninja/SubDirPrefix/greeting.h new file mode 100644 index 0000000000..ee4053ef7f --- /dev/null +++ b/Tests/RunCMake/Ninja/SubDirPrefix/greeting.h @@ -0,0 +1,4 @@ +#if defined(_WIN32) && !defined(GREETING_STATIC) +__declspec(dllimport) +#endif + void greeting(void); diff --git a/Tests/RunCMake/Ninja/TwoLibs.cmake b/Tests/RunCMake/Ninja/TwoLibs.cmake new file mode 100644 index 0000000000..666452f340 --- /dev/null +++ b/Tests/RunCMake/Ninja/TwoLibs.cmake @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5) +project(hello C) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib-static") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") + +add_library(greeting SHARED greeting.c) +add_library(greeting2 STATIC greeting2.c) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +add_executable(hello hello_with_two_greetings.c) +target_link_libraries(hello greeting greeting2) + +set(HELLO_OUTPUT_STRING "Hello world!\nHello world 2!\n") +include(CheckOutput.cmake) + +include(CheckNoPrefixSubDir.cmake) diff --git a/Tests/RunCMake/Ninja/greeting.c b/Tests/RunCMake/Ninja/greeting.c new file mode 100644 index 0000000000..ba3e55beb0 --- /dev/null +++ b/Tests/RunCMake/Ninja/greeting.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +#if defined(_WIN32) && !defined(GREETING_STATIC) +__declspec(dllexport) +#endif + void greeting(void) +{ + printf("Hello world!\n"); +} diff --git a/Tests/RunCMake/Ninja/greeting.h b/Tests/RunCMake/Ninja/greeting.h new file mode 100644 index 0000000000..ee4053ef7f --- /dev/null +++ b/Tests/RunCMake/Ninja/greeting.h @@ -0,0 +1,4 @@ +#if defined(_WIN32) && !defined(GREETING_STATIC) +__declspec(dllimport) +#endif + void greeting(void); diff --git a/Tests/RunCMake/Ninja/greeting2.c b/Tests/RunCMake/Ninja/greeting2.c new file mode 100644 index 0000000000..c6ed87daa0 --- /dev/null +++ b/Tests/RunCMake/Ninja/greeting2.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +void greeting2(void) +{ + printf("Hello world 2!\n"); +} diff --git a/Tests/RunCMake/Ninja/greeting2.h b/Tests/RunCMake/Ninja/greeting2.h new file mode 100644 index 0000000000..c4d8f9b29e --- /dev/null +++ b/Tests/RunCMake/Ninja/greeting2.h @@ -0,0 +1 @@ +void greeting2(void); diff --git a/Tests/RunCMake/Ninja/hello.c b/Tests/RunCMake/Ninja/hello.c new file mode 100644 index 0000000000..aac8b4e0f3 --- /dev/null +++ b/Tests/RunCMake/Ninja/hello.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main(void) +{ + printf("Hello world!\n"); + return 0; +} diff --git a/Tests/RunCMake/Ninja/hello_sub_greeting.c b/Tests/RunCMake/Ninja/hello_sub_greeting.c new file mode 100644 index 0000000000..fc4bd60f16 --- /dev/null +++ b/Tests/RunCMake/Ninja/hello_sub_greeting.c @@ -0,0 +1,7 @@ +#include <SubDirPrefix/greeting.h> + +int main(void) +{ + greeting(); + return 0; +} diff --git a/Tests/RunCMake/Ninja/hello_with_greeting.c b/Tests/RunCMake/Ninja/hello_with_greeting.c new file mode 100644 index 0000000000..dbf90e314f --- /dev/null +++ b/Tests/RunCMake/Ninja/hello_with_greeting.c @@ -0,0 +1,7 @@ +#include <greeting.h> + +int main(void) +{ + greeting(); + return 0; +} diff --git a/Tests/RunCMake/Ninja/hello_with_two_greetings.c b/Tests/RunCMake/Ninja/hello_with_two_greetings.c new file mode 100644 index 0000000000..cbbdaadc07 --- /dev/null +++ b/Tests/RunCMake/Ninja/hello_with_two_greetings.c @@ -0,0 +1,9 @@ +#include <greeting.h> +#include <greeting2.h> + +int main(void) +{ + greeting(); + greeting2(); + return 0; +} |