mmp / pbrt-v4

Source code to pbrt, the ray tracer described in the forthcoming 4th edition of the "Physically Based Rendering: From Theory to Implementation" book.
https://pbrt.org
Apache License 2.0
2.83k stars 440 forks source link

pbrt-v4 as an external lib fails to create pbrt_soa.h #404

Closed Togtja closed 8 months ago

Togtja commented 10 months ago

I have a relatively simple CMAKE file to add pbrt-v4 as part of a project

cmake_minimum_required(VERSION 3.12)

set(PROJECT_NAME "pbrt-cpp")
project(${PROJECT_NAME})
set(SOURCE_FILES main.cpp)

include_directories(
  external/pbrt-v4/src/pbrt
  ${CMAKE_BINARY_DIR}/external/pbrt-v4/src/pbrt
)

set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/external/pbrt-v4/cmake)

add_definitions(-D PBRT_FLOAT_AS_DOUBLE)
add_subdirectory(external/pbrt-v4)

add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)

target_link_libraries(${PROJECT_NAME}
  pbrt
  pbrt::pbrt_lib # Tried with both pbrt_lib and pbrt and with and without pbrt::
)

The configuring part goes nicely, but immediately run into an error when I try to build: [build] ninja: error: '../../../src/pbrt/pbrt.soa', needed by 'external/pbrt-v4/pbrt_soa.h', missing and no known rule to make it

I appreciate any help that I can get

Togtja commented 10 months ago

So my problem was the ${CMAKE_SOURCE_DIR} used in the pbrt-v4 cmake. As this did not represent the path where I had put the project.

https://github.com/mmp/pbrt-v4/blob/2b5837a862d7f79f4c2dd48acb2038e737b019a7/CMakeLists.txt#L800C1-L808

add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pbrt_soa.h
    COMMAND soac ${CMAKE_SOURCE_DIR}/src/pbrt/pbrt.soa > ${CMAKE_CURRENT_BINARY_DIR}/pbrt_soa.h
    DEPENDS soac ${CMAKE_SOURCE_DIR}/src/pbrt/pbrt.soa)
set (PBRT_SOA_GENERATED ${CMAKE_CURRENT_BINARY_DIR}/pbrt_soa.h)

add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/wavefront_workitems_soa.h
    COMMAND soac ${CMAKE_SOURCE_DIR}/src/pbrt/wavefront/workitems.soa > ${CMAKE_CURRENT_BINARY_DIR}/wavefront_workitems_soa.h
    DEPENDS soac ${CMAKE_SOURCE_DIR}/src/pbrt/wavefront/workitems.soa)
set (PBRT_SOA_GENERATED ${PBRT_SOA_GENERATED} ${CMAKE_CURRENT_BINARY_DIR}/wavefront_workitems_soa.h)

So I used edited the cmake to use PROJECT_SOURCE_CODE https://cmake.org/cmake/help/v2.8.12/cmake.html#variable%3aPROJECT_SOURCE_DIR

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pbrt_soa.h
  COMMAND soac ${PBRT_SOURCE_DIR}/src/pbrt/pbrt.soa > ${CMAKE_CURRENT_BINARY_DIR}/pbrt_soa.h
  DEPENDS soac ${PBRT_SOURCE_DIR}/src/pbrt/pbrt.soa)
set(PBRT_SOA_GENERATED ${CMAKE_CURRENT_BINARY_DIR}/pbrt_soa.h)

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/wavefront_workitems_soa.h
  COMMAND soac ${PBRT_SOURCE_DIR}/src/pbrt/wavefront/workitems.soa > ${CMAKE_CURRENT_BINARY_DIR}/wavefront_workitems_soa.h
  DEPENDS soac ${PBRT_SOURCE_DIR}/src/pbrt/wavefront/workitems.soa)
set(PBRT_SOA_GENERATED ${PBRT_SOA_GENERATED} ${CMAKE_CURRENT_BINARY_DIR}/wavefront_workitems_soa.h)

And as such I got further. So my case it was set(PBRT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/external/pbrt-v4)

I think that you should use the PROJECT_SOURCE_CODE and if it is not set, default to CMAKE_SOURCE_DIR

snps-jfaust commented 8 months ago

@Togtja, this is a good solution. I would argue that CMAKE_CURRENT_SOURCE_DIR is a little more appropriate here since it works independent of project().

Also, thanks for fixing the other places where CMAKE_SOURCE_DIR was used. The other build failure was related to FindSanitizers.cmake.