Let's say I have a simple project with the following structure:
.
├── dune-project
└── src
└── bin
├── dune
└── main.ml
dune-project
(lang dune 2.7)
(name myproject)
(package
(name myproject)
(synopsis "myproject")
(description "Basic project")
)
dune
(executable
(name main)
(public_name myproject)
)
When compiling with dune build I have a new directory _build with the following structure:
_build
├── default
│ ├── dune-project
│ ├── META.myproject
│ ├── myproject.dune-package
│ ├── myproject.install
│ └── src
│ └── bin
│ ├── dune
│ ├── main.exe
│ └── main.ml
├── install
│ └── default
│ ├── bin
│ │ └── myproject -> ../../../default/src/bin/main.exe
│ └── lib
│ └── myproject
│ ├── dune-package -> ../../../../default/myproject.dune-package
│ └── META -> ../../../../default/META.myproject
└── log
So dune is able to create a symlink from main.exe to myproject but I actually want myproject to be in . and not in _build/install/default/bin
I tried three things:
Add the rule (promote (into ../../)) in my dune file. It actually copies main.exe and not myproject in the source directory and dune clean doesn't delete main.exe in the root dir
Add the following rule in my dune file:
(rule
(target myproject)
(deps ../../myproject)
(action (copy %{target} %{deps}))
)
which gives me the following error:
❯ dune build
File "src/bin/dune", line 6, characters 0-88:
6 | (rule
7 | (target myproject)
8 | (deps ../../myproject)
9 | (action (copy %{target} %{deps}))
10 | )
Error: No rule found for myproject
Error: Dependency cycle between the following files:
_build/default/src/bin/myproject
Done: 0/0 (jobs: 0)%
Add the following rule in my dune file:
(rule
(target main.exe)
(deps ../../myproject)
(action (copy %{target} %{deps}))
)
which gives me the following error:
❯ dune build
Error: Multiple rules generated for _build/default/src/bin/main.exe:
- src/bin/dune:6
- src/bin/dune:2
Done: 0/0 (jobs: 0)%
And honestly I don't know what else I can do. I read the manual and can't find a solution. I wouldn't mind if I could just type dune run but since dune allows to build multiple executables, I understand it's not an option. I'd like to be able to write dune run myproject since I'm using the public name of my executables but dune can't find it. So I just want to have myproject in my root directory so I can just type ./myproject and be happy.
Do you know about dune exec? It is what you call dune run I believe.
From the root of your project, you can do dune exec ./bin/main.exe.
you can also use promote. For instance,
(executable
(name my_tool)
(promote
(until-clean)
(into ../bin)))
Related
I am developing a module, which depends on another library(wasmtime). I put files into:
modules/mod_wasm/src/include - header files, and
modules/mod_mine/src/lib/libwasmtime.a - the compiled library.
The problem which I faced is that when I compile the acore server with
./acore.sh compiler all
it gives me the error:
[100%] Linking CXX executable worldserver
/usr/bin/ld: ../../../modules/libmodules.a(ModWasm.cpp.o): in function `readWasmFile(char const*)':
ModWasm.cpp:(.text+0x63): undefined reference to `wasm_byte_vec_new_uninitialized'
/usr/bin/ld: ModWasm.cpp:(.text+0xce): undefined reference to `wasm_byte_vec_delete'
The question is it required somehow add to a config that library? If yes, then how to do that?
I was testing my code in simple main.cpp file and it was working with options like "-L${workspaceFolder}/lib" and "-lwasmtime".
Maybe, these options are also required for my module?
Here is a link to azerothcore project which I use.
my module locates in modules/mod-wasm folder
azerothcore-wotlk/modules ‹master*› » tree -L 3 mod-wasm
mod-wasm
├── CMakeLists.txt
├── LICENSE
├── Makefile
├── README.md
├── conf
│ ├── conf.sh.dist
│ └── wasm.conf.dist
├── include.sh
├── mod-wasm.cmake
├── setup_git_commit_template.sh
├── src
│ ├── ModWasm.cpp
│ ├── include
│ │ ├── doc-wasm.h
│ │ ├── wasi.h
│ │ ├── wasm.h
│ │ ├── wasmtime
│ │ ├── wasmtime.h
│ │ └── wasmtime.hh
│ ├── lib
│ │ ├── libwasmtime.a
│ │ └── libwasmtime.so
│ └── wasm_loader.cpp
└── wasm_modules
└── rust_wasm_app.wasm
As I understood from the logs what I see and because CMakeList.txt exists in modules folder, the project considers the folder as module. Which in its turn scans subdirs for *.cmake files and configures the project.
The question now is how to properly configure my module to show that it contains the compiled library wasmtime inside src/lib folder?
As I understood, I could use target_link_libraries, but it requires a target name, and I have no idea what it should be and where I can take it.
At the end, I was able to find an answer with try and catch.
Azerothcore modules supports modname.cmake file to be run when configure libmodules.a which contains all extra modules(if I understood it correctly.
this is part of modules/CMakeFiles.txt
# Enables Devs to Include a cmake file in their module that will get run inline with the config.
foreach(SOURCE_MODULE ${MODULES_MODULE_LIST})
message("SOURCE_MODULE: ${SOURCE_MODULE}")
include("${CMAKE_SOURCE_DIR}/modules/${SOURCE_MODULE}/${SOURCE_MODULE}.cmake" OPTIONAL)
endforeach()
here I have my dirty cmake file which allow me to compile the server
set(WASM_MODULE_DIR ${CMAKE_SOURCE_DIR}/modules/${SOURCE_MODULE})
set(WASM_MODULE_SRC_DIR ${WASM_MODULE_DIR}/src)
message("--------------------->>>>> APPLICATION_NAME : ${APPLICATION_NAME}")
message("--------------------->>>>> APP_PROJECT_NAME : ${APP_PROJECT_NAME}")
message("--------------------->>>>> SOURCE_MODULE : ${SOURCE_MODULE}")
message("--------------------->>>>> WASM_MODULE_DIR : ${WASM_MODULE_DIR}")
message("--------------------->>>>> WASM_MODULE_SRC_DIR : ${WASM_MODULE_SRC_DIR}")
# include wasmtime
target_include_directories(modules PUBLIC ${WASM_MODULE_SRC_DIR}/include)
target_link_directories(modules PUBLIC ${WASM_MODULE_SRC_DIR}/lib)
find_library(LIBWASMTIME_TO_INCLUDE NAMES wasmtime PATHS ${WASM_MODULE_SRC_DIR}/lib REQUIRED)
message("--------------------->>>>>>>>> LIBWASMTIME_TO_INCLUDE: ${LIBWASMTIME_TO_INCLUDE}")
target_link_libraries(modules PUBLIC wasmtime)
So, it compiles now.
But I have next problem, which I am trying to resolve. but this is another story.
Thank you all for the help
RT~ ps: cmake version 3.9.2
My codebase just like this.
suzanwen#n224-004-133:~/repos/C++/ttt:)$ tree -L 2
.
├── build
│ ├── bin
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── lib
│ ├── Makefile
│ ├── test
│ └── thirdparty
├── build.sh
├── CMakeLists.txt
├── Makefile
├── test
│ ├── CMakeLists.txt
│ └── main.cc
└── thirdparty
├── CMakeLists.txt
├── gflags
└── hellolib
10 directories, 9 files
my thirdparty/hellolib/CMakeLists.txt is
PROJECT(hello)
SET(LIBHELLO_SRC hello.cc)
MESSAGE(STATUS "LIBRARY PATH=" ${LIBRARY_OUTPUT_PATH})
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static PROPERTIES ARCHIVE_OUTPUT_NAME "hello")
my test/CMakeLists.txt is
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/thirdparty/hellolib
${PROJECT_SOURCE_DIR}/thirdparty/gflags/include)
IF(LIBRARY_OUTPUT_PATH)
LINK_DIRECTORIES(${LIBRARY_OUTPUT_PATH})
ENDIF(LIBRARY_OUTPUT_PATH)
ADD_EXECUTABLE(main main.cc)
TARGET_LINK_LIBRARIES(main hello)
# TARGET_LINK_LIBRARIES(main hello_static)
when I build my top-level project, an error occurs like this.
/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cc.o -o ../bin/main -L/home/suzanwen/repos/C++/ttt/build/lib -Wl,-rpath,/home/suzanwen/repos/C++/ttt/build/lib -lhello
/usr/bin/ld: cannot find -lhello
But when I comment the line # SET_TARGET_PROPERTIES(hello_static PROPERTIES ARCHIVE_OUTPUT_NAME "hello") and TARGET_LINK_LIBRARIES with hello_static, everything goes fine.
It seems that TARGET_LINK_LIBRARIES cannot find renamed lib target. Could anyone explain it? thanks in advance.
It seems that TARGET_LINK_LIBRARIES cannot find renamed lib target.
Setting ARCHIVE_OUTPUT_NAME property renames not a target, but an output file. So linking with a target still works:
TARGET_LINK_LIBRARIES(main hello_static)
One cannot rename the target once it is created, but it is possible to create ALIAS for a target:
ADD_LIBRARY(hello ALIAS hello_static)
After that it is possible to link with the alias:
TARGET_LINK_LIBRARIES(main hello)
I have the following directories:
$ cd dir1
$ tree
[...]
├── autogen.sh
├── CMakeLists.txt
├── common.gmake.in
├── configure.ac
├── Makefile.am
├── src
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── [...]
│ └── dir2
│ ├── CMakeLists.txt
│ ├── Makefile.am
│ ├── [...]
And in the Makefile.am of dir2, I have:
[...]
include #abs_top_builddir#/common.gmake
[...]
The first time I compile, everything works just fine. But if I want to compile a second time, because I produced a config.status file, the Makefile wants to execute a make distclean. It will execute it in dir1 and will remove the common.gmake. But as it is recursive, when it will enter in the dir2 directory, I have the following error:
Making distclean in dir2
gmake[2]: Entering directory `/dir1/src/dir2'
Makefile:1760: /dir1/common.gmake: No such file or directory
gmake[2]: *** No rule to make target `/dir1/common.gmake'. Stop.
It looks like to me the recursive target generated by automake is wrong as it wants to remove a file it already removed previously. What do you think ?
There is a project layout:
.
├── bin # <= executables go here
├── build # <= object files created here
├── lib # <= libraries go here
├── Makefile
├── src
│ ├── bin1 # <= if there is no "lib" prefix
│ ├── bin2 # <= it must be considered as executable
│ │ ├── a.c
│ │ ├── b.c
│ │ └── foo.h
│ ├── include # <= shared .h files, nothing to build here
│ ├── libt1 # <= if there is "lib" prefix - it must be
│ │ ├── blah.c # a library
│ │ └── blah.h
│ └── libt2
└── test
So i want gnu make to go through every directory in src with "lib" prefix and build a static and shared library with the same name as a directory, i.e. libt1.so and libt1.a and put them all in lib directory. Let's assume the libraries aren't linked with each other so the don't depend on each other either.
After building libs, it must go through every directory except include, and bin an executable with the same name as the directory has, and put it into bin dir. build directory is used for temporary object files.
What is the best way to do this with gnu make? I want rely on implicit rules as much as it's possible.
So now i just collect all directories into variables:
LIBS_TO_BUILD=$(wildcard $(SOURCES_DIR)/lib*)
BINS_TO_BUILD=$(filter-out $(INCLUDE_DIR) $(LIBS_TO_BUILD),\
$(wildcard $(SOURCES_DIR)/*))
But i can't figure out how to do all other steps, how should i iterate by all dirs? Assuming, that if i'll do it "by hands" it will look like:
lib/libt1.a:
$(CC) -o build/libt1.o $(CFLAGS) -c $(wildcard $(SOURCES_DIR)/libt1/*.c)
ar rcs lib/libt1.a build/libt1.o
I am trying link one of my programs to libevent. I am using CMake as build system. My project structure is as follows:
my_project
├── CMakeLists.txt
├── README.md
├── build
│ └── Build stuff
└── software
├── README.md
├── CMakeLists.txt
├── include
├── libraries
│ ├── libevent
│ │ └── CMakeLists.txt
│ └── anotherlibrary
│ └── CMakeLists.txt
├── prog1
│ ├── CMakeLists.txt
├── prog2
│ ├── CMakeLists.txt
└── prog3
└── CMakeLists.txt
CMakeList.txt of prog1 (the one that's needs to be linked to libevent)
cmake_minimum_required(VERSION 2.6)
project (prog1)
file(GLOB prog1
"*.h"
"*.cpp"
)
include_directories("${PROJECT_INCLUDE_DIR}/libevent/include")
add_executable(${PROJECT_NAME} ${prog1})
target_link_libraries(${PROJECT_NAME} event_core)
But when I build the project make can't find the library build by libevent. it searched for: libraries/libevent/lib/libevent_core.a this is the wrong path since libevent builds it libs inside: my_project/build/software/libraries/libevent/lib/libevent_core.a
How do I tell CMake to search there for the library? I already added the following lines to my Cmake file but this wasn't working
link_directories(/my_project/build/software/libraries/libevent/lib/)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build/lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build/bin)
Anyone a suggestion?
I fixed the problem myself by removing the content from the build directory and re running cmake .. inside the build directory.
I think CMake was somehow not aware of the changes I made and by rebuilding the project the problem was fixed.