Arbets- / Spelstation: Arch Linux - Ryzen 5 3600 - RX 7900 XT - 32G DDR4
Server: Arch Linux - Core i5-10400F - 16G DDR4
Lära sig Make och CMake?
CMake har jag ingen koll på - enda gången jag läst CMake kod är när jag konverterat/simplifierat projekt från CMake till Make! I min åsikt är CMake ofta onödigt komplicerat jämfört med Make, från vad jag sett hittils.
Ang. Make så har jag personligen lärt mig inkrementellt från främst stackoverflow allteftersom jag stött på problem som behöver nya lösningar. Kanske inte det bästa sättet, men mina projekt bygger och fungerar, så jag är nöjd.
Om det är alls hjälpsamt kan jag bifoga makefilen från mitt senaste C++ projekt - en pathtracer i C++ och Nvidia Optix, Cuda. Den är "bara" 75 rader, så kanske går att plocka upp lite från den:
######################################################################
# Public variables
######################################################################
SHELL = /bin/sh
OPTIX = $(HOME)/Documents/Optix
CUDA = $(HOME)/Documents/CUDA
CPP = clang
CUS = pathTracer.cu parallelogram.cu sphere.cu
DEBUG = FALSE
######################################################################
# Private variables
######################################################################
NVCC = $(CUDA)/bin/nvcc
SDK = $(OPTIX)/SDK
NVCC_FLAGS = -std=c++11
CPP_FLAGS = -fPIC -Wall -std=c++17
ifeq ($(DEBUG), TRUE)
CPP_FLAGS += -g
else
CPP_FLAGS += -DNDEBUG -g3 -O3 -msse -msse2 -msse3 -mfpmath=sse -funroll-loops
endif
CPP_DEFINES = -DIMGUI_IMPL_OPENGL_LOADER_GLEW
CPP_INCLUDES = -Iimgui -Iglfw3/include -I$(OPTIX)/include -I$(SDK)/sutil -I$(SDK) -I$(OPTIX)/include/optixu -I$(SDK)/support/mdl-sdk/include -I$(CUDA)/include
CPP_LDFLAGS = glfw3/lib64/libglfw3.a $(SDK)/lib/libsutil_sdk.so $(OPTIX)/lib64/liboptix.so -Wl,--disable-new-dtags -lm $(OPTIX)/lib64/liboptixu.so -lXmu -lXi -lGL -lGLU -ldl -lpthread -lX11 $(CUDA)/lib64/libnvrtc.so -lstdc++
PTXS = $(patsubst %.cu,target/%.ptx,$(CUS))
IMGUI_SOURCES = $(wildcard imgui/*.cpp)
IMGUI_OBJS = $(patsubst imgui/%.cpp,build/%.o,$(IMGUI_SOURCES))
HEADERS = $(wildcard src/*.h)
SOURCES = $(wildcard src/*.cpp)
OBJS = $(patsubst src/%.cpp,build/%.o,$(SOURCES)) $(IMGUI_OBJS)
######################################################################
# Targets
######################################################################
.PHONY: default_target
default_target: all
# The main all target
.PHONY: all
all: target build target/pathTracer $(PTXS)
target/pathTracer: $(OBJS) $(SDK)/lib/libsutil_sdk.so
$(CPP) $(CPP_FLAGS) -Wl,-rpath,$(SDK)/lib:$(OPTIX)/lib64:$(CUDA)/lib64 -o target/pathTracer -rdynamic $(OBJS) $(CPP_LDFLAGS)
build/%.o: src/%.cpp $(HEADERS)
$(CPP) $(CPP_DEFINES) $(CPP_INCLUDES) $(CPP_FLAGS) -c -o $@ $<
build/%.o: imgui/%.cpp
$(CPP) $(CPP_DEFINES) $(CPP_INCLUDES) $(CPP_FLAGS) -c -o $@ $<
$(SDK)/lib/libsutil_sdk.so:
make -f $(SDK)/sutil/Makefile
target/%.ptx: src/%.cu $(wildcard src/*.cu)
$(NVCC) $(NVCC_FLAGS) $(CPP_INCLUDES) -ptx -o $@ $<
target:
mkdir -p target
build:
mkdir -p build
.PHONY: clean
clean:
rm -rf build
rm -rf target
.PHONY: run
run: all
cd target && ./pathTracer
Jag har gjort något liknande dina exempelproblem om du kollar på raden HEADERS = $(wildcard src/*.h)
och raderna med CPP_LDFLAGS
.
@Bryal: Grymt! Precis vad jag var ute efter. En Make-fil behöver inte vara 500 rader lång, ett stort projekt kan sättas upp med < 100 rader utan problem.
Precis. Tycker att många verkar "over-engineer"a sina byggsystem för att vara absolut generella och hantera alla möjliga situationer, när en mycket simplare specifik lösning är möjlig.
Stort tack för att du delar med dig av ett eget exempel. Speciellt med CUDA
Ingen orsak! Lycka till!
Arbets- / Spelstation: Arch Linux - Ryzen 5 3600 - RX 7900 XT - 32G DDR4
Server: Arch Linux - Core i5-10400F - 16G DDR4
Har hoppat mellan olika projekt genom åren, och därmed mellan olika plattformar med olika programmeringsspråk. Detta gör att man kan lite av varje. Men såklart, efter 3-4 år så glömmer man ju hur man gjorde. Man får lite "hur var det man gjorde nu igen"-känslan. Nu var det länge sedan jag satte upp ett projekt med Make eller CMake (med gcc/clang) och skulle vilja fräscha upp minnet lite. Vad är enligt er det bästa och snabbaste sättet att dyka in i Make/CMake?
Vet inte exakt vad jag vill göra men jag vill göra ett enkelt projekt som byggs med hjälp av Make och CMake.
Vill egentligen bara sätta upp en enkel projekt-struktur, exempelvis med projektmapp /MyProject och i den mappen finns t.ex. /src, /include, /resource, /lib, etc.
Vill kunna saker såsom: Hämta alla .h/.hpp filer i mappen /include och lagra dessa i en variabel $HEADERS. Länka biblioteken -lXXXX ... från YYYY. Och så vidare.
Ska jag tugga dokumentationen? Kolla Youtube? Böcker? Alla tips uppskattas
Svårt att se varför man inte skulle använda CMake för ett nytt C/C++/CUDA projekt som skapas idag. Kan verka enkelt att svänga ihop sin egen Makefile, men även enkla exempel har typisk flera av dessa problem
potentiella race om man använder flera kärnor för att bygga
felaktiga beroenden mellan filer, speciellt mellan källkodsfiler och headers. För att få detta rätt måste varje källkodsfil scannas och en speciell byggregel för varje fil måste skapas
väldigt komplicerat att få till egna Makefiler som faktiskt fungerar någorlunda på mer än ett OS (varför skulle man inte stödja Linux, MacOS och Windows där det är möjligt?)
svårt för andra att veta hur din makefile fungerar, d.v.s. vad är konfigurerbart, vad förutsätts etc
Detta är grunden till en CMakeLists.txt som du frågar efter. Skulle nog själv dela upp det i flera filer, men för mindre projekt behövs kanske inte det
cmake_minimum_required(VERSION 3.10)
# C++ and CUDA project
project(MyProject VERSION 1.0 LANGUAGES CXX CUDA)
# Enable C++17...
set(CMAKE_CXX_STANDARD 17)
# ...and fail if the compiler do not support C++17
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Enable C++14 for CUDA files...
set(CMAKE_CUDA_STANDARD 14)
# ...and fail if the CUDA_compiler do not support C++14
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
# add /include of this directory to the include path
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
# Make list of all C++ and all CUDA files in /src
file(GLOB CPP_SRCS src/*.cpp)
file(GLOB CUDA_SRCS src/*.cu)
# Build rules for program
add_executable(myprog ${CPP_SRCS} ${CUDA_SRCS})
# Potentially add libraries with
# target_link_libraries(myprog libx liby...)
Detta fungerar både för Linux och Windows (och MacOS om man nu råkar ha en Nvidia GPU). CMake kommer själv lura ut var CUDA är installerat (inom rimliga gränser). Vill du köra med clang++ + debug kör du (har en väldigt gammal version av clang på denna maskin, kör alltid GCC på just den här maskinen)
$ mkdir debug
$ cd debug
$ CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Debug ..
-- The CXX compiler identification is Clang 6.0.0
-- The CUDA compiler identification is NVIDIA 9.1.85
-- Check for working CXX compiler: /opt/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang++
-- Check for working CXX compiler: /opt/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Check for working CUDA compiler: /usr/bin/nvcc
-- Check for working CUDA compiler: /usr/bin/nvcc -- works
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/kjonsson/programming/cmake/proj/debug
$ make -j $(nproc --all)
Edit: Oh, angående vad du bör läsa för att få kläm på CMake. Går att googla.
Problemet är att CMake är väldigt väl dokumenterat, fast bara när man redan förstår grunderna... Ofta rätt svårt att veta vad man ska söka på innan man fått hyfsad kläm på något.
Kan därför rekommendera boken Professional CMAKE - A practical guide, men för det du beskriver ovan kan du garanterat googla dig till det som behövs då det är rätt konkreta frågor samt förutsatt att projektet är ett litet personligt projekt.
Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer
Svårt att se varför man inte skulle använda CMake för ett nytt C/C++/CUDA projekt som skapas idag. Kan verka enkelt att svänga ihop sin egen Makefile, men även enkla exempel har typisk flera av dessa problem
potentiella race om man använder flera kärnor för att bygga
felaktiga beroenden mellan filer, speciellt mellan källkodsfiler och headers. För att få detta rätt måste varje källkodsfil scannas och en speciell byggregel för varje fil måste skapas
väldigt komplicerat att få till egna Makefiler som faktiskt fungerar någorlunda på mer än ett OS (varför skulle man inte stödja Linux, MacOS och Windows där det är möjligt?)
svårt för andra att veta hur din makefile fungerar, d.v.s. vad är konfigurerbart, vad förutsätts etc
Detta är grunden till en CMakeLists.txt som du frågar efter. Skulle nog själv dela upp det i flera filer, men för mindre projekt behövs kanske inte det
cmake_minimum_required(VERSION 3.10)
# C++ and CUDA project
project(MyProject VERSION 1.0 LANGUAGES CXX CUDA)
# Enable C++17...
set(CMAKE_CXX_STANDARD 17)
# ...and fail if the compiler do not support C++17
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Enable C++14 for CUDA files...
set(CMAKE_CUDA_STANDARD 14)
# ...and fail if the CUDA_compiler do not support C++14
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
# add /include of this directory to the include path
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
# Make list of all C++ and all CUDA files in /src
file(GLOB CPP_SRCS src/*.cpp)
file(GLOB CUDA_SRCS src/*.cu)
# Build rules for program
add_executable(myprog ${CPP_SRCS} ${CUDA_SRCS})
# Potentially add libraries with
# target_link_libraries(myprog libx liby...)
Detta fungerar både för Linux och Windows (och MacOS om man nu råkar ha en Nvidia GPU). CMake kommer själv lura ut var CUDA är installerat (inom rimliga gränser). Vill du köra med clang++ + debug kör du (har en väldigt gammal version av clang på denna maskin, kör alltid GCC på just den här maskinen)
$ mkdir debug
$ cd debug
$ CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Debug ..
-- The CXX compiler identification is Clang 6.0.0
-- The CUDA compiler identification is NVIDIA 9.1.85
-- Check for working CXX compiler: /opt/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang++
-- Check for working CXX compiler: /opt/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Check for working CUDA compiler: /usr/bin/nvcc
-- Check for working CUDA compiler: /usr/bin/nvcc -- works
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/kjonsson/programming/cmake/proj/debug
$ make -j $(nproc --all)
Edit: Oh, angående vad du bör läsa för att få kläm på CMake. Går att googla.
Problemet är att CMake är väldigt väl dokumenterat, fast bara när man redan förstår grunderna... Ofta rätt svårt att veta vad man ska söka på innan man fått hyfsad kläm på något.
Kan därför rekommendera boken Professional CMAKE - A practical guide, men för det du beskriver ovan kan du garanterat googla dig till det som behövs då det är rätt konkreta frågor samt förutsatt att projektet är ett litet personligt projekt.
Riktigt snyggt exempel! Ska försöka bygga vidare på det.
Som sagt så vet jag inte vilket som är smidigast att använda, ena är ju mer för cross-plattform medan den andra är statisk(?). Det var länge sedan jag arbetade med dessa verktyg för länk/bygg-miljöer så jag vet inte vad som är enklast idag. Däremot har jag läst någonstans (minns inte var, detta var ett tag sedan) att CMake för version 2.1(?) inte var kompatibelt med CUDA, samt att det skulle vara "klumpigt" att ordna (för vilka plattformar/toolschain minns jag inte...svagt minne...). Men version > 3.0 kanske fungerar mycket bättre?
Tack för boktipset. Den ska jag köpa
Sedan har jag hört lite om Ninja (länk: https://ninja-build.org/). Något som ni rekommenderar? Verkar dock vara ett byggverktyg på låg nivå inte så användarvänligt. Fokus där kanske är prestanda.
Riktigt snyggt exempel! Ska försöka bygga vidare på det.
Som sagt så vet jag inte vilket som är smidigast att använda, ena är ju mer för cross-plattform medan den andra är statisk(?). Det var länge sedan jag arbetade med dessa verktyg för länk/bygg-miljöer så jag vet inte vad som är enklast idag. Däremot har jag läst någonstans (minns inte var, detta var ett tag sedan) att CMake för version 2.1(?) inte var kompatibelt med CUDA, samt att det skulle vara "klumpigt" att ordna (för vilka plattformar/toolschain minns jag inte...svagt minne...). Men version > 3.0 kanske fungerar mycket bättre?
Tack för boktipset. Den ska jag köpa
Sedan har jag hört lite om Ninja (länk: https://ninja-build.org/). Något som ni rekommenderar? Verkar dock vara ett byggverktyg på låg nivå inte så användarvänligt. Fokus där kanske är prestanda.
Håller själv på att undersöker Ninja och det är nog något vi kommer gå över till på jobbet.
CMake är inte ett byggsystem, det är en generator för ett byggsystem där utdata kan vara t.ex. GNU Make, Visual Studio projekt eller just ett Ninja-projekt.
Ninja har ett par fördelar över vanlig make
Ninja finns till Linux, MacOS och Windows. Även om GNU Make finns till Windows är det allt annat än effektivt på den plattformen medan Ninja uppför på lite olika sätt på olika system för att undvika svagheterna i OSet
Ninja är väldigt effektivt på att lura ut vad som inte ska byggas. Kan verka meningslöst, men i riktigt stora projekt är just detta ofta en gigantiskt flaskhals vid inkrementella byggen.
Enda du behöver gör för att använda Ninja i ett projekt som använder CMake är att installera Ninja samt köra detta
$ cd BUILD_DIR
$ cmake -GNinja ..
$ ninja
Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer
- Igår Ny RAM-sparande funktion upptäckt i Microsoft Edge 13
- Igår Så byter du till gamla Notepad i Windows 11 37
- Igår Microsoft Copilot kan snart köras direkt på datorn 14
- 27 / 3 Stort steg för Windows på ARM: Google släpper optimerat Chrome 26
- 27 / 3 Xbox-chef är öppen för fler spelbutiker på konsol 23
- Optimera användning av el till bäst pris1
- Helgsnack: Tipsa om tidsfördriv på nätet6
- Kan jag byta till SSD?49
- Formaterad hårddisk försöker återskapa3
- Teknikoutlets.se lurendrejeri?2
- Var femte användare har lämnat X sedan Musk tog över160
- Uppgradera från ryzen 3800x till ryzen 5700x3d12
- Herman Miller X Logitech G Embody Gaming Chair, recension?113
- bygga dator, köpa en komponent i taget i några månader, köpråd av delarna.20
- Råd kring “Renovering” av MSI GTX 1080 Ti4
- Säljes Samsung Soundbar HW-C410/XE (NY!)
- Säljes RTX 4090
- Säljes MSI RTX 4090 Gaming X Trio
- Säljes RTX 2070S, GTX 660, RX 3700x, Fractal Design Meshify
- Säljes Homelab Server
- Säljes 2 Auktioner - Lenovo T14 G3 och Nvidia A4000
- Köpes Söker 24-25" 240hz+ 1080p. Ev byte mot 1440p 165hz
- Köpes Desktop/"server"/Workstation, 128gb RAM (t.ex. LGA 2011-system) eller delar till sådant system
- Säljes Playstation 5 - Digital Edition
- Säljes Acer Nitro N50-600 (9400F, 1660 Ti, 32 GB RAM & 500 GB SSD)
- Helgsnack: Tipsa om tidsfördriv på nätet8
- Foton visar vit Xbox Series X utan optisk läsare10
- Ny RAM-sparande funktion upptäckt i Microsoft Edge13
- Quiz: Har du koll på det senaste inom processorkylare?75
- Svenska Embracer säljer Gearbox för 4,9 miljarder kronor15
- Cooler Master Ncore 100 Max – lättbyggt minstingchassi12
- Var femte användare har lämnat X sedan Musk tog över160
- Så byter du till gamla Notepad i Windows 1137
- Microsoft Copilot kan snart köras direkt på datorn14
- Stort steg för Windows på ARM: Google släpper optimerat Chrome26