Make libdawn_native a shared library.

The interface exposed by libdawn_native is declared in the new headers
living in src/include/dawn_native so that they both the users and the
libraries use the DAWN_NATIVE_EXPORT macros.
This commit is contained in:
Corentin Wallez 2018-07-25 13:37:28 +02:00 committed by Corentin Wallez
parent 36afbb6a0d
commit 196ade667f
21 changed files with 252 additions and 72 deletions

View File

@ -24,6 +24,7 @@ function(add_dawn_sample target sources)
target_link_libraries(${target} sample_utils)
target_include_directories(${target} SYSTEM PRIVATE ${GLM_INCLUDE_DIR})
target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(${target} PRIVATE ${GLM_INCLUDE_DIR} ${TINYGLTFLOADER_INCLUDE_DIR})
DawnInternalTarget("examples" ${target})
# Suppress some warnings in our sample dependencies

View File

@ -18,6 +18,7 @@ set(METAL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/metal)
set(NULL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/null)
set(OPENGL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/opengl)
set(VULKAN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vulkan)
set(DAWN_NATIVE_INCLUDE_DIR ${INCLUDE_DIR}/dawn_native)
Generate(
LIB_NAME dawn_native_utils_autogen
@ -42,14 +43,20 @@ function(GenerateProcTable backend)
target_link_libraries(${backend}_autogen dawn_native_utils_autogen)
endfunction()
set(DAWN_NATIVE_SOURCES)
set(DAWN_NATIVE_DEPS dawn_common spirv_cross)
set(DAWN_NATIVE_INCLUDE_DIRS ${SPIRV_CROSS_INCLUDE_DIR})
################################################################################
# OpenGL Backend
################################################################################
if (DAWN_ENABLE_OPENGL)
GenerateProcTable(opengl)
target_link_libraries(opengl_autogen glfw glad)
target_link_libraries(opengl_autogen glad)
list(APPEND DAWN_NATIVE_DEPS opengl_autogen glad)
list(APPEND DAWN_NATIVE_INCLUDE_DIRS ${GLAD_INCLUDE_DIR})
list(APPEND DAWN_NATIVE_SOURCES
${OPENGL_DIR}/BlendStateGL.cpp
${OPENGL_DIR}/BlendStateGL.h
@ -84,6 +91,7 @@ if (DAWN_ENABLE_OPENGL)
${OPENGL_DIR}/SwapChainGL.h
${OPENGL_DIR}/TextureGL.cpp
${OPENGL_DIR}/TextureGL.h
${DAWN_NATIVE_INCLUDE_DIR}/OpenGLBackend.h
)
endif()
@ -93,10 +101,12 @@ endif()
if (DAWN_ENABLE_NULL)
GenerateProcTable(null)
list(APPEND DAWN_NATIVE_DEPS null_autogen)
list(APPEND DAWN_NATIVE_SOURCES
${NULL_DIR}/NullBackend.cpp
${NULL_DIR}/NullBackend.h
${DAWN_NATIVE_INCLUDE_DIR}/NullBackend.h
)
endif()
@ -106,7 +116,7 @@ endif()
if (DAWN_ENABLE_METAL)
GenerateProcTable(metal)
target_link_libraries(metal_autogen "-framework QuartzCore" "-framework Metal")
list(APPEND DAWN_NATIVE_DEPS metal_autogen "-framework QuartzCore" "-framework Metal" "-framework Cocoa")
list(APPEND DAWN_NATIVE_SOURCES
${METAL_DIR}/BlendStateMTL.mm
@ -140,6 +150,7 @@ if (DAWN_ENABLE_METAL)
${METAL_DIR}/SwapChainMTL.h
${METAL_DIR}/TextureMTL.mm
${METAL_DIR}/TextureMTL.h
${DAWN_NATIVE_INCLUDE_DIR}/MetalBackend.h
)
endif()
@ -205,8 +216,8 @@ if (DAWN_ENABLE_D3D12)
list(APPEND D3D12_LIBRARIES ${DXGUID_LIBRARY})
endif()
target_link_libraries(d3d12_autogen ${D3D12_LIBRARIES})
target_include_directories(d3d12_autogen SYSTEM PRIVATE ${D3D12_INCLUDE_DIR} ${DXGI_INCLUDE_DIR})
list(APPEND DAWN_NATIVE_DEPS d3d12_autogen ${D3D12_LIBRARIES})
target_include_directories(d3d12_autogen SYSTEM PUBLIC ${D3D12_INCLUDE_DIR} ${DXGI_INCLUDE_DIR})
list(APPEND DAWN_NATIVE_SOURCES
${D3D12_DIR}/d3d12_platform.h
@ -257,6 +268,7 @@ if (DAWN_ENABLE_D3D12)
${D3D12_DIR}/TextureCopySplitter.h
${D3D12_DIR}/TextureD3D12.cpp
${D3D12_DIR}/TextureD3D12.h
${DAWN_NATIVE_INCLUDE_DIR}/D3D12Backend.h
)
endif()
@ -266,6 +278,7 @@ endif()
if (DAWN_ENABLE_VULKAN)
GenerateProcTable(vulkan)
list(APPEND DAWN_NATIVE_DEPS vulkan_autogen)
target_include_directories(vulkan_autogen PUBLIC ${VULKAN_HEADERS_INCLUDE_DIR})
list(APPEND DAWN_NATIVE_SOURCES
@ -318,6 +331,7 @@ if (DAWN_ENABLE_VULKAN)
${VULKAN_DIR}/VulkanFunctions.h
${VULKAN_DIR}/VulkanInfo.cpp
${VULKAN_DIR}/VulkanInfo.h
${DAWN_NATIVE_INCLUDE_DIR}/VulkanBackend.h
)
endif()
@ -382,24 +396,28 @@ list(APPEND DAWN_NATIVE_SOURCES
${DAWN_NATIVE_DIR}/Texture.cpp
${DAWN_NATIVE_DIR}/Texture.h
${DAWN_NATIVE_DIR}/ToBackend.h
${DAWN_NATIVE_INCLUDE_DIR}/dawn_native_export.h
)
add_library(libdawn_native STATIC ${DAWN_NATIVE_SOURCES})
DawnInternalTarget("dawn_native" libdawn_native)
target_link_libraries(libdawn_native dawn_common glfw glad spirv_cross)
# We want to produce both a static and a shared libdawn_native library. The static one is for
# unittests that need access to all the symbols of the library. The shared one is for the other
# users that access libdawn_native through the regular interface.
# We use a CMake "OBJECT" library type which allows precompiling the source files and reusing
# them for both the static and the shared library. Recent CMake versions make it so if you
# depend on an OBJECT library you get its dependencies and source files, which is very similar to
# GN's source_set. However the versions of CMake on our test bots is too old and doesn't support
# this, so instead we duplicate the deps everywhere.
add_library(libdawn_native_objects OBJECT ${DAWN_NATIVE_SOURCES})
DawnInternalTarget("dawn_native" libdawn_native_objects)
target_compile_definitions(libdawn_native_objects PRIVATE DAWN_NATIVE_IMPLEMENTATION)
target_include_directories(libdawn_native_objects PRIVATE ${DAWN_NATIVE_INCLUDE_DIRS})
add_dependencies(libdawn_native_objects dawn_native_utils_autogen)
if (DAWN_ENABLE_D3D12)
target_link_libraries(libdawn_native d3d12_autogen)
endif()
if (DAWN_ENABLE_METAL)
target_link_libraries(libdawn_native metal_autogen)
endif()
if (DAWN_ENABLE_NULL)
target_link_libraries(libdawn_native null_autogen)
endif()
if (DAWN_ENABLE_OPENGL)
target_link_libraries(libdawn_native opengl_autogen)
endif()
if (DAWN_ENABLE_VULKAN)
target_link_libraries(libdawn_native vulkan_autogen)
endif()
add_library(libdawn_native SHARED $<TARGET_OBJECTS:libdawn_native_objects>)
DawnInternalTarget("dawn_native" libdawn_native)
target_link_libraries(libdawn_native ${DAWN_NATIVE_DEPS})
set_property(TARGET libdawn_native PROPERTY OUTPUT_NAME "dawn_native")
add_library(libdawn_native_static STATIC $<TARGET_OBJECTS:libdawn_native_objects>)
DawnInternalTarget("dawn_native" libdawn_native_static)
target_link_libraries(libdawn_native_static ${DAWN_NATIVE_DEPS})

View File

@ -16,6 +16,7 @@
#include "common/Assert.h"
#include "common/SwapChainUtils.h"
#include "dawn_native/D3D12backend.h"
#include "dawn_native/d3d12/BindGroupD3D12.h"
#include "dawn_native/d3d12/BindGroupLayoutD3D12.h"
#include "dawn_native/d3d12/BlendStateD3D12.h"

View File

@ -16,6 +16,7 @@
#include "dawn_native/BindGroup.h"
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/MetalBackend.h"
#include "dawn_native/RenderPassDescriptor.h"
#include "dawn_native/metal/BlendStateMTL.h"
#include "dawn_native/metal/BufferMTL.h"

View File

@ -15,6 +15,7 @@
#include "dawn_native/null/NullBackend.h"
#include "dawn_native/Commands.h"
#include "dawn_native/NullBackend.h"
#include <spirv-cross/spirv_cross.hpp>

View File

@ -16,6 +16,7 @@
#include "dawn_native/BindGroup.h"
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/OpenGLBackend.h"
#include "dawn_native/RenderPassDescriptor.h"
#include "dawn_native/opengl/BlendStateGL.h"
#include "dawn_native/opengl/BufferGL.h"

View File

@ -17,6 +17,7 @@
#include "common/Platform.h"
#include "common/SwapChainUtils.h"
#include "dawn_native/Commands.h"
#include "dawn_native/VulkanBackend.h"
#include "dawn_native/vulkan/BindGroupLayoutVk.h"
#include "dawn_native/vulkan/BindGroupVk.h"
#include "dawn_native/vulkan/BlendStateVk.h"
@ -67,7 +68,8 @@ namespace dawn_native { namespace vulkan {
return backendDevice->GetInstance();
}
dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHRNative surfaceNative) {
DAWN_NATIVE_EXPORT dawnSwapChainImplementation
CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHRNative surfaceNative) {
Device* backendDevice = reinterpret_cast<Device*>(device);
VkSurfaceKHR surface = VkSurfaceKHR::CreateFromHandle(surfaceNative);

View File

@ -0,0 +1,33 @@
// Copyright 2018 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_D3D12BACKEND_H_
#define DAWNNATIVE_D3D12BACKEND_H_
#include <dawn/dawn.h>
#include <dawn/dawn_wsi.h>
#include <dawn_native/dawn_native_export.h>
#include <windows.h>
namespace dawn_native { namespace d3d12 {
DAWN_NATIVE_EXPORT void Init(dawnProcTable* procs, dawnDevice* device);
DAWN_NATIVE_EXPORT dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device,
HWND window);
DAWN_NATIVE_EXPORT dawnTextureFormat
GetNativeSwapChainPreferredFormat(const dawnSwapChainImplementation* swapChain);
}} // namespace dawn_native::d3d12
#endif // DAWNNATIVE_D3D12BACKEND_H_

View File

@ -0,0 +1,33 @@
// Copyright 2018 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_METALBACKEND_H_
#define DAWNNATIVE_METALBACKEND_H_
#include <dawn/dawn.h>
#include <dawn/dawn_wsi.h>
#include <dawn_native/dawn_native_export.h>
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
namespace dawn_native { namespace metal {
DAWN_NATIVE_EXPORT void Init(id<MTLDevice> metalDevice,
dawnProcTable* procs,
dawnDevice* device);
DAWN_NATIVE_EXPORT void SetNextDrawable(dawnDevice device, id<CAMetalDrawable> drawable);
DAWN_NATIVE_EXPORT void Present(dawnDevice device);
}} // namespace dawn_native::metal
#endif // DAWNNATIVE_METALBACKEND_H_

View File

@ -0,0 +1,25 @@
// Copyright 2018 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_NULLBACKEND_H_
#define DAWNNATIVE_NULLBACKEND_H_
#include <dawn/dawn.h>
#include <dawn_native/dawn_native_export.h>
namespace dawn_native { namespace null {
DAWN_NATIVE_EXPORT void Init(dawnProcTable* procs, dawnDevice* device);
}} // namespace dawn_native::null
#endif // DAWNNATIVE_NULLBACKEND_H_

View File

@ -0,0 +1,27 @@
// Copyright 2018 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_OPENGLBACKEND_H_
#define DAWNNATIVE_OPENGLBACKEND_H_
#include <dawn/dawn.h>
#include <dawn_native/dawn_native_export.h>
namespace dawn_native { namespace opengl {
DAWN_NATIVE_EXPORT void Init(void* (*getProc)(const char*),
dawnProcTable* procs,
dawnDevice* device);
}} // namespace dawn_native::opengl
#endif // DAWNNATIVE_OPENGLBACKEND_H_

View File

@ -0,0 +1,39 @@
// Copyright 2018 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_VULKANBACKEND_H_
#define DAWNNATIVE_VULKANBACKEND_H_
#include <dawn/dawn.h>
#include <dawn/dawn_wsi.h>
#include <dawn_native/dawn_native_export.h>
#include <vulkan/vulkan.h>
#include <vector>
namespace dawn_native { namespace vulkan {
DAWN_NATIVE_EXPORT void Init(dawnProcTable* procs,
dawnDevice* device,
const std::vector<const char*>& requiredInstanceExtensions);
DAWN_NATIVE_EXPORT VkInstance GetInstance(dawnDevice device);
DAWN_NATIVE_EXPORT dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device,
VkSurfaceKHR surface);
DAWN_NATIVE_EXPORT dawnTextureFormat
GetNativeSwapChainPreferredFormat(const dawnSwapChainImplementation* swapChain);
}} // namespace dawn_native::vulkan
#endif // DAWNNATIVE_VULKANBACKEND_H_

View File

@ -0,0 +1,32 @@
// Copyright 2018 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_EXPORT_H_
#define DAWNNATIVE_EXPORT_H_
#if defined(WIN32)
# if defined(DAWN_NATIVE_IMPLEMENTATION)
# define DAWN_NATIVE_EXPORT __declspec(dllexport)
# else
# define DAWN_NATIVE_EXPORT __declspec(dllimport)
# endif
#else
# if defined(DAWN_NATIVE_IMPLEMENTATION)
# define DAWN_NATIVE_EXPORT __attribute__((visibility("default")))
# else
# define DAWN_NATIVE_EXPORT
# endif
#endif
#endif // DAWNNATIVE_EXPORT_H_

View File

@ -66,7 +66,7 @@ if (DAWN_ENABLE_D3D12)
endif()
add_executable(dawn_unittests ${UNITTEST_SOURCES})
target_link_libraries(dawn_unittests dawn_common gtest libdawn_native mock_dawn dawn_wire utils)
target_link_libraries(dawn_unittests dawn_common gtest libdawn_native_static mock_dawn dawn_wire utils)
DawnInternalTarget("tests" dawn_unittests)
add_executable(dawn_end2end_tests

View File

@ -54,8 +54,7 @@ if (DAWN_ENABLE_VULKAN)
endif()
add_library(utils STATIC ${UTILS_SOURCES})
target_link_libraries(utils libdawn_native shaderc_shared libdawn)
target_include_directories(utils PUBLIC ${SRC_DIR})
target_link_libraries(utils libdawn_native shaderc_shared libdawn glfw)
DawnInternalTarget("" utils)
if(NOT MSVC)
# allow C-style casts -- for shaderc

View File

@ -15,20 +15,12 @@
#include "utils/BackendBinding.h"
#include "common/Assert.h"
#include "dawn/dawn_wsi.h"
#include "dawn_native/D3D12Backend.h"
#include "GLFW/glfw3.h"
#define GLFW_EXPOSE_NATIVE_WIN32
#include "GLFW/glfw3native.h"
namespace dawn_native { namespace d3d12 {
void Init(dawnProcTable* procs, dawnDevice* device);
dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, HWND window);
dawnTextureFormat GetNativeSwapChainPreferredFormat(
const dawnSwapChainImplementation* swapChain);
}} // namespace dawn_native::d3d12
namespace utils {
class D3D12Binding : public BackendBinding {

View File

@ -16,21 +16,12 @@
#include "common/Assert.h"
#include "common/SwapChainUtils.h"
#include "dawn/dawn_wsi.h"
#include "dawn_native/MetalBackend.h"
#define GLFW_EXPOSE_NATIVE_COCOA
#include "GLFW/glfw3.h"
#include "GLFW/glfw3native.h"
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
namespace dawn_native { namespace metal {
void Init(id<MTLDevice> metalDevice, dawnProcTable* procs, dawnDevice* device);
void SetNextDrawable(dawnDevice device, id<CAMetalDrawable> drawable);
void Present(dawnDevice device);
}}
namespace utils {
class SwapChainImplMTL {
public:

View File

@ -14,9 +14,7 @@
#include "utils/BackendBinding.h"
namespace dawn_native { namespace null {
void Init(dawnProcTable* procs, dawnDevice* device);
}} // namespace dawn_native::null
#include "dawn_native/NullBackend.h"
namespace utils {

View File

@ -18,6 +18,7 @@
#include "common/Platform.h"
#include "common/SwapChainUtils.h"
#include "dawn/dawn_wsi.h"
#include "dawn_native/OpenGLBackend.h"
// Glad needs to be included before GLFW otherwise it complain that GL.h was already included
#include "glad/glad.h"
@ -25,10 +26,6 @@
#include <cstdio>
#include "GLFW/glfw3.h"
namespace dawn_native { namespace opengl {
void Init(void* (*getProc)(const char*), dawnProcTable* procs, dawnDevice* device);
}} // namespace dawn_native::opengl
namespace utils {
class SwapChainImplGL {
public:

View File

@ -15,27 +15,11 @@
#include "utils/BackendBinding.h"
#include "common/Assert.h"
#include "dawn/dawn_wsi.h"
#include "dawn_native/VulkanBackend.h"
#include <vulkan/vulkan.h>
// Include GLFW after Vulkan so that it declares the Vulkan-specific functions
// Include GLFW after VulkanBackend so that it declares the Vulkan-specific functions
#include "GLFW/glfw3.h"
#include <vector>
namespace dawn_native { namespace vulkan {
void Init(dawnProcTable* procs,
dawnDevice* device,
const std::vector<const char*>& requiredInstanceExtensions);
VkInstance GetInstance(dawnDevice device);
dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHR surface);
dawnTextureFormat GetNativeSwapChainPreferredFormat(
const dawnSwapChainImplementation* swapChain);
}} // namespace dawn_native::vulkan
namespace utils {
class SwapChainImplVulkan {

View File

@ -36,7 +36,9 @@ add_library(glad STATIC
${CMAKE_CURRENT_SOURCE_DIR}/glad/include/glad/glad.h
${CMAKE_CURRENT_SOURCE_DIR}/glad/include/KHR/khrplatform.h
)
target_include_directories(glad SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/glad/include)
set(GLAD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/glad/include)
set(GLAD_INCLUDE_DIR ${GLAD_INCLUDE_DIR} PARENT_SCOPE)
target_include_directories(glad SYSTEM PUBLIC ${GLAD_INCLUDE_DIR})
DawnExternalTarget("third_party" glad)
# ShaderC
@ -129,7 +131,7 @@ if (DAWN_ENABLE_OPENGL OR NEED_SPIRV_CROSS_GLSL)
endif()
add_library(spirv_cross STATIC ${SPIRV_CROSS_SOURCES})
target_include_directories(spirv_cross SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set(SPIRV_CROSS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
DawnExternalTarget("third_party" spirv_cross)
# STB, used for stb_image
@ -138,5 +140,8 @@ set(STB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/stb PARENT_SCOPE)
# glm matrix math library
set(GLM_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/glm PARENT_SCOPE)
# Tiny glTF loader library
set(TINYGLTFLOADER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
# Vulkan headers
set(VULKAN_HEADERS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)