How to use CMake to build sources with ghdl as custom target? - cmake

I would like to build VHDL sources with CMake. For this I have a directory structure:
<root>
- CMakeLists.txt
- src/CMakeLists.txt
- src/mymodule.vhdl
- build
Inside the root CMakeLists.txt I have:
cmake_minimum_required(VERSION 3.12)
project(vhdlsdb LANGUAGES NONE)
add_subdirectory(src)
In the src/CMakeLists.txt I have:
set(filelist mymodule.vhdl )
add_custom_target(vhdlize COMMAND ghdl -a ${filelist})
However, when I run cd build && cmake .. -GNinja && cmake --build . --target vhdlize I get:
error: cannot open mymodule
C:\Users\pm\git\GHDL\0.36-mingw64-llvm\bin\ghdl.exe: compilation error
How can I tell CMake to copy or look for the sources in the src folder?

Related

CMake : Compile only one subdirectory with preset

I have a project with this structure, where Components are subdirectories :
CMakeList.txt
CMakePresets.json
|
---Component1/CMakeList.txt
|
---Component2/CMakeList.txt
|
---Component3/CMakeList.txt
I would like to compile only Component1 with the root preset. (I mean compile all targets under Component1).
Normally, to configure and compile all the project i use this commands :
#Configuration
cd myBuildDir
cmake mySourcedDir --preset=myPreset
#Compilation
cd mySourcedDir
cmake --build --preset=myPreset
Problems :
With ninja, after configuration, the myBuildDir/Component1 directory doesn't contain build.ninja file
If i try to do cmake --build in the mySourcedDir/Component1 directory, i have an error message : CMake Error: Could not read presets from...
Try editing Component1/CMakeList.txt with:
get_property(ALL_BUILDSYSTEM_TARGETS DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
add_custom_target(Component1 DEPENDS ${ALL_BUILDSYSTEM_TARGETS})
And then do:
cmake --build --preset=myPreset --target component1

How to copy linked and mingw libs to output dir of executable?

I'm new in CMake.
Could someone please describe to me what I should write in my CMakeLists.txt to copy dependencies to the output directory of the executable file?
So, I have a CMake project:
# top-level CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(CoolLib VERSION 0.0.1)
set(CMAKE_CXX_STANDARD 23)
add_subdirectory(mylib)
add_subdirectory(mytestconsole)
install(TARGETS mnconsole mnlib
RUNTIME DESTINATION bin COMPONENT Runtime
LIBRARY DESTINATION lib COMPONENT Runtime
ARCHIVE DESTINATION lib/myproject COMPONENT Development)
# mylib/CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(mylib VERSION 0.0.1)
add_library(mylib SHARED mylib.cpp mylib.h)
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
# mytestconsole/CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(mytestconsole VERSION 0.0.1)
add_executable(mytestconsole main.cpp)
target_link_libraries(mytestconsole LINK_PUBLIC mylib)
target_include_directories(mytestconsole PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/mylib)
As you can see, I've added an install() command, but this isn't exactly what I want.
As far as I understand, the install() command will copy my program to the Program Files directory in Windows.
GOAL:
I want to copy the mingw libraries (e.g. libgcc_s_seh-1, libstdc++-6, libwinpthread-1, etc.) and mylib to the output directory of the mytestconsole.exe file.
PS: I saw this answer, but GetPrerequesites is deprecated. And I didn't understand how to use it.
I tried to do this:
add_custom_command(
TARGET mnconsole POST_BUILD
COMMAND LIST_PREREQUISITES($<TARGET_FILE:mnconsole>)
VERBATIM)
But got an error:
D:\Programs\JetBrains\CLion\bin\cmake\win\bin\cmake.exe --build D:\Projects\MethaneNumber\_builds\debug --target mnconsole -j 9
[1/1] Linking CXX executable mnconsole\mnconsole.exe
FAILED: mnconsole/mnconsole.exe
cmd.exe /C "cd . && D:\Programs\mingw64\12.2.0\x64\posix-seh\bin\c++.exe -g mnconsole/CMakeFiles/mnconsole.dir/main.cpp.obj -o mnconsole\mnconsole.exe -Wl,--out-implib,mnconsole\libmnconsole.dll.a -Wl,--major-image-version,0,--minor-image-version,0 mnlib/libmnlib.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cmd.exe /C "cd /D D:\Projects\MethaneNumber\_builds\debug\mnconsole && LIST_PREREQUISITES ( D:/Projects/MethaneNumber/_builds/debug/mnconsole/mnconsole.exe )""
"LIST_PREREQUISITES" is ­not recognized as an internal command.
ninja: build stopped: subcommand failed.
PS2: It should work like windeployqt.exe with Qt, but I'm not using Qt in this project right now.

CMake: Building a object file from a source in a object library in a sub directory out of source

Consider the following mock project with these files:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(myproject)
add_subdirectory(sub)
# sub/CMakeLists.txt
add_library(myLib OBJECT bar.c)
add_executable(foo foo.c)
target_link_libraries(foo PRIVATE myLib)
# sub/foo.c
int main() {return 0;}
# sub/bar.c
void bar(){}
When building in source after cmake -G Unix\ Makefiles -B . -S . I can go to the the directory sub and execute make bar.o. How can I achieve the same results when building out of source? I've tried these commands from the project root:
cmake -G Unix\ Makefiles -B test-build -S .
cmake --build test-build --target sub/bar.o
cmake --build test-build --target bar.o
cmake --build test-build --target bar
I get these kinds of error messages gmake: *** No rule to make target 'sub/bar.o'. Stop.
I know it's possible to build the library, but in reality our library is quite large and I would like to focus on one file at the time.

CMake putting build files in source directory

I am very new to CMake. A friend wrote a simple CMakeLists.txt for the project I am coding myself. I am using svn and have just checked out an old version on the same machine into a different folder. Now, in the original source directory (where CMakeLists.txt is located) I create the directory 'build', cd into there, and for the time being run the code
cmake -DCMAKE_BUILD_TYPE=Debug ..
This nicely puts all of the files in the build directory
-- Build files have been written to: ~/MixedFEMultigrid/build
Now when I check out to another directory, create another 'build' directory in that one and then run the CMake command I get the following
-- Build files have been written to: ~/oldCode
where oldCode is actually the parent directory. I have no idea why this is happening. Can someone explain this to me? The full CMakeLists.txt file is given below,
cmake_minimum_required (VERSION 2.6)
project (MixedFEMultigrid)
FIND_PACKAGE(LAPACK REQUIRED)
set( SRC_FILES multigrid.c
gridHandling.c
interpolation.c
linApprox.c
params.c
sparseMatrix.c
testing.c
richardsFunctions.c
definitions.c
newtonIteration.c
)
#Adds the executable with all the dependencies
add_executable (multigrid ${SRC_FILES})
#Specifies the libraries to link to the target
TARGET_LINK_LIBRARIES(multigrid ${LAPACK_LIBRARIES} m)
# Update if necessary
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -fstrict-aliasing -std=c99 -O3")
As per the comment by escrafford I am updating to show what I do on the command line.
cd ~
mkdir oldCode
cd oldCode
svn co <repository>
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
The build files are then put into the directory 'oldCode' instead of the 'build' directory. The following, on the other hand, puts the build files into the 'build' directory
cd ~
mkdir MixedFEMultigrid
cd MixedFEMultigrid
svn co <repository>
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
That comes from a in-source cmake execution
Remember to remove cmake cache:
$ rm CMakeCache.txt
$ mkdir debug
$ cd debug
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
That has another benefit, given that cmake do not provide a clean target
$ cd ..
$ rm -rf debug
is the equivalent of make clean or more precisely make distclean

How to use CPACK_RPM_POST_INSTALL_SCRIPT_FILE?

Here is the setup I tried using CMake 2.8.2 to reproduce the problem:
/test.sh:
/CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
SET(CPACK_PACKAGE_NAME test)
SET(CPACK_PACKAGE_VERSION 1.0)
LIST(APPEND CPACK_GENERATOR RPM)
SET(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "test.sh")
INCLUDE(CPack)
then:
mkdir build && cd build && cmake .. && make package
Results:
CPackRPM:Warning: CPACK_RPM_POST_INSTALL_SCRIPT_FILE does not exists - ignoring
How to make the build system aware of my file test.sh ?
You need to use absolute path:
SET(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/test.sh")
This is needed because CPackRPM needs the absolute path of the file as CPack does not know that test.sh is relative to source tree.