Skip to content
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

Building libsbml and its dependencies in the same project #227

Open
luciansmith opened this issue May 3, 2022 · 5 comments
Open

Building libsbml and its dependencies in the same project #227

luciansmith opened this issue May 3, 2022 · 5 comments
Assignees

Comments

@luciansmith
Copy link
Member

I have a problem. I'm trying to build libsbml in a project where libsbml's dependencies are also being built at the same time. The problem is that when libsbml tries to find expat, it sees that expat hasn't been built yet, and fails. However, this is to be expected: the system is going to build both expat and libsbml; it just has to wait.

Here's the relevant bits of my CMakeLists.txt file:

#expat
set (EXPAT_SHARED_LIBS OFF)
set (EXPAT_BUILD_EXAMPLES OFF)
set (EXPAT_BUILD_TESTS OFF)
set (EXPAT_BUILD_TOOLS OFF)
set (EXPAT_BUILD_TOOLS OFF)
if (WITH_STATIC_RUNTIME)
    #expat is overriding this
  set(EXPAT_MSVC_STATIC_CRT ON CACHE BOOL "Use /MT flag (static CRT) when compiling in MSVC" FORCE)
endif()

add_subdirectory(expat/expat)

set(EXPAT_INCLUDE_DIR "$<TARGET_PROPERTY:expat,INCLUDE_DIRECTORIES>")
set(EXPAT_LIBRARY "$<TARGET_LINKER_FILE:expat>")


# libsbml
message(STATUS "Adding libsbml as subdirectory")
set(WITH_EXPAT ON CACHE BOOL "Compile libsbml with the expat library" FORCE)
set(WITH_LIBXML OFF CACHE BOOL "Compile libsbml with libxml (off by default)" FORCE)
add_subdirectory(libsbml)

and here's the error message I get from CMake:

CMake Error at third_party/libsbml/CMakeModules/FindEXPAT.cmake:163 (message):
  Unable to compile a test executable against expat with

    
    EXPAT_INCLUDE_DIR = $<TARGET_PROPERTY:expat,INCLUDE_DIRECTORIES>
    EXPAT_LIBRARY     = $<TARGET_LINKER_FILE:expat>
    
Call Stack (most recent call first):
  third_party/libsbml/CMakeLists.txt:422 (find_package)

If I comment out the lines defining EXPAT_INCLUDE_DIR and EXPAT_LIBRARY, I get:

CMake Error at C:/Program Files/CMake/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find EXPAT (missing: EXPAT_LIBRARY EXPAT_INCLUDE_DIR)
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
  third_party/libsbml/CMakeModules/FindEXPAT.cmake:179 (find_package_handle_standard_args)
  third_party/libsbml/CMakeLists.txt:422 (find_package)
@fbergmann
Copy link
Member

The expat find script compiles against expat, to see whether further compile definitions are necessary to compile against it. I suppose we could skip those tests in case you already define a expat target. In any case instead for you defining the expat library and include dir, it should be fine to define

add_library(EXPAT::EXPAT ALIAS expat)

and try the following patch:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 53a0d2eaf..a7b840729 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -419,7 +419,9 @@ set(LIBSBML_XML_LIBRARY_LIBS)
 
 if(WITH_EXPAT)
   
+    if(NOT TARGET EXPAT::EXPAT)
     find_package(EXPAT REQUIRED)
+    endif()
 
     add_definitions( -DUSE_EXPAT )
     list(APPEND SWIG_EXTRA_ARGS -DUSE_EXPAT)

@luciansmith
Copy link
Member Author

That worked! Or at least, I could make it work. I had to 'FORCE' the expat library settings; apparently I need to FORCE anything in libsbml I want to set in CMake itself:

add_subdirectory(expat/expat)
add_library(EXPAT::EXPAT ALIAS expat)
set(EXPAT_INCLUDE_DIR "$<TARGET_PROPERTY:expat,INCLUDE_DIRECTORIES>" CACHE PATH "Expat incude directory" FORCE)
set(EXPAT_LIBRARY "$<TARGET_LINKER_FILE:expat>" CACHE FILEPATH "Expat library" FORCE)
set(WITH_EXPAT ON CACHE BOOL "Compile libsbml with the expat library" FORCE)
set(WITH_LIBXML OFF CACHE BOOL "Compile libsbml with libxml (off by default)" FORCE)

I assume you'll want to do the same with the other XML libraries, too? And the ZIP libraries?

@fbergmann
Copy link
Member

I'm not entirely sure why you need the force for the WITH_EXPAT / WITH_LIBXML entries. As they should have just been taken from the definitions if you have a new enough cmake. But i dont mind to have the if (not target ... around the find_package statements.

@luciansmith
Copy link
Member Author

luciansmith commented May 5, 2022

If I leave them out entirely, they aren't defined, and libsbml won't compile, complaining that it doesn't know where 'zconf.h' is. If I put them in like I had originally, they get replaced by the generic UNKNOWN stand-ins. I had to define them with FORCE to get them to work.

@fbergmann
Copy link
Member

zconf indicates, that potentiall the zlib target is missing some adjustments for your usecase.

tbh: i always prefered to have dependencies be built once, instead of all the time together with the actual target you want to build. So while i think it is good to support your usecase, i think it is not the way to focus on. Dependencies can be cached with a ccache action. And i hope that is what we are doing (still learning on that myself).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants