I'm learning to build a llvm project, this is the reference: http://llvm.org/docs/Projects.html. I use the "llvm/projects/sample" directory as the primary project skeleton, and it works. Then I want to build tools from "llvm/examples" to my project, such as Fibonacci, it can't work. I do it this way: first copy the "llvm/examples/Fabonacci" directory to "MyProj/tools" ("MyProj" is top level of my project) and change Makefile to contain Fabonacci target, then configure & make. but the Fabonacci tool seems can't be built. It depends on some libs when linking. So what can I do if I want to build the source code from "llvm/projects/example" in my project?
You need to provide LLVM libraries to linker when building your own project. This means adding some flags, library directories and libraries themselves to link command. Build script probably needs some editing.
llvm-config tool can be used for providing necessary options to compiler/linker. Check documentation and examples.
Related
I have a static library libXY and a program exeA using it. I fail to find a proper project setup which allows me to use ninja from within Eclipse CDT to build only what is needed to build.
So far, I had one project with ninja build files created by cmake which defined several targets which was perfect for building from command line:
build everything if anything changed (aka ninja all)
build libXY if any source files changed (aka ninja libXY)
build libXY if any source files changed and build exeA if any source file changed and link (aka ninja exeA)
I imported the project (created with cmake's Eclipse CDT / Ninja generator) into Eclipse CDT, but there, I could only build everything (ninja all). I was unable to get Ctrl-B to build just the library and the proper target, I was unable to define targets within Eclipse.
As plan B, I created a setup where libXY and exeA are independent projects. I am unable to define the dependency from exeA to libXY so that the library is built automatically if any of its source files changed.
Help! What is the proper project architecture?
I am trying to use the assimp library in a cross platform C++ project. I include the repo as a git submodule, so, effectively, if someone downloads my project they will also download the ASSIMP project.
After I go through the assimp build / CMAKE instructions and (on Linux) type make install and from then on in my project I can use:
target_link_libraries(${PROJECT_NAME} assimp)
However, there is no make install on Windows.
The only other way I have been able to include the library on Linux is to put (in my CmakeLists.txt file):
target_link_libraries(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/build/assimp/code/libassimp.so)
This is not cross platform as it hardcodes the name and location of the .so file which will not work on Windows.
How can I expose the library so that I can do something like target_link_libraries(${PROJECT_NAME} assimp) on all platforms?
My directory tree looks like:
- src
- include
- assimp
- bin
Where the assimp directory in the include directory is the git submodule
I think you're going about this the wrong way. You don't need to build assimp in a separate step from your project, and you don't need to make install to make it available.
There are a number of ways of handling third party dependencies in Cmake, since you've already chosen to submodule the assimp repository, we'll start there. Assuming assimp is located in the root of your repository in a directory called assimp/ this would be a barebones project including it:
cmake_minimum_required(VERSION 3.0)
project(Project myassimpproj)
# include your directories
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
# set any variables you might need to set for your app and assimp
set(BUILD_ASSIMP_TOOLS ON)
set(ASSIMP_BUILD_STATIC_LIB ON)
# add assimp source dir as a subdirectory, effectively making
# assimp's CMakeLists.txt part of your build
add_subdirectory(/path/to/assimp ${CMAKE_BINARY_DIR}/assimp)
add_executable(assimp_target main.cpp)
# be sure to link in assimp, use platform-agnostic syntax for the linker
target_link_libraries(assimp_target assimp)
There may be a better way of phrasing this using generator expressions syntax, but I haven't looked at assimp's CMakeLists.txt to know if it's supported (and this is a more generic way anyway.)
Not every project uses Cmake, so you may not be able to just add_subdirectory(). In those cases, you can effectively "fake" a user call to build them using their build commands on respective platforms. execute_process() runs a command at configure time add_custom_command() and add_custom_target() run commands at build time. You then create a fake target to make integration and cross your fingers they support Cmake someday.
You can also use the ExternalProject commands added to Cmake to create a custom target to drive download, update/patch, configure, build, install and test steps of an external project, but note that this solution and the next download the dependency rather than using the submodule'd source code.
Finally, I prefer to work with prebuilt dependencies, cuts down on build time, and they can be unit tested on their own outside of the project. Conan is an open source, decentralized and multi-platform package manager with very good support for C++ and almost transparent support for Cmake when used the right way. They have grown very stable in the last year. More information on how to use Conan with Cmake can be found here.
With a growing codebase, it makes sense to organize it between separate repositories, each repo being a separate CMake-managed project.
Because of modularity, this usually means you end up in a situation where a CMake-managed project Application depends on another CMake-managed project Library, while both are internal code (i.e., code owned and maintained by your structure).
The automatic dependency recompilation issue
Then, if some sources in Library are modified, it needs to be recompiled in order to build Application. The question being:
Is it possible to have the "build Application" command (a button in an IDE, or a call to make on the command line) to first rebuild Library if Library files changed ?
I'd suggest to use the ExternalProject_Add command.
The documentation has slightly changed for the different versions:
CMake v2.8.9 ExternalProject
CMake v3.0. ExternalProject
CMake v3.3 ExternalProject
In case you encounter problems with getting the dependencies right, this thread might help you.
By looking at how the OpenChemistry parent-project does it, and with the confirmation by normanius's answer, it turns out this can be achieved with relatively few CMake script code.
It turns out that CMake CLI is offering an abstraction over the "build" action of the targeted build systems. See --build option.
ExternalProject_Add can be seen as a wrapper to use this CLI interface directly from CMake scripts.
Imagine there is a CMake-managed repository, building libuseful, and a separate CMake-managed repo, building appawesome with a dependency on libuseful.
find_package(libuseful CONFIG) # The usual way to find a dependency
# appawesome is the executable we are building, it depends on libuseful
add_executable(appawesome main.cpp)
target_link_libraries(appawesome libuseful)
Adding automatic rebuild
Then it is possible to make building appawesome systematically first try to rebuild libuseful with some code looking like:
ExternalProject_Add(EP_libuseful)
SOURCE_DIR <libuseful_sourcedir> # containing libuseful's root CMakeLists.txt
BINARY_DIR <libuseful_binarydir> # containing libuseful's CMakeCache.txt
BUILD_ALWAYS 1 # Always rebuild libuseful
)
add_dependencies(libuseful EP_libuseful)
The last line is quite important: find_package() in config mode should make a libuseful imported targed available. The call to ExternalProject_Add made a build target EP_libuseful available (which is a custom build step, building libuseful). The last line just makes sure that libuseful depends on its build step.
I have a top level CMakeLists.txt file which builds a library called Camellia and several executables in subdirectories which link with Camellia. I would like to add a third party library called XDMF as a dependency for Camellia under Camellia/TPL/Xdmf. Luckily, XDMF is already on a CMake build system, but when I use
add_subdirectory(TPL/Xdmf)
and then
add_library(Camellia ${LIB_SOURCES} ${HEADERS})
it builds Camellia in the build/TPL/Xdmf/bin directory rather than build as it does without the add_subdirectory(TPL/Xdmf). Why does adding a subdirectory change the build directory for Camellia, and how do I fix it? Also how do I make sure Camellia is linking with Xdmf once I get that figured out?
I think that ExternalProject_Add(...) is what you want.
Please see CMake: How to build external projects and include their targets which describes a similar issue.
I have a project that uses cmake to be configured and compiled, but this project depends on an external source tree that uses the traditional configure / make / make install procedure. Is it possible to tell cmake that, before compiling the main project, configure (with some specific parameters), make and make install on the external source tree should be called first?
Thanks
I had the exact same question when coming across this one.
(In my case, wanting to properly add libncurses and libcaca, which are both Autoconf based, as dependecies (and git submodules), to my CMake based project.)
So just to have an answer set to the question, based off of mike.did's comment ;
CMake's ExternalProject module definitely seems to be the proper solution.
(also see:)
Compile other external libraries (without CMakeLists.txt) with CMake
Cleanest way to depend on a make-based C library in my CMake C++ project